OSDN Git Service

Upgrade to mksh R56c.
[android-x86/external-mksh.git] / src / jobs.c
1 /*      $OpenBSD: jobs.c,v 1.43 2015/09/10 22:48:58 nicm Exp $  */
2
3 /*-
4  * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2011,
5  *               2012, 2013, 2014, 2015, 2016, 2018
6  *      mirabilos <m@mirbsd.org>
7  *
8  * Provided that these terms and disclaimer and all copyright notices
9  * are retained or reproduced in an accompanying document, permission
10  * is granted to deal in this work without restriction, including un-
11  * limited rights to use, publicly perform, distribute, sell, modify,
12  * merge, give away, or sublicence.
13  *
14  * This work is provided "AS IS" and WITHOUT WARRANTY of any kind, to
15  * the utmost extent permitted by applicable law, neither express nor
16  * implied; without malicious intent or gross negligence. In no event
17  * may a licensor, author or contributor be held liable for indirect,
18  * direct, other damage, loss, or other issues arising in any way out
19  * of dealing in the work, even if advised of the possibility of such
20  * damage or existence of a defect, except proven that it results out
21  * of said person's immediate fault when using the work as intended.
22  */
23
24 #include "sh.h"
25
26 __RCSID("$MirOS: src/bin/mksh/jobs.c,v 1.125 2018/01/05 20:08:34 tg Exp $");
27
28 #if HAVE_KILLPG
29 #define mksh_killpg             killpg
30 #else
31 /* cross fingers and hope kill is killpg-endowed */
32 #define mksh_killpg(p,s)        kill(-(p), (s))
33 #endif
34
35 /* Order important! */
36 #define PRUNNING        0
37 #define PEXITED         1
38 #define PSIGNALLED      2
39 #define PSTOPPED        3
40
41 typedef struct proc Proc;
42 /* to take alignment into consideration */
43 struct proc_dummy {
44         Proc *next;
45         pid_t pid;
46         int state;
47         int status;
48         char command[128];
49 };
50 /* real structure */
51 struct proc {
52         /* next process in pipeline (if any) */
53         Proc *next;
54         /* process id of this Unix process in the job */
55         pid_t pid;
56         /* one of the four P… above */
57         int state;
58         /* wait status */
59         int status;
60         /* process command string from vistree */
61         char command[256 - (ALLOC_OVERHEAD +
62             offsetof(struct proc_dummy, command[0]))];
63 };
64
65 /* Notify/print flag - j_print() argument */
66 #define JP_SHORT        1       /* print signals processes were killed by */
67 #define JP_MEDIUM       2       /* print [job-num] -/+ command */
68 #define JP_LONG         3       /* print [job-num] -/+ pid command */
69 #define JP_PGRP         4       /* print pgrp */
70
71 /* put_job() flags */
72 #define PJ_ON_FRONT     0       /* at very front */
73 #define PJ_PAST_STOPPED 1       /* just past any stopped jobs */
74
75 /* Job.flags values */
76 #define JF_STARTED      0x001   /* set when all processes in job are started */
77 #define JF_WAITING      0x002   /* set if j_waitj() is waiting on job */
78 #define JF_W_ASYNCNOTIFY 0x004  /* set if waiting and async notification ok */
79 #define JF_XXCOM        0x008   /* set for $(command) jobs */
80 #define JF_FG           0x010   /* running in foreground (also has tty pgrp) */
81 #define JF_SAVEDTTY     0x020   /* j->ttystat is valid */
82 #define JF_CHANGED      0x040   /* process has changed state */
83 #define JF_KNOWN        0x080   /* $! referenced */
84 #define JF_ZOMBIE       0x100   /* known, unwaited process */
85 #define JF_REMOVE       0x200   /* flagged for removal (j_jobs()/j_noityf()) */
86 #define JF_USETTYMODE   0x400   /* tty mode saved if process exits normally */
87 #define JF_SAVEDTTYPGRP 0x800   /* j->saved_ttypgrp is valid */
88
89 typedef struct job Job;
90 struct job {
91         Job *next;              /* next job in list */
92         Proc *proc_list;        /* process list */
93         Proc *last_proc;        /* last process in list */
94         struct timeval systime; /* system time used by job */
95         struct timeval usrtime; /* user time used by job */
96         pid_t pgrp;             /* process group of job */
97         pid_t ppid;             /* pid of process that forked job */
98         int job;                /* job number: %n */
99         int flags;              /* see JF_* */
100         volatile int state;     /* job state */
101         int status;             /* exit status of last process */
102         int age;                /* number of jobs started */
103         Coproc_id coproc_id;    /* 0 or id of coprocess output pipe */
104 #ifndef MKSH_UNEMPLOYED
105         mksh_ttyst ttystat;     /* saved tty state for stopped jobs */
106         pid_t saved_ttypgrp;    /* saved tty process group for stopped jobs */
107 #endif
108 };
109
110 /* Flags for j_waitj() */
111 #define JW_NONE         0x00
112 #define JW_INTERRUPT    0x01    /* ^C will stop the wait */
113 #define JW_ASYNCNOTIFY  0x02    /* asynchronous notification during wait ok */
114 #define JW_STOPPEDWAIT  0x04    /* wait even if job stopped */
115 #define JW_PIPEST       0x08    /* want PIPESTATUS */
116
117 /* Error codes for j_lookup() */
118 #define JL_NOSUCH       0       /* no such job */
119 #define JL_AMBIG        1       /* %foo or %?foo is ambiguous */
120 #define JL_INVALID      2       /* non-pid, non-% job id */
121
122 static const char * const lookup_msgs[] = {
123         "no such job",
124         "ambiguous",
125         "argument must be %job or process id"
126 };
127
128 static Job *job_list;           /* job list */
129 static Job *last_job;
130 static Job *async_job;
131 static pid_t async_pid;
132
133 static int nzombie;             /* # of zombies owned by this process */
134 static int njobs;               /* # of jobs started */
135
136 #ifndef CHILD_MAX
137 #define CHILD_MAX       25
138 #endif
139
140 #ifndef MKSH_NOPROSPECTOFWORK
141 /* held_sigchld is set if sigchld occurs before a job is completely started */
142 static volatile sig_atomic_t held_sigchld;
143 #endif
144
145 #ifndef MKSH_UNEMPLOYED
146 static struct shf       *shl_j;
147 static bool             ttypgrp_ok;     /* set if can use tty pgrps */
148 static pid_t            restore_ttypgrp = -1;
149 static int const        tt_sigs[] = { SIGTSTP, SIGTTIN, SIGTTOU };
150 #endif
151
152 static void             j_set_async(Job *);
153 static void             j_startjob(Job *);
154 static int              j_waitj(Job *, int, const char *);
155 static void             j_sigchld(int);
156 static void             j_print(Job *, int, struct shf *);
157 static Job              *j_lookup(const char *, int *);
158 static Job              *new_job(void);
159 static Proc             *new_proc(void);
160 static void             check_job(Job *);
161 static void             put_job(Job *, int);
162 static void             remove_job(Job *, const char *);
163 static int              kill_job(Job *, int);
164
165 static void tty_init_talking(void);
166 static void tty_init_state(void);
167
168 /* initialise job control */
169 void
170 j_init(void)
171 {
172 #ifndef MKSH_UNEMPLOYED
173         bool mflagset = Flag(FMONITOR) != 127;
174
175         Flag(FMONITOR) = 0;
176 #endif
177
178 #ifndef MKSH_NOPROSPECTOFWORK
179         (void)sigemptyset(&sm_default);
180         sigprocmask(SIG_SETMASK, &sm_default, NULL);
181
182         (void)sigemptyset(&sm_sigchld);
183         (void)sigaddset(&sm_sigchld, SIGCHLD);
184
185         setsig(&sigtraps[SIGCHLD], j_sigchld,
186             SS_RESTORE_ORIG|SS_FORCE|SS_SHTRAP);
187 #else
188         /* Make sure SIGCHLD isn't ignored - can do odd things under SYSV */
189         setsig(&sigtraps[SIGCHLD], SIG_DFL, SS_RESTORE_ORIG|SS_FORCE);
190 #endif
191
192 #ifndef MKSH_UNEMPLOYED
193         if (!mflagset && Flag(FTALKING))
194                 Flag(FMONITOR) = 1;
195
196         /*
197          * shl_j is used to do asynchronous notification (used in
198          * an interrupt handler, so need a distinct shf)
199          */
200         shl_j = shf_fdopen(2, SHF_WR, NULL);
201
202         if (Flag(FMONITOR) || Flag(FTALKING)) {
203                 int i;
204
205                 /*
206                  * the TF_SHELL_USES test is a kludge that lets us know if
207                  * if the signals have been changed by the shell.
208                  */
209                 for (i = NELEM(tt_sigs); --i >= 0; ) {
210                         sigtraps[tt_sigs[i]].flags |= TF_SHELL_USES;
211                         /* j_change() sets this to SS_RESTORE_DFL if FMONITOR */
212                         setsig(&sigtraps[tt_sigs[i]], SIG_IGN,
213                             SS_RESTORE_IGN|SS_FORCE);
214                 }
215         }
216
217         /* j_change() calls tty_init_talking() and tty_init_state() */
218         if (Flag(FMONITOR))
219                 j_change();
220         else
221 #endif
222           if (Flag(FTALKING)) {
223                 tty_init_talking();
224                 tty_init_state();
225         }
226 }
227
228 static int
229 proc_errorlevel(Proc *p)
230 {
231         switch (p->state) {
232         case PEXITED:
233                 return ((WEXITSTATUS(p->status)) & 255);
234         case PSIGNALLED:
235                 return (ksh_sigmask(WTERMSIG(p->status)));
236         default:
237                 return (0);
238         }
239 }
240
241 #if !defined(MKSH_UNEMPLOYED) && HAVE_GETSID
242 /* suspend the shell */
243 void
244 j_suspend(void)
245 {
246         struct sigaction sa, osa;
247
248         /* Restore tty and pgrp. */
249         if (ttypgrp_ok) {
250                 if (tty_hasstate)
251                         mksh_tcset(tty_fd, &tty_state);
252                 if (restore_ttypgrp >= 0) {
253                         if (tcsetpgrp(tty_fd, restore_ttypgrp) < 0) {
254                                 warningf(false, Tf_ssfaileds,
255                                     Tj_suspend, "tcsetpgrp", cstrerror(errno));
256                         } else if (setpgid(0, restore_ttypgrp) < 0) {
257                                 warningf(false, Tf_ssfaileds,
258                                     Tj_suspend, "setpgid", cstrerror(errno));
259                         }
260                 }
261         }
262
263         /* Suspend the shell. */
264         memset(&sa, 0, sizeof(sa));
265         sigemptyset(&sa.sa_mask);
266         sa.sa_handler = SIG_DFL;
267         sigaction(SIGTSTP, &sa, &osa);
268         kill(0, SIGTSTP);
269
270         /* Back from suspend, reset signals, pgrp and tty. */
271         sigaction(SIGTSTP, &osa, NULL);
272         if (ttypgrp_ok) {
273                 if (restore_ttypgrp >= 0) {
274                         if (setpgid(0, kshpid) < 0) {
275                                 warningf(false, Tf_ssfaileds,
276                                     Tj_suspend, "setpgid", cstrerror(errno));
277                                 ttypgrp_ok = false;
278                         } else if (tcsetpgrp(tty_fd, kshpid) < 0) {
279                                 warningf(false, Tf_ssfaileds,
280                                     Tj_suspend, "tcsetpgrp", cstrerror(errno));
281                                 ttypgrp_ok = false;
282                         }
283                 }
284                 tty_init_state();
285         }
286 }
287 #endif
288
289 /* job cleanup before shell exit */
290 void
291 j_exit(void)
292 {
293         /* kill stopped, and possibly running, jobs */
294         Job *j;
295         bool killed = false;
296
297         for (j = job_list; j != NULL; j = j->next) {
298                 if (j->ppid == procpid &&
299                     (j->state == PSTOPPED ||
300                     (j->state == PRUNNING &&
301                     ((j->flags & JF_FG) ||
302                     (Flag(FLOGIN) && !Flag(FNOHUP) && procpid == kshpid))))) {
303                         killed = true;
304                         if (j->pgrp == 0)
305                                 kill_job(j, SIGHUP);
306                         else
307                                 mksh_killpg(j->pgrp, SIGHUP);
308 #ifndef MKSH_UNEMPLOYED
309                         if (j->state == PSTOPPED) {
310                                 if (j->pgrp == 0)
311                                         kill_job(j, SIGCONT);
312                                 else
313                                         mksh_killpg(j->pgrp, SIGCONT);
314                         }
315 #endif
316                 }
317         }
318         if (killed)
319                 sleep(1);
320         j_notify();
321
322 #ifndef MKSH_UNEMPLOYED
323         if (kshpid == procpid && restore_ttypgrp >= 0) {
324                 /*
325                  * Need to restore the tty pgrp to what it was when the
326                  * shell started up, so that the process that started us
327                  * will be able to access the tty when we are done.
328                  * Also need to restore our process group in case we are
329                  * about to do an exec so that both our parent and the
330                  * process we are to become will be able to access the tty.
331                  */
332                 tcsetpgrp(tty_fd, restore_ttypgrp);
333                 setpgid(0, restore_ttypgrp);
334         }
335         if (Flag(FMONITOR)) {
336                 Flag(FMONITOR) = 0;
337                 j_change();
338         }
339 #endif
340 }
341
342 #ifndef MKSH_UNEMPLOYED
343 /* turn job control on or off according to Flag(FMONITOR) */
344 void
345 j_change(void)
346 {
347         int i;
348
349         if (Flag(FMONITOR)) {
350                 bool use_tty = Flag(FTALKING);
351
352                 /* don't call mksh_tcget until we own the tty process group */
353                 if (use_tty)
354                         tty_init_talking();
355
356                 /* no controlling tty, no SIGT* */
357                 if ((ttypgrp_ok = (use_tty && tty_fd >= 0 && tty_devtty))) {
358                         setsig(&sigtraps[SIGTTIN], SIG_DFL,
359                             SS_RESTORE_ORIG|SS_FORCE);
360                         /* wait to be given tty (POSIX.1, B.2, job control) */
361                         while (/* CONSTCOND */ 1) {
362                                 pid_t ttypgrp;
363
364                                 if ((ttypgrp = tcgetpgrp(tty_fd)) < 0) {
365                                         warningf(false, Tf_ssfaileds,
366                                             "j_init", "tcgetpgrp",
367                                             cstrerror(errno));
368                                         ttypgrp_ok = false;
369                                         break;
370                                 }
371                                 if (ttypgrp == kshpgrp)
372                                         break;
373                                 kill(0, SIGTTIN);
374                         }
375                 }
376                 for (i = NELEM(tt_sigs); --i >= 0; )
377                         setsig(&sigtraps[tt_sigs[i]], SIG_IGN,
378                             SS_RESTORE_DFL|SS_FORCE);
379                 if (ttypgrp_ok && kshpgrp != kshpid) {
380                         if (setpgid(0, kshpid) < 0) {
381                                 warningf(false, Tf_ssfaileds,
382                                     "j_init", "setpgid", cstrerror(errno));
383                                 ttypgrp_ok = false;
384                         } else {
385                                 if (tcsetpgrp(tty_fd, kshpid) < 0) {
386                                         warningf(false, Tf_ssfaileds,
387                                             "j_init", "tcsetpgrp",
388                                             cstrerror(errno));
389                                         ttypgrp_ok = false;
390                                 } else
391                                         restore_ttypgrp = kshpgrp;
392                                 kshpgrp = kshpid;
393                         }
394                 }
395 #ifndef MKSH_DISABLE_TTY_WARNING
396                 if (use_tty && !ttypgrp_ok)
397                         warningf(false, Tf_sD_s, "warning",
398                             "won't have full job control");
399 #endif
400         } else {
401                 ttypgrp_ok = false;
402                 if (Flag(FTALKING))
403                         for (i = NELEM(tt_sigs); --i >= 0; )
404                                 setsig(&sigtraps[tt_sigs[i]], SIG_IGN,
405                                     SS_RESTORE_IGN|SS_FORCE);
406                 else
407                         for (i = NELEM(tt_sigs); --i >= 0; ) {
408                                 if (sigtraps[tt_sigs[i]].flags &
409                                     (TF_ORIG_IGN | TF_ORIG_DFL))
410                                         setsig(&sigtraps[tt_sigs[i]],
411                                             (sigtraps[tt_sigs[i]].flags & TF_ORIG_IGN) ?
412                                             SIG_IGN : SIG_DFL,
413                                             SS_RESTORE_ORIG|SS_FORCE);
414                         }
415         }
416         tty_init_state();
417 }
418 #endif
419
420 #if HAVE_NICE
421 /* run nice(3) and ignore the result */
422 static void
423 ksh_nice(int ness)
424 {
425 #if defined(__USE_FORTIFY_LEVEL) && (__USE_FORTIFY_LEVEL > 0)
426         int eno;
427
428         errno = 0;
429         /* this is gonna annoy users; complain to your distro, people! */
430         if (nice(ness) == -1 && (eno = errno) != 0)
431                 warningf(false, Tf_sD_s, "bgnice", cstrerror(eno));
432 #else
433         (void)nice(ness);
434 #endif
435 }
436 #endif
437
438 /* execute tree in child subprocess */
439 int
440 exchild(struct op *t, int flags,
441     volatile int *xerrok,
442     /* used if XPCLOSE or XCCLOSE */
443     int close_fd)
444 {
445         /* for pipelines */
446         static Proc *last_proc;
447
448         int rv = 0, forksleep, jwflags = JW_NONE;
449 #ifndef MKSH_NOPROSPECTOFWORK
450         sigset_t omask;
451 #endif
452         Proc *p;
453         Job *j;
454         pid_t cldpid;
455
456         if (flags & XPIPEST) {
457                 flags &= ~XPIPEST;
458                 jwflags |= JW_PIPEST;
459         }
460
461         if (flags & XEXEC)
462                 /*
463                  * Clear XFORK|XPCLOSE|XCCLOSE|XCOPROC|XPIPEO|XPIPEI|XXCOM|XBGND
464                  * (also done in another execute() below)
465                  */
466                 return (execute(t, flags & (XEXEC | XERROK), xerrok));
467
468 #ifndef MKSH_NOPROSPECTOFWORK
469         /* no SIGCHLDs while messing with job and process lists */
470         sigprocmask(SIG_BLOCK, &sm_sigchld, &omask);
471 #endif
472
473         p = new_proc();
474         p->next = NULL;
475         p->state = PRUNNING;
476         p->status = 0;
477         p->pid = 0;
478
479         /* link process into jobs list */
480         if (flags & XPIPEI) {
481                 /* continuing with a pipe */
482                 if (!last_job)
483                         internal_errorf("exchild: XPIPEI and no last_job - pid %d",
484                             (int)procpid);
485                 j = last_job;
486                 if (last_proc)
487                         last_proc->next = p;
488                 last_proc = p;
489         } else {
490                 /* fills in j->job */
491                 j = new_job();
492                 /*
493                  * we don't consider XXCOMs foreground since they don't get
494                  * tty process group and we don't save or restore tty modes.
495                  */
496                 j->flags = (flags & XXCOM) ? JF_XXCOM :
497                     ((flags & XBGND) ? 0 : (JF_FG|JF_USETTYMODE));
498                 timerclear(&j->usrtime);
499                 timerclear(&j->systime);
500                 j->state = PRUNNING;
501                 j->pgrp = 0;
502                 j->ppid = procpid;
503                 j->age = ++njobs;
504                 j->proc_list = p;
505                 j->coproc_id = 0;
506                 last_job = j;
507                 last_proc = p;
508                 put_job(j, PJ_PAST_STOPPED);
509         }
510
511         vistree(p->command, sizeof(p->command), t);
512
513         /* create child process */
514         forksleep = 1;
515         while ((cldpid = fork()) < 0 && errno == EAGAIN && forksleep < 32) {
516                 if (intrsig)
517                         /* allow user to ^C out... */
518                         break;
519                 sleep(forksleep);
520                 forksleep <<= 1;
521         }
522         /* ensure $RANDOM changes between parent and child */
523         rndset((unsigned long)cldpid);
524         /* fork failed? */
525         if (cldpid < 0) {
526                 kill_job(j, SIGKILL);
527                 remove_job(j, "fork failed");
528 #ifndef MKSH_NOPROSPECTOFWORK
529                 sigprocmask(SIG_SETMASK, &omask, NULL);
530 #endif
531                 errorf("can't fork - try again");
532         }
533         p->pid = cldpid ? cldpid : (procpid = getpid());
534
535 #ifndef MKSH_UNEMPLOYED
536         /* job control set up */
537         if (Flag(FMONITOR) && !(flags&XXCOM)) {
538                 bool dotty = false;
539
540                 if (j->pgrp == 0) {
541                         /* First process */
542                         j->pgrp = p->pid;
543                         dotty = true;
544                 }
545
546                 /*
547                  * set pgrp in both parent and child to deal with race
548                  * condition
549                  */
550                 setpgid(p->pid, j->pgrp);
551                 if (ttypgrp_ok && dotty && !(flags & XBGND))
552                         tcsetpgrp(tty_fd, j->pgrp);
553         }
554 #endif
555
556         /* used to close pipe input fd */
557         if (close_fd >= 0 && (((flags & XPCLOSE) && cldpid) ||
558             ((flags & XCCLOSE) && !cldpid)))
559                 close(close_fd);
560         if (!cldpid) {
561                 /* child */
562
563                 /* Do this before restoring signal */
564                 if (flags & XCOPROC)
565                         coproc_cleanup(false);
566                 cleanup_parents_env();
567 #ifndef MKSH_UNEMPLOYED
568                 /*
569                  * If FMONITOR or FTALKING is set, these signals are ignored,
570                  * if neither FMONITOR nor FTALKING are set, the signals have
571                  * their inherited values.
572                  */
573                 if (Flag(FMONITOR) && !(flags & XXCOM)) {
574                         for (forksleep = NELEM(tt_sigs); --forksleep >= 0; )
575                                 setsig(&sigtraps[tt_sigs[forksleep]], SIG_DFL,
576                                     SS_RESTORE_DFL|SS_FORCE);
577                 }
578 #endif
579 #if HAVE_NICE
580                 if (Flag(FBGNICE) && (flags & XBGND))
581                         ksh_nice(4);
582 #endif
583                 if ((flags & XBGND)
584 #ifndef MKSH_UNEMPLOYED
585                     && !Flag(FMONITOR)
586 #endif
587                     ) {
588                         setsig(&sigtraps[SIGINT], SIG_IGN,
589                             SS_RESTORE_IGN|SS_FORCE);
590                         setsig(&sigtraps[SIGQUIT], SIG_IGN,
591                             SS_RESTORE_IGN|SS_FORCE);
592                         if ((!(flags & (XPIPEI | XCOPROC))) &&
593                             ((forksleep = open("/dev/null", 0)) > 0)) {
594                                 (void)ksh_dup2(forksleep, 0, true);
595                                 close(forksleep);
596                         }
597                 }
598                 /* in case of $(jobs) command */
599                 remove_job(j, "child");
600 #ifndef MKSH_NOPROSPECTOFWORK
601                 /* remove_job needs SIGCHLD blocked still */
602                 sigprocmask(SIG_SETMASK, &omask, NULL);
603 #endif
604                 nzombie = 0;
605 #ifndef MKSH_UNEMPLOYED
606                 ttypgrp_ok = false;
607                 Flag(FMONITOR) = 0;
608 #endif
609                 Flag(FTALKING) = 0;
610                 cleartraps();
611                 /* no return */
612                 execute(t, (flags & XERROK) | XEXEC, NULL);
613 #ifndef MKSH_SMALL
614                 if (t->type == TPIPE)
615                         unwind(LLEAVE);
616                 internal_warningf("%s: execute() returned", "exchild");
617                 fptreef(shl_out, 8, "%s: tried to execute {\n\t%T\n}\n",
618                     "exchild", t);
619                 shf_flush(shl_out);
620 #endif
621                 unwind(LLEAVE);
622                 /* NOTREACHED */
623         }
624
625         /* shell (parent) stuff */
626         if (!(flags & XPIPEO)) {
627                 /* last process in a job */
628                 j_startjob(j);
629                 if (flags & XCOPROC) {
630                         j->coproc_id = coproc.id;
631                         /* n jobs using co-process output */
632                         coproc.njobs++;
633                         /* j using co-process input */
634                         coproc.job = (void *)j;
635                 }
636                 if (flags & XBGND) {
637                         j_set_async(j);
638                         if (Flag(FTALKING)) {
639                                 shf_fprintf(shl_out, "[%d]", j->job);
640                                 for (p = j->proc_list; p; p = p->next)
641                                         shf_fprintf(shl_out, Tf__d,
642                                             (int)p->pid);
643                                 shf_putchar('\n', shl_out);
644                                 shf_flush(shl_out);
645                         }
646                 } else
647                         rv = j_waitj(j, jwflags, "jw:last proc");
648         }
649
650 #ifndef MKSH_NOPROSPECTOFWORK
651         sigprocmask(SIG_SETMASK, &omask, NULL);
652 #endif
653
654         return (rv);
655 }
656
657 /* start the last job: only used for $(command) jobs */
658 void
659 startlast(void)
660 {
661 #ifndef MKSH_NOPROSPECTOFWORK
662         sigset_t omask;
663
664         sigprocmask(SIG_BLOCK, &sm_sigchld, &omask);
665 #endif
666
667         /* no need to report error - waitlast() will do it */
668         if (last_job) {
669                 /* ensure it isn't removed by check_job() */
670                 last_job->flags |= JF_WAITING;
671                 j_startjob(last_job);
672         }
673 #ifndef MKSH_NOPROSPECTOFWORK
674         sigprocmask(SIG_SETMASK, &omask, NULL);
675 #endif
676 }
677
678 /* wait for last job: only used for $(command) jobs */
679 int
680 waitlast(void)
681 {
682         int rv;
683         Job *j;
684 #ifndef MKSH_NOPROSPECTOFWORK
685         sigset_t omask;
686
687         sigprocmask(SIG_BLOCK, &sm_sigchld, &omask);
688 #endif
689
690         j = last_job;
691         if (!j || !(j->flags & JF_STARTED)) {
692                 if (!j)
693                         warningf(true, Tf_sD_s, "waitlast", "no last job");
694                 else
695                         internal_warningf(Tf_sD_s, "waitlast", Tnot_started);
696 #ifndef MKSH_NOPROSPECTOFWORK
697                 sigprocmask(SIG_SETMASK, &omask, NULL);
698 #endif
699                 /* not so arbitrary, non-zero value */
700                 return (125);
701         }
702
703         rv = j_waitj(j, JW_NONE, "waitlast");
704
705 #ifndef MKSH_NOPROSPECTOFWORK
706         sigprocmask(SIG_SETMASK, &omask, NULL);
707 #endif
708
709         return (rv);
710 }
711
712 /* wait for child, interruptable. */
713 int
714 waitfor(const char *cp, int *sigp)
715 {
716         int rv, ecode, flags = JW_INTERRUPT|JW_ASYNCNOTIFY;
717         Job *j;
718 #ifndef MKSH_NOPROSPECTOFWORK
719         sigset_t omask;
720
721         sigprocmask(SIG_BLOCK, &sm_sigchld, &omask);
722 #endif
723
724         *sigp = 0;
725
726         if (cp == NULL) {
727                 /*
728                  * wait for an unspecified job - always returns 0, so
729                  * don't have to worry about exited/signaled jobs
730                  */
731                 for (j = job_list; j; j = j->next)
732                         /* AT&T ksh will wait for stopped jobs - we don't */
733                         if (j->ppid == procpid && j->state == PRUNNING)
734                                 break;
735                 if (!j) {
736 #ifndef MKSH_NOPROSPECTOFWORK
737                         sigprocmask(SIG_SETMASK, &omask, NULL);
738 #endif
739                         return (-1);
740                 }
741         } else if ((j = j_lookup(cp, &ecode))) {
742                 /* don't report normal job completion */
743                 flags &= ~JW_ASYNCNOTIFY;
744                 if (j->ppid != procpid) {
745 #ifndef MKSH_NOPROSPECTOFWORK
746                         sigprocmask(SIG_SETMASK, &omask, NULL);
747 #endif
748                         return (-1);
749                 }
750         } else {
751 #ifndef MKSH_NOPROSPECTOFWORK
752                 sigprocmask(SIG_SETMASK, &omask, NULL);
753 #endif
754                 if (ecode != JL_NOSUCH)
755                         bi_errorf(Tf_sD_s, cp, lookup_msgs[ecode]);
756                 return (-1);
757         }
758
759         /* AT&T ksh will wait for stopped jobs - we don't */
760         rv = j_waitj(j, flags, "jw:waitfor");
761
762 #ifndef MKSH_NOPROSPECTOFWORK
763         sigprocmask(SIG_SETMASK, &omask, NULL);
764 #endif
765
766         if (rv < 0)
767                 /* we were interrupted */
768                 *sigp = ksh_sigmask(-rv);
769
770         return (rv);
771 }
772
773 /* kill (built-in) a job */
774 int
775 j_kill(const char *cp, int sig)
776 {
777         Job *j;
778         int rv = 0, ecode;
779 #ifndef MKSH_NOPROSPECTOFWORK
780         sigset_t omask;
781
782         sigprocmask(SIG_BLOCK, &sm_sigchld, &omask);
783 #endif
784
785         if ((j = j_lookup(cp, &ecode)) == NULL) {
786 #ifndef MKSH_NOPROSPECTOFWORK
787                 sigprocmask(SIG_SETMASK, &omask, NULL);
788 #endif
789                 bi_errorf(Tf_sD_s, cp, lookup_msgs[ecode]);
790                 return (1);
791         }
792
793         if (j->pgrp == 0) {
794                 /* started when !Flag(FMONITOR) */
795                 if (kill_job(j, sig) < 0) {
796                         bi_errorf(Tf_sD_s, cp, cstrerror(errno));
797                         rv = 1;
798                 }
799         } else {
800 #ifndef MKSH_UNEMPLOYED
801                 if (j->state == PSTOPPED && (sig == SIGTERM || sig == SIGHUP))
802                         mksh_killpg(j->pgrp, SIGCONT);
803 #endif
804                 if (mksh_killpg(j->pgrp, sig) < 0) {
805                         bi_errorf(Tf_sD_s, cp, cstrerror(errno));
806                         rv = 1;
807                 }
808         }
809
810 #ifndef MKSH_NOPROSPECTOFWORK
811         sigprocmask(SIG_SETMASK, &omask, NULL);
812 #endif
813
814         return (rv);
815 }
816
817 #ifndef MKSH_UNEMPLOYED
818 /* fg and bg built-ins: called only if Flag(FMONITOR) set */
819 int
820 j_resume(const char *cp, int bg)
821 {
822         Job *j;
823         Proc *p;
824         int ecode, rv = 0;
825         bool running;
826         sigset_t omask;
827
828         sigprocmask(SIG_BLOCK, &sm_sigchld, &omask);
829
830         if ((j = j_lookup(cp, &ecode)) == NULL) {
831                 sigprocmask(SIG_SETMASK, &omask, NULL);
832                 bi_errorf(Tf_sD_s, cp, lookup_msgs[ecode]);
833                 return (1);
834         }
835
836         if (j->pgrp == 0) {
837                 sigprocmask(SIG_SETMASK, &omask, NULL);
838                 bi_errorf("job not job-controlled");
839                 return (1);
840         }
841
842         if (bg)
843                 shprintf("[%d] ", j->job);
844
845         running = false;
846         for (p = j->proc_list; p != NULL; p = p->next) {
847                 if (p->state == PSTOPPED) {
848                         p->state = PRUNNING;
849                         p->status = 0;
850                         running = true;
851                 }
852                 shf_puts(p->command, shl_stdout);
853                 if (p->next)
854                         shf_puts("| ", shl_stdout);
855         }
856         shf_putc('\n', shl_stdout);
857         shf_flush(shl_stdout);
858         if (running)
859                 j->state = PRUNNING;
860
861         put_job(j, PJ_PAST_STOPPED);
862         if (bg)
863                 j_set_async(j);
864         else {
865                 /* attach tty to job */
866                 if (j->state == PRUNNING) {
867                         if (ttypgrp_ok && (j->flags & JF_SAVEDTTY))
868                                 mksh_tcset(tty_fd, &j->ttystat);
869                         /* See comment in j_waitj regarding saved_ttypgrp. */
870                         if (ttypgrp_ok &&
871                             tcsetpgrp(tty_fd, (j->flags & JF_SAVEDTTYPGRP) ?
872                             j->saved_ttypgrp : j->pgrp) < 0) {
873                                 rv = errno;
874                                 if (j->flags & JF_SAVEDTTY)
875                                         mksh_tcset(tty_fd, &tty_state);
876                                 sigprocmask(SIG_SETMASK, &omask, NULL);
877                                 bi_errorf(Tf_ldfailed,
878                                     "fg: 1st", "tcsetpgrp", tty_fd,
879                                     (long)((j->flags & JF_SAVEDTTYPGRP) ?
880                                     j->saved_ttypgrp : j->pgrp),
881                                     cstrerror(rv));
882                                 return (1);
883                         }
884                 }
885                 j->flags |= JF_FG;
886                 j->flags &= ~JF_KNOWN;
887                 if (j == async_job)
888                         async_job = NULL;
889         }
890
891         if (j->state == PRUNNING && mksh_killpg(j->pgrp, SIGCONT) < 0) {
892                 int eno = errno;
893
894                 if (!bg) {
895                         j->flags &= ~JF_FG;
896                         if (ttypgrp_ok && (j->flags & JF_SAVEDTTY))
897                                 mksh_tcset(tty_fd, &tty_state);
898                         if (ttypgrp_ok && tcsetpgrp(tty_fd, kshpgrp) < 0)
899                                 warningf(true, Tf_ldfailed,
900                                     "fg: 2nd", "tcsetpgrp", tty_fd,
901                                     (long)kshpgrp, cstrerror(errno));
902                 }
903                 sigprocmask(SIG_SETMASK, &omask, NULL);
904                 bi_errorf(Tf_s_sD_s, "can't continue job",
905                     cp, cstrerror(eno));
906                 return (1);
907         }
908         if (!bg) {
909                 if (ttypgrp_ok) {
910                         j->flags &= ~(JF_SAVEDTTY | JF_SAVEDTTYPGRP);
911                 }
912                 rv = j_waitj(j, JW_NONE, "jw:resume");
913         }
914         sigprocmask(SIG_SETMASK, &omask, NULL);
915         return (rv);
916 }
917 #endif
918
919 /* are there any running or stopped jobs ? */
920 int
921 j_stopped_running(void)
922 {
923         Job *j;
924         int which = 0;
925
926         for (j = job_list; j != NULL; j = j->next) {
927 #ifndef MKSH_UNEMPLOYED
928                 if (j->ppid == procpid && j->state == PSTOPPED)
929                         which |= 1;
930 #endif
931                 if (Flag(FLOGIN) && !Flag(FNOHUP) && procpid == kshpid &&
932                     j->ppid == procpid && j->state == PRUNNING)
933                         which |= 2;
934         }
935         if (which) {
936                 shellf("You have %s%s%s jobs\n",
937                     which & 1 ? "stopped" : "",
938                     which == 3 ? " and " : "",
939                     which & 2 ? "running" : "");
940                 return (1);
941         }
942
943         return (0);
944 }
945
946
947 /* list jobs for jobs built-in */
948 int
949 j_jobs(const char *cp, int slp,
950     /* 0: short, 1: long, 2: pgrp */
951     int nflag)
952 {
953         Job *j, *tmp;
954         int how, zflag = 0;
955 #ifndef MKSH_NOPROSPECTOFWORK
956         sigset_t omask;
957
958         sigprocmask(SIG_BLOCK, &sm_sigchld, &omask);
959 #endif
960
961         if (nflag < 0) {
962                 /* kludge: print zombies */
963                 nflag = 0;
964                 zflag = 1;
965         }
966         if (cp) {
967                 int ecode;
968
969                 if ((j = j_lookup(cp, &ecode)) == NULL) {
970 #ifndef MKSH_NOPROSPECTOFWORK
971                         sigprocmask(SIG_SETMASK, &omask, NULL);
972 #endif
973                         bi_errorf(Tf_sD_s, cp, lookup_msgs[ecode]);
974                         return (1);
975                 }
976         } else
977                 j = job_list;
978         how = slp == 0 ? JP_MEDIUM : (slp == 1 ? JP_LONG : JP_PGRP);
979         for (; j; j = j->next) {
980                 if ((!(j->flags & JF_ZOMBIE) || zflag) &&
981                     (!nflag || (j->flags & JF_CHANGED))) {
982                         j_print(j, how, shl_stdout);
983                         if (j->state == PEXITED || j->state == PSIGNALLED)
984                                 j->flags |= JF_REMOVE;
985                 }
986                 if (cp)
987                         break;
988         }
989         /* Remove jobs after printing so there won't be multiple + or - jobs */
990         for (j = job_list; j; j = tmp) {
991                 tmp = j->next;
992                 if (j->flags & JF_REMOVE)
993                         remove_job(j, Tjobs);
994         }
995 #ifndef MKSH_NOPROSPECTOFWORK
996         sigprocmask(SIG_SETMASK, &omask, NULL);
997 #endif
998         return (0);
999 }
1000
1001 /* list jobs for top-level notification */
1002 void
1003 j_notify(void)
1004 {
1005         Job *j, *tmp;
1006 #ifndef MKSH_NOPROSPECTOFWORK
1007         sigset_t omask;
1008
1009         sigprocmask(SIG_BLOCK, &sm_sigchld, &omask);
1010 #endif
1011         for (j = job_list; j; j = j->next) {
1012 #ifndef MKSH_UNEMPLOYED
1013                 if (Flag(FMONITOR) && (j->flags & JF_CHANGED))
1014                         j_print(j, JP_MEDIUM, shl_out);
1015 #endif
1016                 /*
1017                  * Remove job after doing reports so there aren't
1018                  * multiple +/- jobs.
1019                  */
1020                 if (j->state == PEXITED || j->state == PSIGNALLED)
1021                         j->flags |= JF_REMOVE;
1022         }
1023         for (j = job_list; j; j = tmp) {
1024                 tmp = j->next;
1025                 if (j->flags & JF_REMOVE) {
1026                         if (j == async_job || (j->flags & JF_KNOWN)) {
1027                                 j->flags = (j->flags & ~JF_REMOVE) | JF_ZOMBIE;
1028                                 j->job = -1;
1029                                 nzombie++;
1030                         } else
1031                                 remove_job(j, "notify");
1032                 }
1033         }
1034         shf_flush(shl_out);
1035 #ifndef MKSH_NOPROSPECTOFWORK
1036         sigprocmask(SIG_SETMASK, &omask, NULL);
1037 #endif
1038 }
1039
1040 /* Return pid of last process in last asynchronous job */
1041 pid_t
1042 j_async(void)
1043 {
1044 #ifndef MKSH_NOPROSPECTOFWORK
1045         sigset_t omask;
1046
1047         sigprocmask(SIG_BLOCK, &sm_sigchld, &omask);
1048 #endif
1049
1050         if (async_job)
1051                 async_job->flags |= JF_KNOWN;
1052
1053 #ifndef MKSH_NOPROSPECTOFWORK
1054         sigprocmask(SIG_SETMASK, &omask, NULL);
1055 #endif
1056
1057         return (async_pid);
1058 }
1059
1060 /*
1061  * Make j the last async process
1062  *
1063  * If jobs are compiled in then this routine expects sigchld to be blocked.
1064  */
1065 static void
1066 j_set_async(Job *j)
1067 {
1068         Job *jl, *oldest;
1069
1070         if (async_job && (async_job->flags & (JF_KNOWN|JF_ZOMBIE)) == JF_ZOMBIE)
1071                 remove_job(async_job, "async");
1072         if (!(j->flags & JF_STARTED)) {
1073                 internal_warningf(Tf_sD_s, "j_async", Tjob_not_started);
1074                 return;
1075         }
1076         async_job = j;
1077         async_pid = j->last_proc->pid;
1078         while (nzombie > CHILD_MAX) {
1079                 oldest = NULL;
1080                 for (jl = job_list; jl; jl = jl->next)
1081                         if (jl != async_job && (jl->flags & JF_ZOMBIE) &&
1082                             (!oldest || jl->age < oldest->age))
1083                                 oldest = jl;
1084                 if (!oldest) {
1085                         /* XXX debugging */
1086                         if (!(async_job->flags & JF_ZOMBIE) || nzombie != 1) {
1087                                 internal_warningf("%s: bad nzombie (%d)",
1088                                     "j_async", nzombie);
1089                                 nzombie = 0;
1090                         }
1091                         break;
1092                 }
1093                 remove_job(oldest, "zombie");
1094         }
1095 }
1096
1097 /*
1098  * Start a job: set STARTED, check for held signals and set j->last_proc
1099  *
1100  * If jobs are compiled in then this routine expects sigchld to be blocked.
1101  */
1102 static void
1103 j_startjob(Job *j)
1104 {
1105         Proc *p;
1106
1107         j->flags |= JF_STARTED;
1108         for (p = j->proc_list; p->next; p = p->next)
1109                 ;
1110         j->last_proc = p;
1111
1112 #ifndef MKSH_NOPROSPECTOFWORK
1113         if (held_sigchld) {
1114                 held_sigchld = 0;
1115                 /* Don't call j_sigchld() as it may remove job... */
1116                 kill(procpid, SIGCHLD);
1117         }
1118 #endif
1119 }
1120
1121 /*
1122  * wait for job to complete or change state
1123  *
1124  * If jobs are compiled in then this routine expects sigchld to be blocked.
1125  */
1126 static int
1127 j_waitj(Job *j,
1128     /* see JW_* */
1129     int flags,
1130     const char *where)
1131 {
1132         Proc *p;
1133         int rv;
1134 #ifdef MKSH_NO_SIGSUSPEND
1135         sigset_t omask;
1136 #endif
1137
1138         /*
1139          * No auto-notify on the job we are waiting on.
1140          */
1141         j->flags |= JF_WAITING;
1142         if (flags & JW_ASYNCNOTIFY)
1143                 j->flags |= JF_W_ASYNCNOTIFY;
1144
1145 #ifndef MKSH_UNEMPLOYED
1146         if (!Flag(FMONITOR))
1147 #endif
1148                 flags |= JW_STOPPEDWAIT;
1149
1150         while (j->state == PRUNNING ||
1151             ((flags & JW_STOPPEDWAIT) && j->state == PSTOPPED)) {
1152 #ifndef MKSH_NOPROSPECTOFWORK
1153 #ifdef MKSH_NO_SIGSUSPEND
1154                 sigprocmask(SIG_SETMASK, &sm_default, &omask);
1155                 pause();
1156                 /* note that handlers may run here so they need to know */
1157                 sigprocmask(SIG_SETMASK, &omask, NULL);
1158 #else
1159                 sigsuspend(&sm_default);
1160 #endif
1161 #else
1162                 j_sigchld(SIGCHLD);
1163 #endif
1164                 if (fatal_trap) {
1165                         int oldf = j->flags & (JF_WAITING|JF_W_ASYNCNOTIFY);
1166                         j->flags &= ~(JF_WAITING|JF_W_ASYNCNOTIFY);
1167                         runtraps(TF_FATAL);
1168                         /* not reached... */
1169                         j->flags |= oldf;
1170                 }
1171                 if ((flags & JW_INTERRUPT) && (rv = trap_pending())) {
1172                         j->flags &= ~(JF_WAITING|JF_W_ASYNCNOTIFY);
1173                         return (-rv);
1174                 }
1175         }
1176         j->flags &= ~(JF_WAITING|JF_W_ASYNCNOTIFY);
1177
1178         if (j->flags & JF_FG) {
1179                 j->flags &= ~JF_FG;
1180 #ifndef MKSH_UNEMPLOYED
1181                 if (Flag(FMONITOR) && ttypgrp_ok && j->pgrp) {
1182                         /*
1183                          * Save the tty's current pgrp so it can be restored
1184                          * when the job is foregrounded. This is to
1185                          * deal with things like the GNU su which does
1186                          * a fork/exec instead of an exec (the fork means
1187                          * the execed shell gets a different pid from its
1188                          * pgrp, so naturally it sets its pgrp and gets hosed
1189                          * when it gets foregrounded by the parent shell which
1190                          * has restored the tty's pgrp to that of the su
1191                          * process).
1192                          */
1193                         if (j->state == PSTOPPED &&
1194                             (j->saved_ttypgrp = tcgetpgrp(tty_fd)) >= 0)
1195                                 j->flags |= JF_SAVEDTTYPGRP;
1196                         if (tcsetpgrp(tty_fd, kshpgrp) < 0)
1197                                 warningf(true, Tf_ldfailed,
1198                                     "j_waitj:", "tcsetpgrp", tty_fd,
1199                                     (long)kshpgrp, cstrerror(errno));
1200                         if (j->state == PSTOPPED) {
1201                                 j->flags |= JF_SAVEDTTY;
1202                                 mksh_tcget(tty_fd, &j->ttystat);
1203                         }
1204                 }
1205 #endif
1206                 if (tty_hasstate) {
1207                         /*
1208                          * Only restore tty settings if job was originally
1209                          * started in the foreground. Problems can be
1210                          * caused by things like 'more foobar &' which will
1211                          * typically get and save the shell's vi/emacs tty
1212                          * settings before setting up the tty for itself;
1213                          * when more exits, it restores the 'original'
1214                          * settings, and things go down hill from there...
1215                          */
1216                         if (j->state == PEXITED && j->status == 0 &&
1217                             (j->flags & JF_USETTYMODE)) {
1218                                 mksh_tcget(tty_fd, &tty_state);
1219                         } else {
1220                                 mksh_tcset(tty_fd, &tty_state);
1221                                 /*-
1222                                  * Don't use tty mode if job is stopped and
1223                                  * later restarted and exits. Consider
1224                                  * the sequence:
1225                                  *      vi foo (stopped)
1226                                  *      ...
1227                                  *      stty something
1228                                  *      ...
1229                                  *      fg (vi; ZZ)
1230                                  * mode should be that of the stty, not what
1231                                  * was before the vi started.
1232                                  */
1233                                 if (j->state == PSTOPPED)
1234                                         j->flags &= ~JF_USETTYMODE;
1235                         }
1236                 }
1237 #ifndef MKSH_UNEMPLOYED
1238                 /*
1239                  * If it looks like user hit ^C to kill a job, pretend we got
1240                  * one too to break out of for loops, etc. (AT&T ksh does this
1241                  * even when not monitoring, but this doesn't make sense since
1242                  * a tty generated ^C goes to the whole process group)
1243                  */
1244                 if (Flag(FMONITOR) && j->state == PSIGNALLED &&
1245                     WIFSIGNALED(j->last_proc->status)) {
1246                         int termsig;
1247
1248                         if ((termsig = WTERMSIG(j->last_proc->status)) > 0 &&
1249                             termsig < ksh_NSIG &&
1250                             (sigtraps[termsig].flags & TF_TTY_INTR))
1251                                 trapsig(termsig);
1252                 }
1253 #endif
1254         }
1255
1256         j_usrtime = j->usrtime;
1257         j_systime = j->systime;
1258         rv = j->status;
1259
1260         if (!(p = j->proc_list)) {
1261                 ;       /* nothing */
1262         } else if (flags & JW_PIPEST) {
1263                 uint32_t num = 0;
1264                 struct tbl *vp;
1265
1266                 unset(vp_pipest, 1);
1267                 vp = vp_pipest;
1268                 vp->flag = DEFINED | ISSET | INTEGER | RDONLY | ARRAY | INT_U;
1269                 goto got_array;
1270
1271                 while (p != NULL) {
1272                         {
1273                                 struct tbl *vq;
1274
1275                                 /* strlen(vp_pipest->name) == 10 */
1276                                 vq = alloc(offsetof(struct tbl, name[0]) + 11,
1277                                     vp_pipest->areap);
1278                                 memset(vq, 0, offsetof(struct tbl, name[0]));
1279                                 memcpy(vq->name, vp_pipest->name, 11);
1280                                 vp->u.array = vq;
1281                                 vp = vq;
1282                         }
1283                         vp->areap = vp_pipest->areap;
1284                         vp->ua.index = ++num;
1285                         vp->flag = DEFINED | ISSET | INTEGER | RDONLY |
1286                             ARRAY | INT_U | AINDEX;
1287  got_array:
1288                         vp->val.i = proc_errorlevel(p);
1289                         if (Flag(FPIPEFAIL) && vp->val.i)
1290                                 rv = vp->val.i;
1291                         p = p->next;
1292                 }
1293         } else if (Flag(FPIPEFAIL)) {
1294                 do {
1295                         const int i = proc_errorlevel(p);
1296
1297                         if (i)
1298                                 rv = i;
1299                 } while ((p = p->next));
1300         }
1301
1302         if (!(flags & JW_ASYNCNOTIFY)
1303 #ifndef MKSH_UNEMPLOYED
1304             && (!Flag(FMONITOR) || j->state != PSTOPPED)
1305 #endif
1306             ) {
1307                 j_print(j, JP_SHORT, shl_out);
1308                 shf_flush(shl_out);
1309         }
1310         if (j->state != PSTOPPED
1311 #ifndef MKSH_UNEMPLOYED
1312             && (!Flag(FMONITOR) || !(flags & JW_ASYNCNOTIFY))
1313 #endif
1314             )
1315                 remove_job(j, where);
1316
1317         return (rv);
1318 }
1319
1320 /*
1321  * SIGCHLD handler to reap children and update job states
1322  *
1323  * If jobs are compiled in then this routine expects sigchld to be blocked.
1324  */
1325 /* ARGSUSED */
1326 static void
1327 j_sigchld(int sig MKSH_A_UNUSED)
1328 {
1329         int saved_errno = errno;
1330         Job *j;
1331         Proc *p = NULL;
1332         pid_t pid;
1333         int status;
1334         struct rusage ru0, ru1;
1335 #ifdef MKSH_NO_SIGSUSPEND
1336         sigset_t omask;
1337
1338         /* this handler can run while SIGCHLD is not blocked, so block it now */
1339         sigprocmask(SIG_BLOCK, &sm_sigchld, &omask);
1340 #endif
1341
1342 #ifndef MKSH_NOPROSPECTOFWORK
1343         /*
1344          * Don't wait for any processes if a job is partially started.
1345          * This is so we don't do away with the process group leader
1346          * before all the processes in a pipe line are started (so the
1347          * setpgid() won't fail)
1348          */
1349         for (j = job_list; j; j = j->next)
1350                 if (j->ppid == procpid && !(j->flags & JF_STARTED)) {
1351                         held_sigchld = 1;
1352                         goto j_sigchld_out;
1353                 }
1354 #endif
1355
1356         getrusage(RUSAGE_CHILDREN, &ru0);
1357         do {
1358 #ifndef MKSH_NOPROSPECTOFWORK
1359                 pid = waitpid(-1, &status, (WNOHANG |
1360 #if defined(WCONTINUED) && defined(WIFCONTINUED)
1361                     WCONTINUED |
1362 #endif
1363                     WUNTRACED));
1364 #else
1365                 pid = wait(&status);
1366 #endif
1367
1368                 /*
1369                  * return if this would block (0) or no children
1370                  * or interrupted (-1)
1371                  */
1372                 if (pid <= 0)
1373                         goto j_sigchld_out;
1374
1375                 getrusage(RUSAGE_CHILDREN, &ru1);
1376
1377                 /* find job and process structures for this pid */
1378                 for (j = job_list; j != NULL; j = j->next)
1379                         for (p = j->proc_list; p != NULL; p = p->next)
1380                                 if (p->pid == pid)
1381                                         goto found;
1382  found:
1383                 if (j == NULL) {
1384                         /* Can occur if process has kids, then execs shell
1385                         warningf(true, "bad process waited for (pid = %d)",
1386                                 pid);
1387                          */
1388                         ru0 = ru1;
1389                         continue;
1390                 }
1391
1392                 timeradd(&j->usrtime, &ru1.ru_utime, &j->usrtime);
1393                 timersub(&j->usrtime, &ru0.ru_utime, &j->usrtime);
1394                 timeradd(&j->systime, &ru1.ru_stime, &j->systime);
1395                 timersub(&j->systime, &ru0.ru_stime, &j->systime);
1396                 ru0 = ru1;
1397                 p->status = status;
1398 #ifndef MKSH_UNEMPLOYED
1399                 if (WIFSTOPPED(status))
1400                         p->state = PSTOPPED;
1401                 else
1402 #if defined(WCONTINUED) && defined(WIFCONTINUED)
1403                   if (WIFCONTINUED(status)) {
1404                         p->state = j->state = PRUNNING;
1405                         /* skip check_job(), no-op in this case */
1406                         continue;
1407                 } else
1408 #endif
1409 #endif
1410                   if (WIFSIGNALED(status))
1411                         p->state = PSIGNALLED;
1412                 else
1413                         p->state = PEXITED;
1414
1415                 /* check to see if entire job is done */
1416                 check_job(j);
1417         }
1418 #ifndef MKSH_NOPROSPECTOFWORK
1419             while (/* CONSTCOND */ 1);
1420 #else
1421             while (/* CONSTCOND */ 0);
1422 #endif
1423
1424  j_sigchld_out:
1425 #ifdef MKSH_NO_SIGSUSPEND
1426         sigprocmask(SIG_SETMASK, &omask, NULL);
1427 #endif
1428         errno = saved_errno;
1429 }
1430
1431 /*
1432  * Called only when a process in j has exited/stopped (ie, called only
1433  * from j_sigchld()). If no processes are running, the job status
1434  * and state are updated, asynchronous job notification is done and,
1435  * if unneeded, the job is removed.
1436  *
1437  * If jobs are compiled in then this routine expects sigchld to be blocked.
1438  */
1439 static void
1440 check_job(Job *j)
1441 {
1442         int jstate;
1443         Proc *p;
1444
1445         /* XXX debugging (nasty - interrupt routine using shl_out) */
1446         if (!(j->flags & JF_STARTED)) {
1447                 internal_warningf("check_job: job started (flags 0x%X)",
1448                     (unsigned int)j->flags);
1449                 return;
1450         }
1451
1452         jstate = PRUNNING;
1453         for (p=j->proc_list; p != NULL; p = p->next) {
1454                 if (p->state == PRUNNING)
1455                         /* some processes still running */
1456                         return;
1457                 if (p->state > jstate)
1458                         jstate = p->state;
1459         }
1460         j->state = jstate;
1461         j->status = proc_errorlevel(j->last_proc);
1462
1463         /*
1464          * Note when co-process dies: can't be done in j_wait() nor
1465          * remove_job() since neither may be called for non-interactive
1466          * shells.
1467          */
1468         if (j->state == PEXITED || j->state == PSIGNALLED) {
1469                 /*
1470                  * No need to keep co-process input any more
1471                  * (at least, this is what ksh93d thinks)
1472                  */
1473                 if (coproc.job == j) {
1474                         coproc.job = NULL;
1475                         /*
1476                          * XXX would be nice to get the closes out of here
1477                          * so they aren't done in the signal handler.
1478                          * Would mean a check in coproc_getfd() to
1479                          * do "if job == 0 && write >= 0, close write".
1480                          */
1481                         coproc_write_close(coproc.write);
1482                 }
1483                 /* Do we need to keep the output? */
1484                 if (j->coproc_id && j->coproc_id == coproc.id &&
1485                     --coproc.njobs == 0)
1486                         coproc_readw_close(coproc.read);
1487         }
1488
1489         j->flags |= JF_CHANGED;
1490 #ifndef MKSH_UNEMPLOYED
1491         if (Flag(FMONITOR) && !(j->flags & JF_XXCOM)) {
1492                 /*
1493                  * Only put stopped jobs at the front to avoid confusing
1494                  * the user (don't want finished jobs effecting %+ or %-)
1495                  */
1496                 if (j->state == PSTOPPED)
1497                         put_job(j, PJ_ON_FRONT);
1498                 if (Flag(FNOTIFY) &&
1499                     (j->flags & (JF_WAITING|JF_W_ASYNCNOTIFY)) != JF_WAITING) {
1500                         /* Look for the real file descriptor 2 */
1501                         {
1502                                 struct env *ep;
1503                                 int fd = 2;
1504
1505                                 for (ep = e; ep; ep = ep->oenv)
1506                                         if (ep->savefd && ep->savefd[2])
1507                                                 fd = ep->savefd[2];
1508                                 shf_reopen(fd, SHF_WR, shl_j);
1509                         }
1510                         /*
1511                          * Can't call j_notify() as it removes jobs. The job
1512                          * must stay in the job list as j_waitj() may be
1513                          * running with this job.
1514                          */
1515                         j_print(j, JP_MEDIUM, shl_j);
1516                         shf_flush(shl_j);
1517                         if (!(j->flags & JF_WAITING) && j->state != PSTOPPED)
1518                                 remove_job(j, "notify");
1519                 }
1520         }
1521 #endif
1522         if (
1523 #ifndef MKSH_UNEMPLOYED
1524             !Flag(FMONITOR) &&
1525 #endif
1526             !(j->flags & (JF_WAITING|JF_FG)) &&
1527             j->state != PSTOPPED) {
1528                 if (j == async_job || (j->flags & JF_KNOWN)) {
1529                         j->flags |= JF_ZOMBIE;
1530                         j->job = -1;
1531                         nzombie++;
1532                 } else
1533                         remove_job(j, "checkjob");
1534         }
1535 }
1536
1537 /*
1538  * Print job status in either short, medium or long format.
1539  *
1540  * If jobs are compiled in then this routine expects sigchld to be blocked.
1541  */
1542 static void
1543 j_print(Job *j, int how, struct shf *shf)
1544 {
1545         Proc *p;
1546         int state;
1547         int status;
1548 #ifdef WCOREDUMP
1549         bool coredumped;
1550 #endif
1551         char jobchar = ' ';
1552         char buf[64];
1553         const char *filler;
1554         int output = 0;
1555
1556         if (how == JP_PGRP) {
1557                 /*
1558                  * POSIX doesn't say what to do it there is no process
1559                  * group leader (ie, !FMONITOR). We arbitrarily return
1560                  * last pid (which is what $! returns).
1561                  */
1562                 shf_fprintf(shf, Tf_dN, (int)(j->pgrp ? j->pgrp :
1563                     (j->last_proc ? j->last_proc->pid : 0)));
1564                 return;
1565         }
1566         j->flags &= ~JF_CHANGED;
1567         filler = j->job > 10 ? "\n       " : "\n      ";
1568         if (j == job_list)
1569                 jobchar = '+';
1570         else if (j == job_list->next)
1571                 jobchar = '-';
1572
1573         for (p = j->proc_list; p != NULL;) {
1574 #ifdef WCOREDUMP
1575                 coredumped = false;
1576 #endif
1577                 switch (p->state) {
1578                 case PRUNNING:
1579                         memcpy(buf, "Running", 8);
1580                         break;
1581                 case PSTOPPED: {
1582                         int stopsig = WSTOPSIG(p->status);
1583
1584                         strlcpy(buf, stopsig > 0 && stopsig < ksh_NSIG ?
1585                             sigtraps[stopsig].mess : "Stopped", sizeof(buf));
1586                         break;
1587                 }
1588                 case PEXITED: {
1589                         int exitstatus = (WEXITSTATUS(p->status)) & 255;
1590
1591                         if (how == JP_SHORT)
1592                                 buf[0] = '\0';
1593                         else if (exitstatus == 0)
1594                                 memcpy(buf, "Done", 5);
1595                         else
1596                                 shf_snprintf(buf, sizeof(buf), "Done (%d)",
1597                                     exitstatus);
1598                         break;
1599                 }
1600                 case PSIGNALLED: {
1601                         int termsig = WTERMSIG(p->status);
1602 #ifdef WCOREDUMP
1603                         if (WCOREDUMP(p->status))
1604                                 coredumped = true;
1605 #endif
1606                         /*
1607                          * kludge for not reporting 'normal termination
1608                          * signals' (i.e. SIGINT, SIGPIPE)
1609                          */
1610                         if (how == JP_SHORT &&
1611 #ifdef WCOREDUMP
1612                             !coredumped &&
1613 #endif
1614                             (termsig == SIGINT || termsig == SIGPIPE)) {
1615                                 buf[0] = '\0';
1616                         } else
1617                                 strlcpy(buf, termsig > 0 && termsig < ksh_NSIG ?
1618                                     sigtraps[termsig].mess : "Signalled",
1619                                     sizeof(buf));
1620                         break;
1621                 }
1622                 default:
1623                         buf[0] = '\0';
1624                 }
1625
1626                 if (how != JP_SHORT) {
1627                         if (p == j->proc_list)
1628                                 shf_fprintf(shf, "[%d] %c ", j->job, jobchar);
1629                         else
1630                                 shf_puts(filler, shf);
1631                 }
1632
1633                 if (how == JP_LONG)
1634                         shf_fprintf(shf, "%5d ", (int)p->pid);
1635
1636                 if (how == JP_SHORT) {
1637                         if (buf[0]) {
1638                                 output = 1;
1639 #ifdef WCOREDUMP
1640                                 shf_fprintf(shf, "%s%s ",
1641                                     buf, coredumped ? " (core dumped)" : null);
1642 #else
1643                                 shf_puts(buf, shf);
1644                                 shf_putchar(' ', shf);
1645 #endif
1646                         }
1647                 } else {
1648                         output = 1;
1649                         shf_fprintf(shf, "%-20s %s%s%s", buf, p->command,
1650                             p->next ? "|" : null,
1651 #ifdef WCOREDUMP
1652                             coredumped ? " (core dumped)" :
1653 #endif
1654                              null);
1655                 }
1656
1657                 state = p->state;
1658                 status = p->status;
1659                 p = p->next;
1660                 while (p && p->state == state && p->status == status) {
1661                         if (how == JP_LONG)
1662                                 shf_fprintf(shf, "%s%5d %-20s %s%s", filler,
1663                                     (int)p->pid, T1space, p->command,
1664                                     p->next ? "|" : null);
1665                         else if (how == JP_MEDIUM)
1666                                 shf_fprintf(shf, Tf__ss, p->command,
1667                                     p->next ? "|" : null);
1668                         p = p->next;
1669                 }
1670         }
1671         if (output)
1672                 shf_putc('\n', shf);
1673 }
1674
1675 /*
1676  * Convert % sequence to job
1677  *
1678  * If jobs are compiled in then this routine expects sigchld to be blocked.
1679  */
1680 static Job *
1681 j_lookup(const char *cp, int *ecodep)
1682 {
1683         Job *j, *last_match;
1684         Proc *p;
1685         size_t len;
1686         int job = 0;
1687
1688         if (ctype(*cp, C_DIGIT) && getn(cp, &job)) {
1689                 /* Look for last_proc->pid (what $! returns) first... */
1690                 for (j = job_list; j != NULL; j = j->next)
1691                         if (j->last_proc && j->last_proc->pid == job)
1692                                 return (j);
1693                 /*
1694                  * ...then look for process group (this is non-POSIX,
1695                  * but should not break anything
1696                  */
1697                 for (j = job_list; j != NULL; j = j->next)
1698                         if (j->pgrp && j->pgrp == job)
1699                                 return (j);
1700                 goto j_lookup_nosuch;
1701         }
1702         if (*cp != '%') {
1703  j_lookup_invalid:
1704                 if (ecodep)
1705                         *ecodep = JL_INVALID;
1706                 return (NULL);
1707         }
1708         switch (*++cp) {
1709         case '\0': /* non-standard */
1710         case '+':
1711         case '%':
1712                 if (job_list != NULL)
1713                         return (job_list);
1714                 break;
1715
1716         case '-':
1717                 if (job_list != NULL && job_list->next)
1718                         return (job_list->next);
1719                 break;
1720
1721         case '0': case '1': case '2': case '3': case '4':
1722         case '5': case '6': case '7': case '8': case '9':
1723                 if (!getn(cp, &job))
1724                         goto j_lookup_invalid;
1725                 for (j = job_list; j != NULL; j = j->next)
1726                         if (j->job == job)
1727                                 return (j);
1728                 break;
1729
1730         /* %?string */
1731         case '?':
1732                 last_match = NULL;
1733                 for (j = job_list; j != NULL; j = j->next)
1734                         for (p = j->proc_list; p != NULL; p = p->next)
1735                                 if (strstr(p->command, cp+1) != NULL) {
1736                                         if (last_match) {
1737                                                 if (ecodep)
1738                                                         *ecodep = JL_AMBIG;
1739                                                 return (NULL);
1740                                         }
1741                                         last_match = j;
1742                                 }
1743                 if (last_match)
1744                         return (last_match);
1745                 break;
1746
1747         /* %string */
1748         default:
1749                 len = strlen(cp);
1750                 last_match = NULL;
1751                 for (j = job_list; j != NULL; j = j->next)
1752                         if (strncmp(cp, j->proc_list->command, len) == 0) {
1753                                 if (last_match) {
1754                                         if (ecodep)
1755                                                 *ecodep = JL_AMBIG;
1756                                         return (NULL);
1757                                 }
1758                                 last_match = j;
1759                         }
1760                 if (last_match)
1761                         return (last_match);
1762                 break;
1763         }
1764  j_lookup_nosuch:
1765         if (ecodep)
1766                 *ecodep = JL_NOSUCH;
1767         return (NULL);
1768 }
1769
1770 static Job      *free_jobs;
1771 static Proc     *free_procs;
1772
1773 /*
1774  * allocate a new job and fill in the job number.
1775  *
1776  * If jobs are compiled in then this routine expects sigchld to be blocked.
1777  */
1778 static Job *
1779 new_job(void)
1780 {
1781         int i;
1782         Job *newj, *j;
1783
1784         if (free_jobs != NULL) {
1785                 newj = free_jobs;
1786                 free_jobs = free_jobs->next;
1787         } else
1788                 newj = alloc(sizeof(Job), APERM);
1789
1790         /* brute force method */
1791         for (i = 1; ; i++) {
1792                 for (j = job_list; j && j->job != i; j = j->next)
1793                         ;
1794                 if (j == NULL)
1795                         break;
1796         }
1797         newj->job = i;
1798
1799         return (newj);
1800 }
1801
1802 /*
1803  * Allocate new process struct
1804  *
1805  * If jobs are compiled in then this routine expects sigchld to be blocked.
1806  */
1807 static Proc *
1808 new_proc(void)
1809 {
1810         Proc *p;
1811
1812         if (free_procs != NULL) {
1813                 p = free_procs;
1814                 free_procs = free_procs->next;
1815         } else
1816                 p = alloc(sizeof(Proc), APERM);
1817
1818         return (p);
1819 }
1820
1821 /*
1822  * Take job out of job_list and put old structures into free list.
1823  * Keeps nzombies, last_job and async_job up to date.
1824  *
1825  * If jobs are compiled in then this routine expects sigchld to be blocked.
1826  */
1827 static void
1828 remove_job(Job *j, const char *where)
1829 {
1830         Proc *p, *tmp;
1831         Job **prev, *curr;
1832
1833         prev = &job_list;
1834         curr = job_list;
1835         while (curr && curr != j) {
1836                 prev = &curr->next;
1837                 curr = *prev;
1838         }
1839         if (curr != j) {
1840                 internal_warningf("remove_job: job %s (%s)", Tnot_found, where);
1841                 return;
1842         }
1843         *prev = curr->next;
1844
1845         /* free up proc structures */
1846         for (p = j->proc_list; p != NULL; ) {
1847                 tmp = p;
1848                 p = p->next;
1849                 tmp->next = free_procs;
1850                 free_procs = tmp;
1851         }
1852
1853         if ((j->flags & JF_ZOMBIE) && j->ppid == procpid)
1854                 --nzombie;
1855         j->next = free_jobs;
1856         free_jobs = j;
1857
1858         if (j == last_job)
1859                 last_job = NULL;
1860         if (j == async_job)
1861                 async_job = NULL;
1862 }
1863
1864 /*
1865  * put j in a particular location (taking it out job_list if it is there
1866  * already)
1867  *
1868  * If jobs are compiled in then this routine expects sigchld to be blocked.
1869  */
1870 static void
1871 put_job(Job *j, int where)
1872 {
1873         Job **prev, *curr;
1874
1875         /* Remove job from list (if there) */
1876         prev = &job_list;
1877         curr = job_list;
1878         while (curr && curr != j) {
1879                 prev = &curr->next;
1880                 curr = *prev;
1881         }
1882         if (curr == j)
1883                 *prev = curr->next;
1884
1885         switch (where) {
1886         case PJ_ON_FRONT:
1887                 j->next = job_list;
1888                 job_list = j;
1889                 break;
1890
1891         case PJ_PAST_STOPPED:
1892                 prev = &job_list;
1893                 curr = job_list;
1894                 for (; curr && curr->state == PSTOPPED; prev = &curr->next,
1895                     curr = *prev)
1896                         ;
1897                 j->next = curr;
1898                 *prev = j;
1899                 break;
1900         }
1901 }
1902
1903 /*
1904  * nuke a job (called when unable to start full job).
1905  *
1906  * If jobs are compiled in then this routine expects sigchld to be blocked.
1907  */
1908 static int
1909 kill_job(Job *j, int sig)
1910 {
1911         Proc *p;
1912         int rval = 0;
1913
1914         for (p = j->proc_list; p != NULL; p = p->next)
1915                 if (p->pid != 0)
1916                         if (kill(p->pid, sig) < 0)
1917                                 rval = -1;
1918         return (rval);
1919 }
1920
1921 static void
1922 tty_init_talking(void)
1923 {
1924         switch (tty_init_fd()) {
1925         case 0:
1926                 break;
1927         case 1:
1928 #ifndef MKSH_DISABLE_TTY_WARNING
1929                 warningf(false, Tf_sD_s_sD_s,
1930                     "No controlling tty", Topen, T_devtty, cstrerror(errno));
1931 #endif
1932                 break;
1933         case 2:
1934 #ifndef MKSH_DISABLE_TTY_WARNING
1935                 warningf(false, Tf_sD_s_s, Tcant_find, Ttty_fd,
1936                     cstrerror(errno));
1937 #endif
1938                 break;
1939         case 3:
1940                 warningf(false, Tf_ssfaileds, "j_ttyinit",
1941                     Ttty_fd_dupof, cstrerror(errno));
1942                 break;
1943         case 4:
1944                 warningf(false, Tf_sD_sD_s, "j_ttyinit",
1945                     "can't set close-on-exec flag", cstrerror(errno));
1946                 break;
1947         }
1948 }
1949
1950 static void
1951 tty_init_state(void)
1952 {
1953         if (tty_fd >= 0) {
1954                 mksh_tcget(tty_fd, &tty_state);
1955                 tty_hasstate = true;
1956         }
1957 }