OSDN Git Service

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