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