1 /* vi:set ts=8 sts=4 sw=4 noet:
2  *
3  * VIM - Vi IMproved	by Bram Moolenaar
4  *
5  * Do ":help uganda"  in Vim to read copying and usage conditions.
6  * Do ":help credits" in Vim to see a list of people who contributed.
7  */
8 
9 /*
10  * Implements starting jobs and controlling them.
11  */
12 
13 #include "vim.h"
14 
15 #if defined(FEAT_JOB_CHANNEL) || defined(PROTO)
16 
17 #define FOR_ALL_JOBS(job) \
18     for ((job) = first_job; (job) != NULL; (job) = (job)->jv_next)
19 
20     static int
handle_mode(typval_T * item,jobopt_T * opt,ch_mode_T * modep,int jo)21 handle_mode(typval_T *item, jobopt_T *opt, ch_mode_T *modep, int jo)
22 {
23     char_u	*val = tv_get_string(item);
24 
25     opt->jo_set |= jo;
26     if (STRCMP(val, "nl") == 0)
27 	*modep = MODE_NL;
28     else if (STRCMP(val, "raw") == 0)
29 	*modep = MODE_RAW;
30     else if (STRCMP(val, "js") == 0)
31 	*modep = MODE_JS;
32     else if (STRCMP(val, "json") == 0)
33 	*modep = MODE_JSON;
34     else
35     {
36 	semsg(_(e_invarg2), val);
37 	return FAIL;
38     }
39     return OK;
40 }
41 
42     static int
handle_io(typval_T * item,ch_part_T part,jobopt_T * opt)43 handle_io(typval_T *item, ch_part_T part, jobopt_T *opt)
44 {
45     char_u	*val = tv_get_string(item);
46 
47     opt->jo_set |= JO_OUT_IO << (part - PART_OUT);
48     if (STRCMP(val, "null") == 0)
49 	opt->jo_io[part] = JIO_NULL;
50     else if (STRCMP(val, "pipe") == 0)
51 	opt->jo_io[part] = JIO_PIPE;
52     else if (STRCMP(val, "file") == 0)
53 	opt->jo_io[part] = JIO_FILE;
54     else if (STRCMP(val, "buffer") == 0)
55 	opt->jo_io[part] = JIO_BUFFER;
56     else if (STRCMP(val, "out") == 0 && part == PART_ERR)
57 	opt->jo_io[part] = JIO_OUT;
58     else
59     {
60 	semsg(_(e_invarg2), val);
61 	return FAIL;
62     }
63     return OK;
64 }
65 
66 /*
67  * Clear a jobopt_T before using it.
68  */
69     void
clear_job_options(jobopt_T * opt)70 clear_job_options(jobopt_T *opt)
71 {
72     CLEAR_POINTER(opt);
73 }
74 
75 /*
76  * Free any members of a jobopt_T.
77  */
78     void
free_job_options(jobopt_T * opt)79 free_job_options(jobopt_T *opt)
80 {
81     if (opt->jo_callback.cb_partial != NULL)
82 	partial_unref(opt->jo_callback.cb_partial);
83     else if (opt->jo_callback.cb_name != NULL)
84 	func_unref(opt->jo_callback.cb_name);
85     if (opt->jo_out_cb.cb_partial != NULL)
86 	partial_unref(opt->jo_out_cb.cb_partial);
87     else if (opt->jo_out_cb.cb_name != NULL)
88 	func_unref(opt->jo_out_cb.cb_name);
89     if (opt->jo_err_cb.cb_partial != NULL)
90 	partial_unref(opt->jo_err_cb.cb_partial);
91     else if (opt->jo_err_cb.cb_name != NULL)
92 	func_unref(opt->jo_err_cb.cb_name);
93     if (opt->jo_close_cb.cb_partial != NULL)
94 	partial_unref(opt->jo_close_cb.cb_partial);
95     else if (opt->jo_close_cb.cb_name != NULL)
96 	func_unref(opt->jo_close_cb.cb_name);
97     if (opt->jo_exit_cb.cb_partial != NULL)
98 	partial_unref(opt->jo_exit_cb.cb_partial);
99     else if (opt->jo_exit_cb.cb_name != NULL)
100 	func_unref(opt->jo_exit_cb.cb_name);
101     if (opt->jo_env != NULL)
102 	dict_unref(opt->jo_env);
103 }
104 
105 /*
106  * Get the PART_ number from the first character of an option name.
107  */
108     static int
part_from_char(int c)109 part_from_char(int c)
110 {
111     return c == 'i' ? PART_IN : c == 'o' ? PART_OUT: PART_ERR;
112 }
113 
114 /*
115  * Get the option entries from the dict in "tv", parse them and put the result
116  * in "opt".
117  * Only accept JO_ options in "supported" and JO2_ options in "supported2".
118  * If an option value is invalid return FAIL.
119  */
120     int
get_job_options(typval_T * tv,jobopt_T * opt,int supported,int supported2)121 get_job_options(typval_T *tv, jobopt_T *opt, int supported, int supported2)
122 {
123     typval_T	*item;
124     char_u	*val;
125     dict_T	*dict;
126     int		todo;
127     hashitem_T	*hi;
128     ch_part_T	part;
129 
130     if (tv->v_type == VAR_UNKNOWN)
131 	return OK;
132     if (tv->v_type != VAR_DICT)
133     {
134 	emsg(_(e_dictreq));
135 	return FAIL;
136     }
137     dict = tv->vval.v_dict;
138     if (dict == NULL)
139 	return OK;
140 
141     todo = (int)dict->dv_hashtab.ht_used;
142     for (hi = dict->dv_hashtab.ht_array; todo > 0; ++hi)
143 	if (!HASHITEM_EMPTY(hi))
144 	{
145 	    item = &dict_lookup(hi)->di_tv;
146 
147 	    if (STRCMP(hi->hi_key, "mode") == 0)
148 	    {
149 		if (!(supported & JO_MODE))
150 		    break;
151 		if (handle_mode(item, opt, &opt->jo_mode, JO_MODE) == FAIL)
152 		    return FAIL;
153 	    }
154 	    else if (STRCMP(hi->hi_key, "in_mode") == 0)
155 	    {
156 		if (!(supported & JO_IN_MODE))
157 		    break;
158 		if (handle_mode(item, opt, &opt->jo_in_mode, JO_IN_MODE)
159 								      == FAIL)
160 		    return FAIL;
161 	    }
162 	    else if (STRCMP(hi->hi_key, "out_mode") == 0)
163 	    {
164 		if (!(supported & JO_OUT_MODE))
165 		    break;
166 		if (handle_mode(item, opt, &opt->jo_out_mode, JO_OUT_MODE)
167 								      == FAIL)
168 		    return FAIL;
169 	    }
170 	    else if (STRCMP(hi->hi_key, "err_mode") == 0)
171 	    {
172 		if (!(supported & JO_ERR_MODE))
173 		    break;
174 		if (handle_mode(item, opt, &opt->jo_err_mode, JO_ERR_MODE)
175 								      == FAIL)
176 		    return FAIL;
177 	    }
178 	    else if (STRCMP(hi->hi_key, "noblock") == 0)
179 	    {
180 		if (!(supported & JO_MODE))
181 		    break;
182 		opt->jo_noblock = tv_get_bool(item);
183 	    }
184 	    else if (STRCMP(hi->hi_key, "in_io") == 0
185 		    || STRCMP(hi->hi_key, "out_io") == 0
186 		    || STRCMP(hi->hi_key, "err_io") == 0)
187 	    {
188 		if (!(supported & JO_OUT_IO))
189 		    break;
190 		if (handle_io(item, part_from_char(*hi->hi_key), opt) == FAIL)
191 		    return FAIL;
192 	    }
193 	    else if (STRCMP(hi->hi_key, "in_name") == 0
194 		    || STRCMP(hi->hi_key, "out_name") == 0
195 		    || STRCMP(hi->hi_key, "err_name") == 0)
196 	    {
197 		part = part_from_char(*hi->hi_key);
198 
199 		if (!(supported & JO_OUT_IO))
200 		    break;
201 		opt->jo_set |= JO_OUT_NAME << (part - PART_OUT);
202 		opt->jo_io_name[part] = tv_get_string_buf_chk(item,
203 						   opt->jo_io_name_buf[part]);
204 	    }
205 	    else if (STRCMP(hi->hi_key, "pty") == 0)
206 	    {
207 		if (!(supported & JO_MODE))
208 		    break;
209 		opt->jo_pty = tv_get_bool(item);
210 	    }
211 	    else if (STRCMP(hi->hi_key, "in_buf") == 0
212 		    || STRCMP(hi->hi_key, "out_buf") == 0
213 		    || STRCMP(hi->hi_key, "err_buf") == 0)
214 	    {
215 		part = part_from_char(*hi->hi_key);
216 
217 		if (!(supported & JO_OUT_IO))
218 		    break;
219 		opt->jo_set |= JO_OUT_BUF << (part - PART_OUT);
220 		opt->jo_io_buf[part] = tv_get_number(item);
221 		if (opt->jo_io_buf[part] <= 0)
222 		{
223 		    semsg(_(e_invargNval), hi->hi_key, tv_get_string(item));
224 		    return FAIL;
225 		}
226 		if (buflist_findnr(opt->jo_io_buf[part]) == NULL)
227 		{
228 		    semsg(_(e_nobufnr), (long)opt->jo_io_buf[part]);
229 		    return FAIL;
230 		}
231 	    }
232 	    else if (STRCMP(hi->hi_key, "out_modifiable") == 0
233 		    || STRCMP(hi->hi_key, "err_modifiable") == 0)
234 	    {
235 		part = part_from_char(*hi->hi_key);
236 
237 		if (!(supported & JO_OUT_IO))
238 		    break;
239 		opt->jo_set |= JO_OUT_MODIFIABLE << (part - PART_OUT);
240 		opt->jo_modifiable[part] = tv_get_bool(item);
241 	    }
242 	    else if (STRCMP(hi->hi_key, "out_msg") == 0
243 		    || STRCMP(hi->hi_key, "err_msg") == 0)
244 	    {
245 		part = part_from_char(*hi->hi_key);
246 
247 		if (!(supported & JO_OUT_IO))
248 		    break;
249 		opt->jo_set2 |= JO2_OUT_MSG << (part - PART_OUT);
250 		opt->jo_message[part] = tv_get_bool(item);
251 	    }
252 	    else if (STRCMP(hi->hi_key, "in_top") == 0
253 		    || STRCMP(hi->hi_key, "in_bot") == 0)
254 	    {
255 		linenr_T *lp;
256 
257 		if (!(supported & JO_OUT_IO))
258 		    break;
259 		if (hi->hi_key[3] == 't')
260 		{
261 		    lp = &opt->jo_in_top;
262 		    opt->jo_set |= JO_IN_TOP;
263 		}
264 		else
265 		{
266 		    lp = &opt->jo_in_bot;
267 		    opt->jo_set |= JO_IN_BOT;
268 		}
269 		*lp = tv_get_number(item);
270 		if (*lp < 0)
271 		{
272 		    semsg(_(e_invargNval), hi->hi_key, tv_get_string(item));
273 		    return FAIL;
274 		}
275 	    }
276 	    else if (STRCMP(hi->hi_key, "channel") == 0)
277 	    {
278 		if (!(supported & JO_OUT_IO))
279 		    break;
280 		opt->jo_set |= JO_CHANNEL;
281 		if (item->v_type != VAR_CHANNEL)
282 		{
283 		    semsg(_(e_invargval), "channel");
284 		    return FAIL;
285 		}
286 		opt->jo_channel = item->vval.v_channel;
287 	    }
288 	    else if (STRCMP(hi->hi_key, "callback") == 0)
289 	    {
290 		if (!(supported & JO_CALLBACK))
291 		    break;
292 		opt->jo_set |= JO_CALLBACK;
293 		opt->jo_callback = get_callback(item);
294 		if (opt->jo_callback.cb_name == NULL)
295 		{
296 		    semsg(_(e_invargval), "callback");
297 		    return FAIL;
298 		}
299 	    }
300 	    else if (STRCMP(hi->hi_key, "out_cb") == 0)
301 	    {
302 		if (!(supported & JO_OUT_CALLBACK))
303 		    break;
304 		opt->jo_set |= JO_OUT_CALLBACK;
305 		opt->jo_out_cb = get_callback(item);
306 		if (opt->jo_out_cb.cb_name == NULL)
307 		{
308 		    semsg(_(e_invargval), "out_cb");
309 		    return FAIL;
310 		}
311 	    }
312 	    else if (STRCMP(hi->hi_key, "err_cb") == 0)
313 	    {
314 		if (!(supported & JO_ERR_CALLBACK))
315 		    break;
316 		opt->jo_set |= JO_ERR_CALLBACK;
317 		opt->jo_err_cb = get_callback(item);
318 		if (opt->jo_err_cb.cb_name == NULL)
319 		{
320 		    semsg(_(e_invargval), "err_cb");
321 		    return FAIL;
322 		}
323 	    }
324 	    else if (STRCMP(hi->hi_key, "close_cb") == 0)
325 	    {
326 		if (!(supported & JO_CLOSE_CALLBACK))
327 		    break;
328 		opt->jo_set |= JO_CLOSE_CALLBACK;
329 		opt->jo_close_cb = get_callback(item);
330 		if (opt->jo_close_cb.cb_name == NULL)
331 		{
332 		    semsg(_(e_invargval), "close_cb");
333 		    return FAIL;
334 		}
335 	    }
336 	    else if (STRCMP(hi->hi_key, "drop") == 0)
337 	    {
338 		int never = FALSE;
339 		val = tv_get_string(item);
340 
341 		if (STRCMP(val, "never") == 0)
342 		    never = TRUE;
343 		else if (STRCMP(val, "auto") != 0)
344 		{
345 		    semsg(_(e_invargNval), "drop", val);
346 		    return FAIL;
347 		}
348 		opt->jo_drop_never = never;
349 	    }
350 	    else if (STRCMP(hi->hi_key, "exit_cb") == 0)
351 	    {
352 		if (!(supported & JO_EXIT_CB))
353 		    break;
354 		opt->jo_set |= JO_EXIT_CB;
355 		opt->jo_exit_cb = get_callback(item);
356 		if (opt->jo_exit_cb.cb_name == NULL)
357 		{
358 		    semsg(_(e_invargval), "exit_cb");
359 		    return FAIL;
360 		}
361 	    }
362 #ifdef FEAT_TERMINAL
363 	    else if (STRCMP(hi->hi_key, "term_name") == 0)
364 	    {
365 		if (!(supported2 & JO2_TERM_NAME))
366 		    break;
367 		opt->jo_set2 |= JO2_TERM_NAME;
368 		opt->jo_term_name = tv_get_string_buf_chk(item,
369 						       opt->jo_term_name_buf);
370 		if (opt->jo_term_name == NULL)
371 		{
372 		    semsg(_(e_invargval), "term_name");
373 		    return FAIL;
374 		}
375 	    }
376 	    else if (STRCMP(hi->hi_key, "term_finish") == 0)
377 	    {
378 		if (!(supported2 & JO2_TERM_FINISH))
379 		    break;
380 		val = tv_get_string(item);
381 		if (STRCMP(val, "open") != 0 && STRCMP(val, "close") != 0)
382 		{
383 		    semsg(_(e_invargNval), "term_finish", val);
384 		    return FAIL;
385 		}
386 		opt->jo_set2 |= JO2_TERM_FINISH;
387 		opt->jo_term_finish = *val;
388 	    }
389 	    else if (STRCMP(hi->hi_key, "term_opencmd") == 0)
390 	    {
391 		char_u *p;
392 
393 		if (!(supported2 & JO2_TERM_OPENCMD))
394 		    break;
395 		opt->jo_set2 |= JO2_TERM_OPENCMD;
396 		p = opt->jo_term_opencmd = tv_get_string_buf_chk(item,
397 						    opt->jo_term_opencmd_buf);
398 		if (p != NULL)
399 		{
400 		    // Must have %d and no other %.
401 		    p = vim_strchr(p, '%');
402 		    if (p != NULL && (p[1] != 'd'
403 					    || vim_strchr(p + 2, '%') != NULL))
404 			p = NULL;
405 		}
406 		if (p == NULL)
407 		{
408 		    semsg(_(e_invargval), "term_opencmd");
409 		    return FAIL;
410 		}
411 	    }
412 	    else if (STRCMP(hi->hi_key, "eof_chars") == 0)
413 	    {
414 		if (!(supported2 & JO2_EOF_CHARS))
415 		    break;
416 		opt->jo_set2 |= JO2_EOF_CHARS;
417 		opt->jo_eof_chars = tv_get_string_buf_chk(item,
418 						       opt->jo_eof_chars_buf);
419 		if (opt->jo_eof_chars == NULL)
420 		{
421 		    semsg(_(e_invargval), "eof_chars");
422 		    return FAIL;
423 		}
424 	    }
425 	    else if (STRCMP(hi->hi_key, "term_rows") == 0)
426 	    {
427 		int error = FALSE;
428 
429 		if (!(supported2 & JO2_TERM_ROWS))
430 		    break;
431 		opt->jo_set2 |= JO2_TERM_ROWS;
432 		opt->jo_term_rows = tv_get_number_chk(item, &error);
433 		if (error)
434 		    return FAIL;
435 		if (opt->jo_term_rows < 0 || opt->jo_term_rows > 1000)
436 		{
437 		    semsg(_(e_invargval), "term_rows");
438 		    return FAIL;
439 		}
440 	    }
441 	    else if (STRCMP(hi->hi_key, "term_cols") == 0)
442 	    {
443 		if (!(supported2 & JO2_TERM_COLS))
444 		    break;
445 		opt->jo_set2 |= JO2_TERM_COLS;
446 		opt->jo_term_cols = tv_get_number(item);
447 	    }
448 	    else if (STRCMP(hi->hi_key, "vertical") == 0)
449 	    {
450 		if (!(supported2 & JO2_VERTICAL))
451 		    break;
452 		opt->jo_set2 |= JO2_VERTICAL;
453 		opt->jo_vertical = tv_get_bool(item);
454 	    }
455 	    else if (STRCMP(hi->hi_key, "curwin") == 0)
456 	    {
457 		if (!(supported2 & JO2_CURWIN))
458 		    break;
459 		opt->jo_set2 |= JO2_CURWIN;
460 		opt->jo_curwin = tv_get_bool(item);
461 	    }
462 	    else if (STRCMP(hi->hi_key, "bufnr") == 0)
463 	    {
464 		int nr;
465 
466 		if (!(supported2 & JO2_CURWIN))
467 		    break;
468 		opt->jo_set2 |= JO2_BUFNR;
469 		nr = tv_get_number(item);
470 		if (nr <= 0)
471 		{
472 		    semsg(_(e_invargNval), hi->hi_key, tv_get_string(item));
473 		    return FAIL;
474 		}
475 		opt->jo_bufnr_buf = buflist_findnr(nr);
476 		if (opt->jo_bufnr_buf == NULL)
477 		{
478 		    semsg(_(e_nobufnr), (long)nr);
479 		    return FAIL;
480 		}
481 		if (opt->jo_bufnr_buf->b_nwindows == 0
482 			|| opt->jo_bufnr_buf->b_term == NULL)
483 		{
484 		    semsg(_(e_invarg2), "bufnr");
485 		    return FAIL;
486 		}
487 	    }
488 	    else if (STRCMP(hi->hi_key, "hidden") == 0)
489 	    {
490 		if (!(supported2 & JO2_HIDDEN))
491 		    break;
492 		opt->jo_set2 |= JO2_HIDDEN;
493 		opt->jo_hidden = tv_get_bool(item);
494 	    }
495 	    else if (STRCMP(hi->hi_key, "norestore") == 0)
496 	    {
497 		if (!(supported2 & JO2_NORESTORE))
498 		    break;
499 		opt->jo_set2 |= JO2_NORESTORE;
500 		opt->jo_term_norestore = tv_get_bool(item);
501 	    }
502 	    else if (STRCMP(hi->hi_key, "term_kill") == 0)
503 	    {
504 		if (!(supported2 & JO2_TERM_KILL))
505 		    break;
506 		opt->jo_set2 |= JO2_TERM_KILL;
507 		opt->jo_term_kill = tv_get_string_buf_chk(item,
508 						       opt->jo_term_kill_buf);
509 		if (opt->jo_term_kill == NULL)
510 		{
511 		    semsg(_(e_invargval), "term_kill");
512 		    return FAIL;
513 		}
514 	    }
515 	    else if (STRCMP(hi->hi_key, "tty_type") == 0)
516 	    {
517 		char_u *p;
518 
519 		if (!(supported2 & JO2_TTY_TYPE))
520 		    break;
521 		opt->jo_set2 |= JO2_TTY_TYPE;
522 		p = tv_get_string_chk(item);
523 		if (p == NULL)
524 		{
525 		    semsg(_(e_invargval), "tty_type");
526 		    return FAIL;
527 		}
528 		// Allow empty string, "winpty", "conpty".
529 		if (!(*p == NUL || STRCMP(p, "winpty") == 0
530 					          || STRCMP(p, "conpty") == 0))
531 		{
532 		    semsg(_(e_invargval), "tty_type");
533 		    return FAIL;
534 		}
535 		opt->jo_tty_type = p[0];
536 	    }
537 # if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
538 	    else if (STRCMP(hi->hi_key, "ansi_colors") == 0)
539 	    {
540 		int		n = 0;
541 		listitem_T	*li;
542 		long_u		rgb[16];
543 
544 		if (!(supported2 & JO2_ANSI_COLORS))
545 		    break;
546 
547 		if (item == NULL || item->v_type != VAR_LIST
548 			|| item->vval.v_list == NULL)
549 		{
550 		    semsg(_(e_invargval), "ansi_colors");
551 		    return FAIL;
552 		}
553 
554 		CHECK_LIST_MATERIALIZE(item->vval.v_list);
555 		li = item->vval.v_list->lv_first;
556 		for (; li != NULL && n < 16; li = li->li_next, n++)
557 		{
558 		    char_u	*color_name;
559 		    guicolor_T	guicolor;
560 		    int		called_emsg_before = called_emsg;
561 
562 		    color_name = tv_get_string_chk(&li->li_tv);
563 		    if (color_name == NULL)
564 			return FAIL;
565 
566 		    guicolor = GUI_GET_COLOR(color_name);
567 		    if (guicolor == INVALCOLOR)
568 		    {
569 			if (called_emsg_before == called_emsg)
570 			    // may not get the error if the GUI didn't start
571 			    semsg(_(e_cannot_allocate_color_str), color_name);
572 			return FAIL;
573 		    }
574 
575 		    rgb[n] = GUI_MCH_GET_RGB(guicolor);
576 		}
577 
578 		if (n != 16 || li != NULL)
579 		{
580 		    semsg(_(e_invargval), "ansi_colors");
581 		    return FAIL;
582 		}
583 
584 		opt->jo_set2 |= JO2_ANSI_COLORS;
585 		memcpy(opt->jo_ansi_colors, rgb, sizeof(rgb));
586 	    }
587 # endif
588 	    else if (STRCMP(hi->hi_key, "term_highlight") == 0)
589 	    {
590 		char_u *p;
591 
592 		if (!(supported2 & JO2_TERM_HIGHLIGHT))
593 		    break;
594 		opt->jo_set2 |= JO2_TERM_HIGHLIGHT;
595 		p = tv_get_string_buf_chk(item, opt->jo_term_highlight_buf);
596 		if (p == NULL || *p == NUL)
597 		{
598 		    semsg(_(e_invargval), "term_highlight");
599 		    return FAIL;
600 		}
601 		opt->jo_term_highlight = p;
602 	    }
603 	    else if (STRCMP(hi->hi_key, "term_api") == 0)
604 	    {
605 		if (!(supported2 & JO2_TERM_API))
606 		    break;
607 		opt->jo_set2 |= JO2_TERM_API;
608 		opt->jo_term_api = tv_get_string_buf_chk(item,
609 							opt->jo_term_api_buf);
610 		if (opt->jo_term_api == NULL)
611 		{
612 		    semsg(_(e_invargval), "term_api");
613 		    return FAIL;
614 		}
615 	    }
616 #endif
617 	    else if (STRCMP(hi->hi_key, "env") == 0)
618 	    {
619 		if (!(supported2 & JO2_ENV))
620 		    break;
621 		if (item->v_type != VAR_DICT)
622 		{
623 		    semsg(_(e_invargval), "env");
624 		    return FAIL;
625 		}
626 		opt->jo_set2 |= JO2_ENV;
627 		opt->jo_env = item->vval.v_dict;
628 		if (opt->jo_env != NULL)
629 		    ++opt->jo_env->dv_refcount;
630 	    }
631 	    else if (STRCMP(hi->hi_key, "cwd") == 0)
632 	    {
633 		if (!(supported2 & JO2_CWD))
634 		    break;
635 		opt->jo_cwd = tv_get_string_buf_chk(item, opt->jo_cwd_buf);
636 		if (opt->jo_cwd == NULL || !mch_isdir(opt->jo_cwd)
637 #ifndef MSWIN  // Win32 directories don't have the concept of "executable"
638 				|| mch_access((char *)opt->jo_cwd, X_OK) != 0
639 #endif
640 				)
641 		{
642 		    semsg(_(e_invargval), "cwd");
643 		    return FAIL;
644 		}
645 		opt->jo_set2 |= JO2_CWD;
646 	    }
647 	    else if (STRCMP(hi->hi_key, "waittime") == 0)
648 	    {
649 		if (!(supported & JO_WAITTIME))
650 		    break;
651 		opt->jo_set |= JO_WAITTIME;
652 		opt->jo_waittime = tv_get_number(item);
653 	    }
654 	    else if (STRCMP(hi->hi_key, "timeout") == 0)
655 	    {
656 		if (!(supported & JO_TIMEOUT))
657 		    break;
658 		opt->jo_set |= JO_TIMEOUT;
659 		opt->jo_timeout = tv_get_number(item);
660 	    }
661 	    else if (STRCMP(hi->hi_key, "out_timeout") == 0)
662 	    {
663 		if (!(supported & JO_OUT_TIMEOUT))
664 		    break;
665 		opt->jo_set |= JO_OUT_TIMEOUT;
666 		opt->jo_out_timeout = tv_get_number(item);
667 	    }
668 	    else if (STRCMP(hi->hi_key, "err_timeout") == 0)
669 	    {
670 		if (!(supported & JO_ERR_TIMEOUT))
671 		    break;
672 		opt->jo_set |= JO_ERR_TIMEOUT;
673 		opt->jo_err_timeout = tv_get_number(item);
674 	    }
675 	    else if (STRCMP(hi->hi_key, "part") == 0)
676 	    {
677 		if (!(supported & JO_PART))
678 		    break;
679 		opt->jo_set |= JO_PART;
680 		val = tv_get_string(item);
681 		if (STRCMP(val, "err") == 0)
682 		    opt->jo_part = PART_ERR;
683 		else if (STRCMP(val, "out") == 0)
684 		    opt->jo_part = PART_OUT;
685 		else
686 		{
687 		    semsg(_(e_invargNval), "part", val);
688 		    return FAIL;
689 		}
690 	    }
691 	    else if (STRCMP(hi->hi_key, "id") == 0)
692 	    {
693 		if (!(supported & JO_ID))
694 		    break;
695 		opt->jo_set |= JO_ID;
696 		opt->jo_id = tv_get_number(item);
697 	    }
698 	    else if (STRCMP(hi->hi_key, "stoponexit") == 0)
699 	    {
700 		if (!(supported & JO_STOPONEXIT))
701 		    break;
702 		opt->jo_set |= JO_STOPONEXIT;
703 		opt->jo_stoponexit = tv_get_string_buf_chk(item,
704 						      opt->jo_stoponexit_buf);
705 		if (opt->jo_stoponexit == NULL)
706 		{
707 		    semsg(_(e_invargval), "stoponexit");
708 		    return FAIL;
709 		}
710 	    }
711 	    else if (STRCMP(hi->hi_key, "block_write") == 0)
712 	    {
713 		if (!(supported & JO_BLOCK_WRITE))
714 		    break;
715 		opt->jo_set |= JO_BLOCK_WRITE;
716 		opt->jo_block_write = tv_get_number(item);
717 	    }
718 	    else
719 		break;
720 	    --todo;
721 	}
722     if (todo > 0)
723     {
724 	semsg(_(e_invarg2), hi->hi_key);
725 	return FAIL;
726     }
727 
728     return OK;
729 }
730 
731 static job_T *first_job = NULL;
732 
733     static void
job_free_contents(job_T * job)734 job_free_contents(job_T *job)
735 {
736     int		i;
737 
738     ch_log(job->jv_channel, "Freeing job");
739     if (job->jv_channel != NULL)
740     {
741 	// The link from the channel to the job doesn't count as a reference,
742 	// thus don't decrement the refcount of the job.  The reference from
743 	// the job to the channel does count the reference, decrement it and
744 	// NULL the reference.  We don't set ch_job_killed, unreferencing the
745 	// job doesn't mean it stops running.
746 	job->jv_channel->ch_job = NULL;
747 	channel_unref(job->jv_channel);
748     }
749     mch_clear_job(job);
750 
751     vim_free(job->jv_tty_in);
752     vim_free(job->jv_tty_out);
753     vim_free(job->jv_stoponexit);
754 #ifdef UNIX
755     vim_free(job->jv_termsig);
756 #endif
757 #ifdef MSWIN
758     vim_free(job->jv_tty_type);
759 #endif
760     free_callback(&job->jv_exit_cb);
761     if (job->jv_argv != NULL)
762     {
763 	for (i = 0; job->jv_argv[i] != NULL; i++)
764 	    vim_free(job->jv_argv[i]);
765 	vim_free(job->jv_argv);
766     }
767 }
768 
769 /*
770  * Remove "job" from the list of jobs.
771  */
772     static void
job_unlink(job_T * job)773 job_unlink(job_T *job)
774 {
775     if (job->jv_next != NULL)
776 	job->jv_next->jv_prev = job->jv_prev;
777     if (job->jv_prev == NULL)
778 	first_job = job->jv_next;
779     else
780 	job->jv_prev->jv_next = job->jv_next;
781 }
782 
783     static void
job_free_job(job_T * job)784 job_free_job(job_T *job)
785 {
786     job_unlink(job);
787     vim_free(job);
788 }
789 
790     static void
job_free(job_T * job)791 job_free(job_T *job)
792 {
793     if (!in_free_unref_items)
794     {
795 	job_free_contents(job);
796 	job_free_job(job);
797     }
798 }
799 
800 static job_T *jobs_to_free = NULL;
801 
802 /*
803  * Put "job" in a list to be freed later, when it's no longer referenced.
804  */
805     static void
job_free_later(job_T * job)806 job_free_later(job_T *job)
807 {
808     job_unlink(job);
809     job->jv_next = jobs_to_free;
810     jobs_to_free = job;
811 }
812 
813     static void
free_jobs_to_free_later(void)814 free_jobs_to_free_later(void)
815 {
816     job_T *job;
817 
818     while (jobs_to_free != NULL)
819     {
820 	job = jobs_to_free;
821 	jobs_to_free = job->jv_next;
822 	job_free_contents(job);
823 	vim_free(job);
824     }
825 }
826 
827 #if defined(EXITFREE) || defined(PROTO)
828     void
job_free_all(void)829 job_free_all(void)
830 {
831     while (first_job != NULL)
832 	job_free(first_job);
833     free_jobs_to_free_later();
834 
835 # ifdef FEAT_TERMINAL
836     free_unused_terminals();
837 # endif
838 }
839 #endif
840 
841 /*
842  * Return TRUE if we need to check if the process of "job" has ended.
843  */
844     static int
job_need_end_check(job_T * job)845 job_need_end_check(job_T *job)
846 {
847     return job->jv_status == JOB_STARTED
848 	    && (job->jv_stoponexit != NULL || job->jv_exit_cb.cb_name != NULL);
849 }
850 
851 /*
852  * Return TRUE if the channel of "job" is still useful.
853  */
854     static int
job_channel_still_useful(job_T * job)855 job_channel_still_useful(job_T *job)
856 {
857     return job->jv_channel != NULL && channel_still_useful(job->jv_channel);
858 }
859 
860 /*
861  * Return TRUE if the channel of "job" is closeable.
862  */
863     static int
job_channel_can_close(job_T * job)864 job_channel_can_close(job_T *job)
865 {
866     return job->jv_channel != NULL && channel_can_close(job->jv_channel);
867 }
868 
869 /*
870  * Return TRUE if the job should not be freed yet.  Do not free the job when
871  * it has not ended yet and there is a "stoponexit" flag, an exit callback
872  * or when the associated channel will do something with the job output.
873  */
874     static int
job_still_useful(job_T * job)875 job_still_useful(job_T *job)
876 {
877     return job_need_end_check(job) || job_channel_still_useful(job);
878 }
879 
880 #if defined(GUI_MAY_FORK) || defined(GUI_MAY_SPAWN) || defined(PROTO)
881 /*
882  * Return TRUE when there is any running job that we care about.
883  */
884     int
job_any_running()885 job_any_running()
886 {
887     job_T	*job;
888 
889     FOR_ALL_JOBS(job)
890 	if (job_still_useful(job))
891 	{
892 	    ch_log(NULL, "GUI not forking because a job is running");
893 	    return TRUE;
894 	}
895     return FALSE;
896 }
897 #endif
898 
899 // Unix uses argv[] for the command, other systems use a string.
900 #if defined(UNIX)
901 # define USE_ARGV
902 #endif
903 
904 #if !defined(USE_ARGV) || defined(PROTO)
905 /*
906  * Escape one argument for an external command.
907  * Returns the escaped string in allocated memory.  NULL when out of memory.
908  */
909     static char_u *
win32_escape_arg(char_u * arg)910 win32_escape_arg(char_u *arg)
911 {
912     int		slen, dlen;
913     int		escaping = 0;
914     int		i;
915     char_u	*s, *d;
916     char_u	*escaped_arg;
917     int		has_spaces = FALSE;
918 
919     // First count the number of extra bytes required.
920     slen = (int)STRLEN(arg);
921     dlen = slen;
922     for (s = arg; *s != NUL; MB_PTR_ADV(s))
923     {
924 	if (*s == '"' || *s == '\\')
925 	    ++dlen;
926 	if (*s == ' ' || *s == '\t')
927 	    has_spaces = TRUE;
928     }
929 
930     if (has_spaces)
931 	dlen += 2;
932 
933     if (dlen == slen)
934 	return vim_strsave(arg);
935 
936     // Allocate memory for the result and fill it.
937     escaped_arg = alloc(dlen + 1);
938     if (escaped_arg == NULL)
939 	return NULL;
940     memset(escaped_arg, 0, dlen+1);
941 
942     d = escaped_arg;
943 
944     if (has_spaces)
945 	*d++ = '"';
946 
947     for (s = arg; *s != NUL;)
948     {
949 	switch (*s)
950 	{
951 	    case '"':
952 		for (i = 0; i < escaping; i++)
953 		    *d++ = '\\';
954 		escaping = 0;
955 		*d++ = '\\';
956 		*d++ = *s++;
957 		break;
958 	    case '\\':
959 		escaping++;
960 		*d++ = *s++;
961 		break;
962 	    default:
963 		escaping = 0;
964 		MB_COPY_CHAR(s, d);
965 		break;
966 	}
967     }
968 
969     // add terminating quote and finish with a NUL
970     if (has_spaces)
971     {
972 	for (i = 0; i < escaping; i++)
973 	    *d++ = '\\';
974 	*d++ = '"';
975     }
976     *d = NUL;
977 
978     return escaped_arg;
979 }
980 
981 /*
982  * Build a command line from a list, taking care of escaping.
983  * The result is put in gap->ga_data.
984  * Returns FAIL when out of memory.
985  */
986     int
win32_build_cmd(list_T * l,garray_T * gap)987 win32_build_cmd(list_T *l, garray_T *gap)
988 {
989     listitem_T  *li;
990     char_u	*s;
991 
992     CHECK_LIST_MATERIALIZE(l);
993     FOR_ALL_LIST_ITEMS(l, li)
994     {
995 	s = tv_get_string_chk(&li->li_tv);
996 	if (s == NULL)
997 	    return FAIL;
998 	s = win32_escape_arg(s);
999 	if (s == NULL)
1000 	    return FAIL;
1001 	ga_concat(gap, s);
1002 	vim_free(s);
1003 	if (li->li_next != NULL)
1004 	    ga_append(gap, ' ');
1005     }
1006     return OK;
1007 }
1008 #endif
1009 
1010 /*
1011  * NOTE: Must call job_cleanup() only once right after the status of "job"
1012  * changed to JOB_ENDED (i.e. after job_status() returned "dead" first or
1013  * mch_detect_ended_job() returned non-NULL).
1014  * If the job is no longer used it will be removed from the list of jobs, and
1015  * deleted a bit later.
1016  */
1017     void
job_cleanup(job_T * job)1018 job_cleanup(job_T *job)
1019 {
1020     if (job->jv_status != JOB_ENDED)
1021 	return;
1022 
1023     // Ready to cleanup the job.
1024     job->jv_status = JOB_FINISHED;
1025 
1026     // When only channel-in is kept open, close explicitly.
1027     if (job->jv_channel != NULL)
1028 	ch_close_part(job->jv_channel, PART_IN);
1029 
1030     if (job->jv_exit_cb.cb_name != NULL)
1031     {
1032 	typval_T	argv[3];
1033 	typval_T	rettv;
1034 
1035 	// Invoke the exit callback. Make sure the refcount is > 0.
1036 	ch_log(job->jv_channel, "Invoking exit callback %s",
1037 						      job->jv_exit_cb.cb_name);
1038 	++job->jv_refcount;
1039 	argv[0].v_type = VAR_JOB;
1040 	argv[0].vval.v_job = job;
1041 	argv[1].v_type = VAR_NUMBER;
1042 	argv[1].vval.v_number = job->jv_exitval;
1043 	call_callback(&job->jv_exit_cb, -1, &rettv, 2, argv);
1044 	clear_tv(&rettv);
1045 	--job->jv_refcount;
1046 	channel_need_redraw = TRUE;
1047     }
1048 
1049     if (job->jv_channel != NULL && job->jv_channel->ch_anonymous_pipe)
1050 	job->jv_channel->ch_killing = TRUE;
1051 
1052     // Do not free the job in case the close callback of the associated channel
1053     // isn't invoked yet and may get information by job_info().
1054     if (job->jv_refcount == 0 && !job_channel_still_useful(job))
1055 	// The job was already unreferenced and the associated channel was
1056 	// detached, now that it ended it can be freed. However, a caller might
1057 	// still use it, thus free it a bit later.
1058 	job_free_later(job);
1059 }
1060 
1061 /*
1062  * Mark references in jobs that are still useful.
1063  */
1064     int
set_ref_in_job(int copyID)1065 set_ref_in_job(int copyID)
1066 {
1067     int		abort = FALSE;
1068     job_T	*job;
1069     typval_T	tv;
1070 
1071     for (job = first_job; !abort && job != NULL; job = job->jv_next)
1072 	if (job_still_useful(job))
1073 	{
1074 	    tv.v_type = VAR_JOB;
1075 	    tv.vval.v_job = job;
1076 	    abort = abort || set_ref_in_item(&tv, copyID, NULL, NULL);
1077 	}
1078     return abort;
1079 }
1080 
1081 /*
1082  * Dereference "job".  Note that after this "job" may have been freed.
1083  */
1084     void
job_unref(job_T * job)1085 job_unref(job_T *job)
1086 {
1087     if (job != NULL && --job->jv_refcount <= 0)
1088     {
1089 	// Do not free the job if there is a channel where the close callback
1090 	// may get the job info.
1091 	if (!job_channel_still_useful(job))
1092 	{
1093 	    // Do not free the job when it has not ended yet and there is a
1094 	    // "stoponexit" flag or an exit callback.
1095 	    if (!job_need_end_check(job))
1096 	    {
1097 		job_free(job);
1098 	    }
1099 	    else if (job->jv_channel != NULL)
1100 	    {
1101 		// Do remove the link to the channel, otherwise it hangs
1102 		// around until Vim exits. See job_free() for refcount.
1103 		ch_log(job->jv_channel, "detaching channel from job");
1104 		job->jv_channel->ch_job = NULL;
1105 		channel_unref(job->jv_channel);
1106 		job->jv_channel = NULL;
1107 	    }
1108 	}
1109     }
1110 }
1111 
1112     int
free_unused_jobs_contents(int copyID,int mask)1113 free_unused_jobs_contents(int copyID, int mask)
1114 {
1115     int		did_free = FALSE;
1116     job_T	*job;
1117 
1118     FOR_ALL_JOBS(job)
1119 	if ((job->jv_copyID & mask) != (copyID & mask)
1120 						    && !job_still_useful(job))
1121 	{
1122 	    // Free the channel and ordinary items it contains, but don't
1123 	    // recurse into Lists, Dictionaries etc.
1124 	    job_free_contents(job);
1125 	    did_free = TRUE;
1126 	}
1127     return did_free;
1128 }
1129 
1130     void
free_unused_jobs(int copyID,int mask)1131 free_unused_jobs(int copyID, int mask)
1132 {
1133     job_T	*job;
1134     job_T	*job_next;
1135 
1136     for (job = first_job; job != NULL; job = job_next)
1137     {
1138 	job_next = job->jv_next;
1139 	if ((job->jv_copyID & mask) != (copyID & mask)
1140 						    && !job_still_useful(job))
1141 	{
1142 	    // Free the job struct itself.
1143 	    job_free_job(job);
1144 	}
1145     }
1146 }
1147 
1148 /*
1149  * Allocate a job.  Sets the refcount to one and sets options default.
1150  */
1151     job_T *
job_alloc(void)1152 job_alloc(void)
1153 {
1154     job_T *job;
1155 
1156     job = ALLOC_CLEAR_ONE(job_T);
1157     if (job != NULL)
1158     {
1159 	job->jv_refcount = 1;
1160 	job->jv_stoponexit = vim_strsave((char_u *)"term");
1161 
1162 	if (first_job != NULL)
1163 	{
1164 	    first_job->jv_prev = job;
1165 	    job->jv_next = first_job;
1166 	}
1167 	first_job = job;
1168     }
1169     return job;
1170 }
1171 
1172     void
job_set_options(job_T * job,jobopt_T * opt)1173 job_set_options(job_T *job, jobopt_T *opt)
1174 {
1175     if (opt->jo_set & JO_STOPONEXIT)
1176     {
1177 	vim_free(job->jv_stoponexit);
1178 	if (opt->jo_stoponexit == NULL || *opt->jo_stoponexit == NUL)
1179 	    job->jv_stoponexit = NULL;
1180 	else
1181 	    job->jv_stoponexit = vim_strsave(opt->jo_stoponexit);
1182     }
1183     if (opt->jo_set & JO_EXIT_CB)
1184     {
1185 	free_callback(&job->jv_exit_cb);
1186 	if (opt->jo_exit_cb.cb_name == NULL || *opt->jo_exit_cb.cb_name == NUL)
1187 	{
1188 	    job->jv_exit_cb.cb_name = NULL;
1189 	    job->jv_exit_cb.cb_partial = NULL;
1190 	}
1191 	else
1192 	    copy_callback(&job->jv_exit_cb, &opt->jo_exit_cb);
1193     }
1194 }
1195 
1196 /*
1197  * Called when Vim is exiting: kill all jobs that have the "stoponexit" flag.
1198  */
1199     void
job_stop_on_exit(void)1200 job_stop_on_exit(void)
1201 {
1202     job_T	*job;
1203 
1204     FOR_ALL_JOBS(job)
1205 	if (job->jv_status == JOB_STARTED && job->jv_stoponexit != NULL)
1206 	    mch_signal_job(job, job->jv_stoponexit);
1207 }
1208 
1209 /*
1210  * Return TRUE when there is any job that has an exit callback and might exit,
1211  * which means job_check_ended() should be called more often.
1212  */
1213     int
has_pending_job(void)1214 has_pending_job(void)
1215 {
1216     job_T	    *job;
1217 
1218     FOR_ALL_JOBS(job)
1219 	// Only should check if the channel has been closed, if the channel is
1220 	// open the job won't exit.
1221 	if ((job->jv_status == JOB_STARTED && !job_channel_still_useful(job))
1222 		    || (job->jv_status == JOB_FINISHED
1223 					      && job_channel_can_close(job)))
1224 	    return TRUE;
1225     return FALSE;
1226 }
1227 
1228 #define MAX_CHECK_ENDED 8
1229 
1230 /*
1231  * Called once in a while: check if any jobs that seem useful have ended.
1232  * Returns TRUE if a job did end.
1233  */
1234     int
job_check_ended(void)1235 job_check_ended(void)
1236 {
1237     int		i;
1238     int		did_end = FALSE;
1239 
1240     // be quick if there are no jobs to check
1241     if (first_job == NULL)
1242 	return did_end;
1243 
1244     for (i = 0; i < MAX_CHECK_ENDED; ++i)
1245     {
1246 	// NOTE: mch_detect_ended_job() must only return a job of which the
1247 	// status was just set to JOB_ENDED.
1248 	job_T	*job = mch_detect_ended_job(first_job);
1249 
1250 	if (job == NULL)
1251 	    break;
1252 	did_end = TRUE;
1253 	job_cleanup(job); // may add "job" to jobs_to_free
1254     }
1255 
1256     // Actually free jobs that were cleaned up.
1257     free_jobs_to_free_later();
1258 
1259     if (channel_need_redraw)
1260     {
1261 	channel_need_redraw = FALSE;
1262 	redraw_after_callback(TRUE);
1263     }
1264     return did_end;
1265 }
1266 
1267 /*
1268  * Create a job and return it.  Implements job_start().
1269  * "argv_arg" is only for Unix.
1270  * When "argv_arg" is NULL then "argvars" is used.
1271  * The returned job has a refcount of one.
1272  * Returns NULL when out of memory.
1273  */
1274     job_T *
job_start(typval_T * argvars,char ** argv_arg UNUSED,jobopt_T * opt_arg,job_T ** term_job)1275 job_start(
1276 	typval_T    *argvars,
1277 	char	    **argv_arg UNUSED,
1278 	jobopt_T    *opt_arg,
1279 	job_T	    **term_job)
1280 {
1281     job_T	*job;
1282     char_u	*cmd = NULL;
1283     char	**argv = NULL;
1284     int		argc = 0;
1285     int		i;
1286 #ifndef USE_ARGV
1287     garray_T	ga;
1288 #endif
1289     jobopt_T	opt;
1290     ch_part_T	part;
1291 
1292     job = job_alloc();
1293     if (job == NULL)
1294 	return NULL;
1295 
1296     job->jv_status = JOB_FAILED;
1297 #ifndef USE_ARGV
1298     ga_init2(&ga, (int)sizeof(char*), 20);
1299 #endif
1300 
1301     if (opt_arg != NULL)
1302 	opt = *opt_arg;
1303     else
1304     {
1305 	// Default mode is NL.
1306 	clear_job_options(&opt);
1307 	opt.jo_mode = MODE_NL;
1308 	if (get_job_options(&argvars[1], &opt,
1309 		    JO_MODE_ALL + JO_CB_ALL + JO_TIMEOUT_ALL + JO_STOPONEXIT
1310 			 + JO_EXIT_CB + JO_OUT_IO + JO_BLOCK_WRITE,
1311 		     JO2_ENV + JO2_CWD) == FAIL)
1312 	    goto theend;
1313     }
1314 
1315     // Check that when io is "file" that there is a file name.
1316     for (part = PART_OUT; part < PART_COUNT; ++part)
1317 	if ((opt.jo_set & (JO_OUT_IO << (part - PART_OUT)))
1318 		&& opt.jo_io[part] == JIO_FILE
1319 		&& (!(opt.jo_set & (JO_OUT_NAME << (part - PART_OUT)))
1320 		    || *opt.jo_io_name[part] == NUL))
1321 	{
1322 	    emsg(_("E920: _io file requires _name to be set"));
1323 	    goto theend;
1324 	}
1325 
1326     if ((opt.jo_set & JO_IN_IO) && opt.jo_io[PART_IN] == JIO_BUFFER)
1327     {
1328 	buf_T *buf = NULL;
1329 
1330 	// check that we can find the buffer before starting the job
1331 	if (opt.jo_set & JO_IN_BUF)
1332 	{
1333 	    buf = buflist_findnr(opt.jo_io_buf[PART_IN]);
1334 	    if (buf == NULL)
1335 		semsg(_(e_nobufnr), (long)opt.jo_io_buf[PART_IN]);
1336 	}
1337 	else if (!(opt.jo_set & JO_IN_NAME))
1338 	{
1339 	    emsg(_("E915: in_io buffer requires in_buf or in_name to be set"));
1340 	}
1341 	else
1342 	    buf = buflist_find_by_name(opt.jo_io_name[PART_IN], FALSE);
1343 	if (buf == NULL)
1344 	    goto theend;
1345 	if (buf->b_ml.ml_mfp == NULL)
1346 	{
1347 	    char_u	numbuf[NUMBUFLEN];
1348 	    char_u	*s;
1349 
1350 	    if (opt.jo_set & JO_IN_BUF)
1351 	    {
1352 		sprintf((char *)numbuf, "%d", opt.jo_io_buf[PART_IN]);
1353 		s = numbuf;
1354 	    }
1355 	    else
1356 		s = opt.jo_io_name[PART_IN];
1357 	    semsg(_("E918: buffer must be loaded: %s"), s);
1358 	    goto theend;
1359 	}
1360 	job->jv_in_buf = buf;
1361     }
1362 
1363     job_set_options(job, &opt);
1364 
1365 #ifdef USE_ARGV
1366     if (argv_arg != NULL)
1367     {
1368 	// Make a copy of argv_arg for job->jv_argv.
1369 	for (i = 0; argv_arg[i] != NULL; i++)
1370 	    argc++;
1371 	argv = ALLOC_MULT(char *, argc + 1);
1372 	if (argv == NULL)
1373 	    goto theend;
1374 	for (i = 0; i < argc; i++)
1375 	    argv[i] = (char *)vim_strsave((char_u *)argv_arg[i]);
1376 	argv[argc] = NULL;
1377     }
1378     else
1379 #endif
1380     if (argvars[0].v_type == VAR_STRING)
1381     {
1382 	// Command is a string.
1383 	cmd = argvars[0].vval.v_string;
1384 	if (cmd == NULL || *skipwhite(cmd) == NUL)
1385 	{
1386 	    emsg(_(e_invarg));
1387 	    goto theend;
1388 	}
1389 
1390 	if (build_argv_from_string(cmd, &argv, &argc) == FAIL)
1391 	    goto theend;
1392     }
1393     else if (argvars[0].v_type != VAR_LIST
1394 	    || argvars[0].vval.v_list == NULL
1395 	    || argvars[0].vval.v_list->lv_len < 1)
1396     {
1397 	emsg(_(e_invarg));
1398 	goto theend;
1399     }
1400     else
1401     {
1402 	list_T *l = argvars[0].vval.v_list;
1403 
1404 	if (build_argv_from_list(l, &argv, &argc) == FAIL)
1405 	    goto theend;
1406 
1407 	// Empty command is invalid.
1408 	if (argc == 0 || *skipwhite((char_u *)argv[0]) == NUL)
1409 	{
1410 	    emsg(_(e_invarg));
1411 	    goto theend;
1412 	}
1413 #ifndef USE_ARGV
1414 	if (win32_build_cmd(l, &ga) == FAIL)
1415 	    goto theend;
1416 	cmd = ga.ga_data;
1417 	if (cmd == NULL || *skipwhite(cmd) == NUL)
1418 	{
1419 	    emsg(_(e_invarg));
1420 	    goto theend;
1421 	}
1422 #endif
1423     }
1424 
1425     // Save the command used to start the job.
1426     job->jv_argv = argv;
1427 
1428     if (term_job != NULL)
1429 	*term_job = job;
1430 
1431 #ifdef USE_ARGV
1432     if (ch_log_active())
1433     {
1434 	garray_T    ga;
1435 
1436 	ga_init2(&ga, (int)sizeof(char), 200);
1437 	for (i = 0; i < argc; ++i)
1438 	{
1439 	    if (i > 0)
1440 		ga_concat(&ga, (char_u *)"  ");
1441 	    ga_concat(&ga, (char_u *)argv[i]);
1442 	}
1443 	ga_append(&ga, NUL);
1444 	ch_log(NULL, "Starting job: %s", (char *)ga.ga_data);
1445 	ga_clear(&ga);
1446     }
1447     mch_job_start(argv, job, &opt, term_job != NULL);
1448 #else
1449     ch_log(NULL, "Starting job: %s", (char *)cmd);
1450     mch_job_start((char *)cmd, job, &opt);
1451 #endif
1452 
1453     // If the channel is reading from a buffer, write lines now.
1454     if (job->jv_channel != NULL)
1455 	channel_write_in(job->jv_channel);
1456 
1457 theend:
1458 #ifndef USE_ARGV
1459     vim_free(ga.ga_data);
1460 #endif
1461     if (argv != NULL && argv != job->jv_argv)
1462     {
1463 	for (i = 0; argv[i] != NULL; i++)
1464 	    vim_free(argv[i]);
1465 	vim_free(argv);
1466     }
1467     free_job_options(&opt);
1468     return job;
1469 }
1470 
1471 /*
1472  * Get the status of "job" and invoke the exit callback when needed.
1473  * The returned string is not allocated.
1474  */
1475     char *
job_status(job_T * job)1476 job_status(job_T *job)
1477 {
1478     char	*result;
1479 
1480     if (job->jv_status >= JOB_ENDED)
1481 	// No need to check, dead is dead.
1482 	result = "dead";
1483     else if (job->jv_status == JOB_FAILED)
1484 	result = "fail";
1485     else
1486     {
1487 	result = mch_job_status(job);
1488 	if (job->jv_status == JOB_ENDED)
1489 	    job_cleanup(job);
1490     }
1491     return result;
1492 }
1493 
1494 /*
1495  * Send a signal to "job".  Implements job_stop().
1496  * When "type" is not NULL use this for the type.
1497  * Otherwise use argvars[1] for the type.
1498  */
1499     int
job_stop(job_T * job,typval_T * argvars,char * type)1500 job_stop(job_T *job, typval_T *argvars, char *type)
1501 {
1502     char_u *arg;
1503 
1504     if (type != NULL)
1505 	arg = (char_u *)type;
1506     else if (argvars[1].v_type == VAR_UNKNOWN)
1507 	arg = (char_u *)"";
1508     else
1509     {
1510 	arg = tv_get_string_chk(&argvars[1]);
1511 	if (arg == NULL)
1512 	{
1513 	    emsg(_(e_invarg));
1514 	    return 0;
1515 	}
1516     }
1517     if (job->jv_status == JOB_FAILED)
1518     {
1519 	ch_log(job->jv_channel, "Job failed to start, job_stop() skipped");
1520 	return 0;
1521     }
1522     if (job->jv_status == JOB_ENDED)
1523     {
1524 	ch_log(job->jv_channel, "Job has already ended, job_stop() skipped");
1525 	return 0;
1526     }
1527     ch_log(job->jv_channel, "Stopping job with '%s'", (char *)arg);
1528     if (mch_signal_job(job, arg) == FAIL)
1529 	return 0;
1530 
1531     // Assume that only "kill" will kill the job.
1532     if (job->jv_channel != NULL && STRCMP(arg, "kill") == 0)
1533 	job->jv_channel->ch_job_killed = TRUE;
1534 
1535     // We don't try freeing the job, obviously the caller still has a
1536     // reference to it.
1537     return 1;
1538 }
1539 
1540     void
invoke_prompt_callback(void)1541 invoke_prompt_callback(void)
1542 {
1543     typval_T	rettv;
1544     typval_T	argv[2];
1545     char_u	*text;
1546     char_u	*prompt;
1547     linenr_T	lnum = curbuf->b_ml.ml_line_count;
1548 
1549     // Add a new line for the prompt before invoking the callback, so that
1550     // text can always be inserted above the last line.
1551     ml_append(lnum, (char_u  *)"", 0, FALSE);
1552     curwin->w_cursor.lnum = lnum + 1;
1553     curwin->w_cursor.col = 0;
1554 
1555     if (curbuf->b_prompt_callback.cb_name == NULL
1556 	    || *curbuf->b_prompt_callback.cb_name == NUL)
1557 	return;
1558     text = ml_get(lnum);
1559     prompt = prompt_text();
1560     if (STRLEN(text) >= STRLEN(prompt))
1561 	text += STRLEN(prompt);
1562     argv[0].v_type = VAR_STRING;
1563     argv[0].vval.v_string = vim_strsave(text);
1564     argv[1].v_type = VAR_UNKNOWN;
1565 
1566     call_callback(&curbuf->b_prompt_callback, -1, &rettv, 1, argv);
1567     clear_tv(&argv[0]);
1568     clear_tv(&rettv);
1569 }
1570 
1571 /*
1572  * Return TRUE when the interrupt callback was invoked.
1573  */
1574     int
invoke_prompt_interrupt(void)1575 invoke_prompt_interrupt(void)
1576 {
1577     typval_T	rettv;
1578     typval_T	argv[1];
1579 
1580     if (curbuf->b_prompt_interrupt.cb_name == NULL
1581 	    || *curbuf->b_prompt_interrupt.cb_name == NUL)
1582 	return FALSE;
1583     argv[0].v_type = VAR_UNKNOWN;
1584 
1585     got_int = FALSE; // don't skip executing commands
1586     call_callback(&curbuf->b_prompt_interrupt, -1, &rettv, 0, argv);
1587     clear_tv(&rettv);
1588     return TRUE;
1589 }
1590 
1591 /*
1592  * Return the effective prompt for the specified buffer.
1593  */
1594     static char_u *
buf_prompt_text(buf_T * buf)1595 buf_prompt_text(buf_T* buf)
1596 {
1597     if (buf->b_prompt_text == NULL)
1598 	return (char_u *)"% ";
1599     return buf->b_prompt_text;
1600 }
1601 
1602 /*
1603  * Return the effective prompt for the current buffer.
1604  */
1605     char_u *
prompt_text(void)1606 prompt_text(void)
1607 {
1608     return buf_prompt_text(curbuf);
1609 }
1610 
1611 
1612 /*
1613  * Prepare for prompt mode: Make sure the last line has the prompt text.
1614  * Move the cursor to this line.
1615  */
1616     void
init_prompt(int cmdchar_todo)1617 init_prompt(int cmdchar_todo)
1618 {
1619     char_u *prompt = prompt_text();
1620     char_u *text;
1621 
1622     curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
1623     text = ml_get_curline();
1624     if (STRNCMP(text, prompt, STRLEN(prompt)) != 0)
1625     {
1626 	// prompt is missing, insert it or append a line with it
1627 	if (*text == NUL)
1628 	    ml_replace(curbuf->b_ml.ml_line_count, prompt, TRUE);
1629 	else
1630 	    ml_append(curbuf->b_ml.ml_line_count, prompt, 0, FALSE);
1631 	curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
1632 	coladvance((colnr_T)MAXCOL);
1633 	changed_bytes(curbuf->b_ml.ml_line_count, 0);
1634     }
1635 
1636     // Insert always starts after the prompt, allow editing text after it.
1637     if (Insstart_orig.lnum != curwin->w_cursor.lnum
1638 				   || Insstart_orig.col != (int)STRLEN(prompt))
1639 	set_insstart(curwin->w_cursor.lnum, (int)STRLEN(prompt));
1640 
1641     if (cmdchar_todo == 'A')
1642 	coladvance((colnr_T)MAXCOL);
1643     if (curwin->w_cursor.col < (int)STRLEN(prompt))
1644 	curwin->w_cursor.col = (int)STRLEN(prompt);
1645     // Make sure the cursor is in a valid position.
1646     check_cursor();
1647 }
1648 
1649 /*
1650  * Return TRUE if the cursor is in the editable position of the prompt line.
1651  */
1652     int
prompt_curpos_editable()1653 prompt_curpos_editable()
1654 {
1655     return curwin->w_cursor.lnum == curbuf->b_ml.ml_line_count
1656 	&& curwin->w_cursor.col >= (int)STRLEN(prompt_text());
1657 }
1658 
1659 /*
1660  * "prompt_setcallback({buffer}, {callback})" function
1661  */
1662     void
f_prompt_setcallback(typval_T * argvars,typval_T * rettv UNUSED)1663 f_prompt_setcallback(typval_T *argvars, typval_T *rettv UNUSED)
1664 {
1665     buf_T	*buf;
1666     callback_T	callback;
1667 
1668     if (check_secure())
1669 	return;
1670 
1671     if (in_vim9script() && check_for_buffer_arg(argvars, 0) == FAIL)
1672 	return;
1673 
1674     buf = tv_get_buf(&argvars[0], FALSE);
1675     if (buf == NULL)
1676 	return;
1677 
1678     callback = get_callback(&argvars[1]);
1679     if (callback.cb_name == NULL)
1680 	return;
1681 
1682     free_callback(&buf->b_prompt_callback);
1683     set_callback(&buf->b_prompt_callback, &callback);
1684 }
1685 
1686 /*
1687  * "prompt_setinterrupt({buffer}, {callback})" function
1688  */
1689     void
f_prompt_setinterrupt(typval_T * argvars,typval_T * rettv UNUSED)1690 f_prompt_setinterrupt(typval_T *argvars, typval_T *rettv UNUSED)
1691 {
1692     buf_T	*buf;
1693     callback_T	callback;
1694 
1695     if (check_secure())
1696 	return;
1697 
1698     if (in_vim9script() && check_for_buffer_arg(argvars, 0) == FAIL)
1699 	return;
1700 
1701     buf = tv_get_buf(&argvars[0], FALSE);
1702     if (buf == NULL)
1703 	return;
1704 
1705     callback = get_callback(&argvars[1]);
1706     if (callback.cb_name == NULL)
1707 	return;
1708 
1709     free_callback(&buf->b_prompt_interrupt);
1710     set_callback(&buf->b_prompt_interrupt, &callback);
1711 }
1712 
1713 
1714 /*
1715  * "prompt_getprompt({buffer})" function
1716  */
1717     void
f_prompt_getprompt(typval_T * argvars,typval_T * rettv)1718 f_prompt_getprompt(typval_T *argvars, typval_T *rettv)
1719 {
1720     buf_T	*buf;
1721 
1722     // return an empty string by default, e.g. it's not a prompt buffer
1723     rettv->v_type = VAR_STRING;
1724     rettv->vval.v_string = NULL;
1725 
1726     if (in_vim9script() && check_for_buffer_arg(argvars, 0) == FAIL)
1727 	return;
1728 
1729     buf = tv_get_buf_from_arg(&argvars[0]);
1730     if (buf == NULL)
1731 	return;
1732 
1733     if (!bt_prompt(buf))
1734 	return;
1735 
1736     rettv->vval.v_string = vim_strsave(buf_prompt_text(buf));
1737 }
1738 
1739 /*
1740  * "prompt_setprompt({buffer}, {text})" function
1741  */
1742     void
f_prompt_setprompt(typval_T * argvars,typval_T * rettv UNUSED)1743 f_prompt_setprompt(typval_T *argvars, typval_T *rettv UNUSED)
1744 {
1745     buf_T	*buf;
1746     char_u	*text;
1747 
1748     if (in_vim9script()
1749 	    && (check_for_buffer_arg(argvars, 0) == FAIL
1750 		|| check_for_string_arg(argvars, 1) == FAIL))
1751 	return;
1752 
1753     if (check_secure())
1754 	return;
1755     buf = tv_get_buf(&argvars[0], FALSE);
1756     if (buf == NULL)
1757 	return;
1758 
1759     text = tv_get_string(&argvars[1]);
1760     vim_free(buf->b_prompt_text);
1761     buf->b_prompt_text = vim_strsave(text);
1762 }
1763 
1764 /*
1765  * Get the job from the argument.
1766  * Returns NULL if the job is invalid.
1767  */
1768     static job_T *
get_job_arg(typval_T * tv)1769 get_job_arg(typval_T *tv)
1770 {
1771     job_T *job;
1772 
1773     if (tv->v_type != VAR_JOB)
1774     {
1775 	semsg(_(e_invarg2), tv_get_string(tv));
1776 	return NULL;
1777     }
1778     job = tv->vval.v_job;
1779 
1780     if (job == NULL)
1781 	emsg(_("E916: not a valid job"));
1782     return job;
1783 }
1784 
1785 /*
1786  * "job_getchannel()" function
1787  */
1788     void
f_job_getchannel(typval_T * argvars,typval_T * rettv)1789 f_job_getchannel(typval_T *argvars, typval_T *rettv)
1790 {
1791     job_T	*job;
1792 
1793     if (in_vim9script() && check_for_job_arg(argvars, 0) == FAIL)
1794 	return;
1795 
1796     job = get_job_arg(&argvars[0]);
1797     if (job != NULL)
1798     {
1799 	rettv->v_type = VAR_CHANNEL;
1800 	rettv->vval.v_channel = job->jv_channel;
1801 	if (job->jv_channel != NULL)
1802 	    ++job->jv_channel->ch_refcount;
1803     }
1804 }
1805 
1806 /*
1807  * Implementation of job_info().
1808  */
1809     static void
job_info(job_T * job,dict_T * dict)1810 job_info(job_T *job, dict_T *dict)
1811 {
1812     dictitem_T	*item;
1813     varnumber_T	nr;
1814     list_T	*l;
1815     int		i;
1816 
1817     dict_add_string(dict, "status", (char_u *)job_status(job));
1818 
1819     item = dictitem_alloc((char_u *)"channel");
1820     if (item == NULL)
1821 	return;
1822     item->di_tv.v_type = VAR_CHANNEL;
1823     item->di_tv.vval.v_channel = job->jv_channel;
1824     if (job->jv_channel != NULL)
1825 	++job->jv_channel->ch_refcount;
1826     if (dict_add(dict, item) == FAIL)
1827 	dictitem_free(item);
1828 
1829 #ifdef UNIX
1830     nr = job->jv_pid;
1831 #else
1832     nr = job->jv_proc_info.dwProcessId;
1833 #endif
1834     dict_add_number(dict, "process", nr);
1835     dict_add_string(dict, "tty_in", job->jv_tty_in);
1836     dict_add_string(dict, "tty_out", job->jv_tty_out);
1837 
1838     dict_add_number(dict, "exitval", job->jv_exitval);
1839     dict_add_string(dict, "exit_cb", job->jv_exit_cb.cb_name);
1840     dict_add_string(dict, "stoponexit", job->jv_stoponexit);
1841 #ifdef UNIX
1842     dict_add_string(dict, "termsig", job->jv_termsig);
1843 #endif
1844 #ifdef MSWIN
1845     dict_add_string(dict, "tty_type", job->jv_tty_type);
1846 #endif
1847 
1848     l = list_alloc();
1849     if (l != NULL)
1850     {
1851 	dict_add_list(dict, "cmd", l);
1852 	if (job->jv_argv != NULL)
1853 	    for (i = 0; job->jv_argv[i] != NULL; i++)
1854 		list_append_string(l, (char_u *)job->jv_argv[i], -1);
1855     }
1856 }
1857 
1858 /*
1859  * Implementation of job_info() to return info for all jobs.
1860  */
1861     static void
job_info_all(list_T * l)1862 job_info_all(list_T *l)
1863 {
1864     job_T	*job;
1865     typval_T	tv;
1866 
1867     FOR_ALL_JOBS(job)
1868     {
1869 	tv.v_type = VAR_JOB;
1870 	tv.vval.v_job = job;
1871 
1872 	if (list_append_tv(l, &tv) != OK)
1873 	    return;
1874     }
1875 }
1876 
1877 /*
1878  * "job_info()" function
1879  */
1880     void
f_job_info(typval_T * argvars,typval_T * rettv)1881 f_job_info(typval_T *argvars, typval_T *rettv)
1882 {
1883     if (in_vim9script() && check_for_opt_job_arg(argvars, 0) == FAIL)
1884 	return;
1885 
1886     if (argvars[0].v_type != VAR_UNKNOWN)
1887     {
1888 	job_T	*job;
1889 
1890 	job = get_job_arg(&argvars[0]);
1891 	if (job != NULL && rettv_dict_alloc(rettv) != FAIL)
1892 	    job_info(job, rettv->vval.v_dict);
1893     }
1894     else if (rettv_list_alloc(rettv) == OK)
1895 	job_info_all(rettv->vval.v_list);
1896 }
1897 
1898 /*
1899  * "job_setoptions()" function
1900  */
1901     void
f_job_setoptions(typval_T * argvars,typval_T * rettv UNUSED)1902 f_job_setoptions(typval_T *argvars, typval_T *rettv UNUSED)
1903 {
1904     job_T	*job;
1905     jobopt_T	opt;
1906 
1907     if (in_vim9script()
1908 	    && (check_for_job_arg(argvars, 0) == FAIL
1909 		|| check_for_dict_arg(argvars, 1) == FAIL))
1910 	return;
1911 
1912     job = get_job_arg(&argvars[0]);
1913     if (job == NULL)
1914 	return;
1915     clear_job_options(&opt);
1916     if (get_job_options(&argvars[1], &opt, JO_STOPONEXIT + JO_EXIT_CB, 0) == OK)
1917 	job_set_options(job, &opt);
1918     free_job_options(&opt);
1919 }
1920 
1921 /*
1922  * "job_start()" function
1923  */
1924     void
f_job_start(typval_T * argvars,typval_T * rettv)1925 f_job_start(typval_T *argvars, typval_T *rettv)
1926 {
1927     rettv->v_type = VAR_JOB;
1928     if (check_restricted() || check_secure())
1929 	return;
1930 
1931     if (in_vim9script()
1932 	    && (check_for_string_or_list_arg(argvars, 0) == FAIL
1933 		|| check_for_opt_dict_arg(argvars, 1) == FAIL))
1934 	return;
1935 
1936     rettv->vval.v_job = job_start(argvars, NULL, NULL, NULL);
1937 }
1938 
1939 /*
1940  * "job_status()" function
1941  */
1942     void
f_job_status(typval_T * argvars,typval_T * rettv)1943 f_job_status(typval_T *argvars, typval_T *rettv)
1944 {
1945     if (in_vim9script() && check_for_job_arg(argvars, 0) == FAIL)
1946 	return;
1947 
1948     if (argvars[0].v_type == VAR_JOB && argvars[0].vval.v_job == NULL)
1949     {
1950 	// A job that never started returns "fail".
1951 	rettv->v_type = VAR_STRING;
1952 	rettv->vval.v_string = vim_strsave((char_u *)"fail");
1953     }
1954     else
1955     {
1956 	job_T	*job = get_job_arg(&argvars[0]);
1957 
1958 	if (job != NULL)
1959 	{
1960 	    rettv->v_type = VAR_STRING;
1961 	    rettv->vval.v_string = vim_strsave((char_u *)job_status(job));
1962 	}
1963     }
1964 }
1965 
1966 /*
1967  * "job_stop()" function
1968  */
1969     void
f_job_stop(typval_T * argvars,typval_T * rettv)1970 f_job_stop(typval_T *argvars, typval_T *rettv)
1971 {
1972     job_T	*job;
1973 
1974     if (in_vim9script()
1975 	    && (check_for_job_arg(argvars, 0) == FAIL
1976 		|| check_for_opt_string_or_number_arg(argvars, 1) == FAIL))
1977 	return;
1978 
1979     job = get_job_arg(&argvars[0]);
1980     if (job != NULL)
1981 	rettv->vval.v_number = job_stop(job, argvars, NULL);
1982 }
1983 
1984 /*
1985  * Get a string with information about the job in "varp" in "buf".
1986  * "buf" must be at least NUMBUFLEN long.
1987  */
1988     char_u *
job_to_string_buf(typval_T * varp,char_u * buf)1989 job_to_string_buf(typval_T *varp, char_u *buf)
1990 {
1991     job_T *job = varp->vval.v_job;
1992     char  *status;
1993 
1994     if (job == NULL)
1995     {
1996 	vim_snprintf((char *)buf, NUMBUFLEN, "no process");
1997 	return buf;
1998     }
1999     status = job->jv_status == JOB_FAILED ? "fail"
2000 		    : job->jv_status >= JOB_ENDED ? "dead"
2001 		    : "run";
2002 # ifdef UNIX
2003     vim_snprintf((char *)buf, NUMBUFLEN,
2004 		"process %ld %s", (long)job->jv_pid, status);
2005 # elif defined(MSWIN)
2006     vim_snprintf((char *)buf, NUMBUFLEN,
2007 		"process %ld %s",
2008 		(long)job->jv_proc_info.dwProcessId,
2009 		status);
2010 # else
2011     // fall-back
2012     vim_snprintf((char *)buf, NUMBUFLEN, "process ? %s", status);
2013 # endif
2014     return buf;
2015 }
2016 
2017 #endif // FEAT_JOB_CHANNEL
2018