jobs.c revision 1.113 1 /* $NetBSD: jobs.c,v 1.113 2021/10/10 08:35:34 rillig Exp $ */
2
3 /*-
4 * Copyright (c) 1991, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * This code is derived from software contributed to Berkeley by
8 * Kenneth Almquist.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the University nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 */
34
35 #include <sys/cdefs.h>
36 #ifndef lint
37 #if 0
38 static char sccsid[] = "@(#)jobs.c 8.5 (Berkeley) 5/4/95";
39 #else
40 __RCSID("$NetBSD: jobs.c,v 1.113 2021/10/10 08:35:34 rillig Exp $");
41 #endif
42 #endif /* not lint */
43
44 #include <stdio.h>
45 #include <fcntl.h>
46 #include <signal.h>
47 #include <errno.h>
48 #include <unistd.h>
49 #include <stdlib.h>
50 #include <paths.h>
51 #include <sys/types.h>
52 #include <sys/param.h>
53 #ifdef BSD
54 #include <sys/wait.h>
55 #include <sys/time.h>
56 #include <sys/resource.h>
57 #endif
58 #include <sys/ioctl.h>
59
60 #include "shell.h"
61 #if JOBS
62 #if OLD_TTY_DRIVER
63 #include "sgtty.h"
64 #else
65 #include <termios.h>
66 #endif
67 #undef CEOF /* syntax.h redefines this */
68 #endif
69 #include "redir.h"
70 #include "show.h"
71 #include "main.h"
72 #include "parser.h"
73 #include "nodes.h"
74 #include "jobs.h"
75 #include "var.h"
76 #include "options.h"
77 #include "builtins.h"
78 #include "trap.h"
79 #include "syntax.h"
80 #include "input.h"
81 #include "output.h"
82 #include "memalloc.h"
83 #include "error.h"
84 #include "mystring.h"
85
86
87 #ifndef WCONTINUED
88 #define WCONTINUED 0 /* So we can compile on old systems */
89 #endif
90 #ifndef WIFCONTINUED
91 #define WIFCONTINUED(x) (0) /* ditto */
92 #endif
93
94
95 static struct job *jobtab; /* array of jobs */
96 static int njobs; /* size of array */
97 static int jobs_invalid; /* set in child */
98 MKINIT pid_t backgndpid = -1; /* pid of last background process */
99 #if JOBS
100 int initialpgrp; /* pgrp of shell on invocation */
101 static int curjob = -1; /* current job */
102 #endif
103 static int ttyfd = -1;
104
105 STATIC void restartjob(struct job *);
106 STATIC void freejob(struct job *);
107 STATIC struct job *getjob(const char *, int);
108 STATIC int dowait(int, struct job *, struct job **);
109 #define WBLOCK 1
110 #define WNOFREE 2
111 #define WSILENT 4
112 STATIC int jobstatus(const struct job *, int);
113 STATIC int waitproc(int, struct job *, int *);
114 STATIC void cmdtxt(union node *);
115 STATIC void cmdlist(union node *, int);
116 STATIC void cmdputs(const char *);
117 inline static void cmdputi(int);
118
119 #ifdef SYSV
120 STATIC int onsigchild(void);
121 #endif
122
123 #ifdef OLD_TTY_DRIVER
124 static pid_t tcgetpgrp(int fd);
125 static int tcsetpgrp(int fd, pid_t pgrp);
126
127 static pid_t
128 tcgetpgrp(int fd)
129 {
130 pid_t pgrp;
131 if (ioctl(fd, TIOCGPGRP, (char *)&pgrp) == -1)
132 return -1;
133 else
134 return pgrp;
135 }
136
137 static int
138 tcsetpgrp(int fd, pid_tpgrp)
139 {
140 return ioctl(fd, TIOCSPGRP, (char *)&pgrp);
141 }
142 #endif
143
144 static void
145 ttyfd_change(int from, int to)
146 {
147 if (ttyfd == from)
148 ttyfd = to;
149 }
150
151 /*
152 * Turn job control on and off.
153 *
154 * Note: This code assumes that the third arg to ioctl is a character
155 * pointer, which is true on Berkeley systems but not System V. Since
156 * System V doesn't have job control yet, this isn't a problem now.
157 */
158
159 MKINIT int jobctl;
160
161 void
162 setjobctl(int on)
163 {
164 #ifdef OLD_TTY_DRIVER
165 int ldisc;
166 #endif
167
168 if (on == jobctl || rootshell == 0)
169 return;
170 if (on) {
171 #if defined(FIOCLEX) || defined(FD_CLOEXEC)
172 int i;
173
174 if (ttyfd != -1)
175 sh_close(ttyfd);
176 if ((ttyfd = open("/dev/tty", O_RDWR)) == -1) {
177 for (i = 0; i < 3; i++) {
178 if (isatty(i) && (ttyfd = dup(i)) != -1)
179 break;
180 }
181 if (i == 3)
182 goto out;
183 }
184 ttyfd = to_upper_fd(ttyfd); /* Move to a high fd */
185 register_sh_fd(ttyfd, ttyfd_change);
186 #else
187 out2str("sh: Need FIOCLEX or FD_CLOEXEC to support job control");
188 goto out;
189 #endif
190 do { /* while we are in the background */
191 if ((initialpgrp = tcgetpgrp(ttyfd)) < 0) {
192 out:
193 out2str("sh: can't access tty; job control turned off\n");
194 mflag = 0;
195 return;
196 }
197 if (initialpgrp == -1)
198 initialpgrp = getpgrp();
199 else if (initialpgrp != getpgrp())
200 killpg(0, SIGTTIN);
201 } while (0);
202
203 #ifdef OLD_TTY_DRIVER
204 if (ioctl(ttyfd, TIOCGETD, (char *)&ldisc) < 0
205 || ldisc != NTTYDISC) {
206 out2str("sh: need new tty driver to run job control; job control turned off\n");
207 mflag = 0;
208 return;
209 }
210 #endif
211 setsignal(SIGTSTP, 0);
212 setsignal(SIGTTOU, 0);
213 setsignal(SIGTTIN, 0);
214 if (getpgrp() != rootpid && setpgid(0, rootpid) == -1)
215 error("Cannot set process group (%s) at %d",
216 strerror(errno), __LINE__);
217 if (tcsetpgrp(ttyfd, rootpid) == -1)
218 error("Cannot set tty process group (%s) at %d",
219 strerror(errno), __LINE__);
220 } else { /* turning job control off */
221 if (getpgrp() != initialpgrp && setpgid(0, initialpgrp) == -1)
222 error("Cannot set process group (%s) at %d",
223 strerror(errno), __LINE__);
224 if (tcsetpgrp(ttyfd, initialpgrp) == -1)
225 error("Cannot set tty process group (%s) at %d",
226 strerror(errno), __LINE__);
227 sh_close(ttyfd);
228 ttyfd = -1;
229 setsignal(SIGTSTP, 0);
230 setsignal(SIGTTOU, 0);
231 setsignal(SIGTTIN, 0);
232 }
233 jobctl = on;
234 }
235
236
237 #ifdef mkinit
238 INCLUDE <stdlib.h>
239
240 SHELLPROC {
241 backgndpid = -1;
242 #if JOBS
243 jobctl = 0;
244 #endif
245 }
246
247 #endif
248
249
250
251 #if JOBS
252 static int
253 do_fgcmd(const char *arg_ptr)
254 {
255 struct job *jp;
256 int i;
257 int status;
258
259 if (jobs_invalid)
260 error("No current jobs");
261 jp = getjob(arg_ptr, 0);
262 if (jp->jobctl == 0)
263 error("job not created under job control");
264 out1fmt("%s", jp->ps[0].cmd);
265 for (i = 1; i < jp->nprocs; i++)
266 out1fmt(" | %s", jp->ps[i].cmd );
267 out1c('\n');
268 flushall();
269
270 for (i = 0; i < jp->nprocs; i++)
271 if (tcsetpgrp(ttyfd, jp->ps[i].pid) != -1)
272 break;
273
274 if (i >= jp->nprocs) {
275 error("Cannot set tty process group (%s) at %d",
276 strerror(errno), __LINE__);
277 }
278 INTOFF;
279 restartjob(jp);
280 status = waitforjob(jp);
281 INTON;
282 return status;
283 }
284
285 int
286 fgcmd(int argc, char **argv)
287 {
288 nextopt("");
289 return do_fgcmd(*argptr);
290 }
291
292 int
293 fgcmd_percent(int argc, char **argv)
294 {
295 nextopt("");
296 return do_fgcmd(*argv);
297 }
298
299 static void
300 set_curjob(struct job *jp, int mode)
301 {
302 struct job *jp1, *jp2;
303 int i, ji;
304
305 ji = jp - jobtab;
306
307 /* first remove from list */
308 if (ji == curjob)
309 curjob = jp->prev_job;
310 else {
311 for (i = 0; i < njobs; i++) {
312 if (jobtab[i].prev_job != ji)
313 continue;
314 jobtab[i].prev_job = jp->prev_job;
315 break;
316 }
317 }
318
319 /* Then re-insert in correct position */
320 switch (mode) {
321 case 0: /* job being deleted */
322 jp->prev_job = -1;
323 break;
324 case 1: /* newly created job or backgrounded job,
325 put after all stopped jobs. */
326 if (curjob != -1 && jobtab[curjob].state == JOBSTOPPED) {
327 for (jp1 = jobtab + curjob; ; jp1 = jp2) {
328 if (jp1->prev_job == -1)
329 break;
330 jp2 = jobtab + jp1->prev_job;
331 if (jp2->state != JOBSTOPPED)
332 break;
333 }
334 jp->prev_job = jp1->prev_job;
335 jp1->prev_job = ji;
336 break;
337 }
338 /* FALLTHROUGH */
339 case 2: /* newly stopped job - becomes curjob */
340 jp->prev_job = curjob;
341 curjob = ji;
342 break;
343 }
344 }
345
346 int
347 bgcmd(int argc, char **argv)
348 {
349 struct job *jp;
350 int i;
351
352 nextopt("");
353 if (jobs_invalid)
354 error("No current jobs");
355 do {
356 jp = getjob(*argptr, 0);
357 if (jp->jobctl == 0)
358 error("job not created under job control");
359 set_curjob(jp, 1);
360 out1fmt("[%ld] %s", (long)(jp - jobtab + 1), jp->ps[0].cmd);
361 for (i = 1; i < jp->nprocs; i++)
362 out1fmt(" | %s", jp->ps[i].cmd );
363 out1c('\n');
364 flushall();
365 restartjob(jp);
366 } while (*argptr && *++argptr);
367 return 0;
368 }
369
370
371 STATIC void
372 restartjob(struct job *jp)
373 {
374 struct procstat *ps;
375 int i, e;
376
377 if (jp->state == JOBDONE)
378 return;
379 INTOFF;
380 for (e = i = 0; i < jp->nprocs; i++) {
381 /*
382 * Don't touch a process we already waited for and collected
383 * exit status, that pid may have been reused for something
384 * else - even another of our jobs
385 */
386 if (jp->ps[i].status != -1 && !WIFSTOPPED(jp->ps[i].status))
387 continue;
388
389 /*
390 * Otherwise tell it to continue, if it worked, we're done
391 * (we signal the whole process group)
392 */
393 if (killpg(jp->ps[i].pid, SIGCONT) != -1)
394 break;
395 if (e == 0 && errno != ESRCH)
396 e = errno;
397 }
398 if (i >= jp->nprocs)
399 error("Cannot continue job (%s)", strerror(e ? e : ESRCH));
400
401 /*
402 * Now change state of all stopped processes in the job to running
403 * If there were any, the job is now running as well.
404 */
405 for (ps = jp->ps, i = jp->nprocs ; --i >= 0 ; ps++) {
406 if (WIFSTOPPED(ps->status)) {
407 VTRACE(DBG_JOBS, (
408 "restartjob: [%zu] pid %d status change"
409 " from %#x (stopped) to -1 (running)\n",
410 (size_t)(jp-jobtab+1), ps->pid, ps->status));
411 ps->status = -1;
412 jp->state = JOBRUNNING;
413 }
414 }
415 INTON;
416 }
417 #endif
418
419 inline static void
420 cmdputi(int n)
421 {
422 char str[20];
423
424 fmtstr(str, sizeof str, "%d", n);
425 cmdputs(str);
426 }
427
428 static void
429 showjob(struct output *out, struct job *jp, int mode)
430 {
431 int procno;
432 int st;
433 struct procstat *ps;
434 int col;
435 char s[64];
436
437 #if JOBS
438 if (mode & SHOW_PGID) {
439 /* just output process (group) id of pipeline */
440 outfmt(out, "%ld\n", (long)jp->ps->pid);
441 return;
442 }
443 #endif
444
445 procno = jp->nprocs;
446 if (!procno)
447 return;
448
449 if (mode & SHOW_PID)
450 mode |= SHOW_MULTILINE;
451
452 if ((procno > 1 && !(mode & SHOW_MULTILINE))
453 || (mode & SHOW_SIGNALLED)) {
454 /* See if we have more than one status to report */
455 ps = jp->ps;
456 st = ps->status;
457 do {
458 int st1 = ps->status;
459 if (st1 != st)
460 /* yes - need multi-line output */
461 mode |= SHOW_MULTILINE;
462 if (st1 == -1 || !(mode & SHOW_SIGNALLED) || WIFEXITED(st1))
463 continue;
464 if (WIFSTOPPED(st1) || ((st1 = WTERMSIG(st1) & 0x7f)
465 && st1 != SIGINT && st1 != SIGPIPE))
466 mode |= SHOW_ISSIG;
467
468 } while (ps++, --procno);
469 procno = jp->nprocs;
470 }
471
472 if (mode & SHOW_SIGNALLED && !(mode & SHOW_ISSIG)) {
473 if (jp->state == JOBDONE && !(mode & SHOW_NO_FREE)) {
474 VTRACE(DBG_JOBS, ("showjob: freeing job %d\n",
475 jp - jobtab + 1));
476 freejob(jp);
477 }
478 return;
479 }
480
481 for (ps = jp->ps; --procno >= 0; ps++) { /* for each process */
482 if (ps == jp->ps)
483 fmtstr(s, 16, "[%ld] %c ",
484 (long)(jp - jobtab + 1),
485 #if JOBS
486 jp - jobtab == curjob ?
487 '+' :
488 curjob != -1 &&
489 jp - jobtab == jobtab[curjob].prev_job ?
490 '-' :
491 #endif
492 ' ');
493 else
494 fmtstr(s, 16, " " );
495 col = strlen(s);
496 if (mode & SHOW_PID) {
497 fmtstr(s + col, 16, "%ld ", (long)ps->pid);
498 col += strlen(s + col);
499 }
500 if (ps->status == -1) {
501 scopy("Running", s + col);
502 } else if (WIFEXITED(ps->status)) {
503 st = WEXITSTATUS(ps->status);
504 if (st)
505 fmtstr(s + col, 16, "Done(%d)", st);
506 else
507 fmtstr(s + col, 16, "Done");
508 } else {
509 #if JOBS
510 if (WIFSTOPPED(ps->status))
511 st = WSTOPSIG(ps->status);
512 else /* WIFSIGNALED(ps->status) */
513 #endif
514 st = WTERMSIG(ps->status);
515 scopyn(strsignal(st), s + col, 32);
516 if (WCOREDUMP(ps->status)) {
517 col += strlen(s + col);
518 scopyn(" (core dumped)", s + col, 64 - col);
519 }
520 }
521 col += strlen(s + col);
522 outstr(s, out);
523 do {
524 outc(' ', out);
525 col++;
526 } while (col < 30);
527 outstr(ps->cmd, out);
528 if (mode & SHOW_MULTILINE) {
529 if (procno > 0) {
530 outc(' ', out);
531 outc('|', out);
532 }
533 } else {
534 while (--procno >= 0)
535 outfmt(out, " | %s", (++ps)->cmd );
536 }
537 outc('\n', out);
538 }
539 flushout(out);
540 jp->flags &= ~JOBCHANGED;
541 if (jp->state == JOBDONE && !(mode & SHOW_NO_FREE))
542 freejob(jp);
543 }
544
545 int
546 jobscmd(int argc, char **argv)
547 {
548 int mode, m;
549
550 mode = 0;
551 while ((m = nextopt("lpZ")))
552 switch (m) {
553 case 'l':
554 mode = SHOW_PID;
555 break;
556 case 'p':
557 mode = SHOW_PGID;
558 break;
559 case 'Z':
560 mode = SHOW_PROCTITLE;
561 break;
562 }
563
564 if (mode == SHOW_PROCTITLE) {
565 if (*argptr && **argptr)
566 setproctitle("%s", *argptr);
567 else
568 setproctitle(NULL);
569 return 0;
570 }
571
572 if (!iflag && !posix)
573 mode |= SHOW_NO_FREE;
574
575 if (*argptr) {
576 do
577 showjob(out1, getjob(*argptr,0), mode);
578 while (*++argptr);
579 } else
580 showjobs(out1, mode);
581 return 0;
582 }
583
584
585 /*
586 * Print a list of jobs. If "change" is nonzero, only print jobs whose
587 * statuses have changed since the last call to showjobs.
588 *
589 * If the shell is interrupted in the process of creating a job, the
590 * result may be a job structure containing zero processes. Such structures
591 * will be freed here.
592 */
593
594 void
595 showjobs(struct output *out, int mode)
596 {
597 int jobno;
598 struct job *jp;
599 int silent = 0, gotpid;
600
601 CTRACE(DBG_JOBS, ("showjobs(%x) called\n", mode));
602
603 /* Collect everything pending in the kernel */
604 if ((gotpid = dowait(WSILENT, NULL, NULL)) > 0)
605 while (dowait(WSILENT, NULL, NULL) > 0)
606 continue;
607 #ifdef JOBS
608 /*
609 * Check if we are not in our foreground group, and if not
610 * put us in it.
611 */
612 if (mflag && gotpid != -1 && tcgetpgrp(ttyfd) != getpid()) {
613 if (tcsetpgrp(ttyfd, getpid()) == -1)
614 error("Cannot set tty process group (%s) at %d",
615 strerror(errno), __LINE__);
616 VTRACE(DBG_JOBS|DBG_INPUT, ("repaired tty process group\n"));
617 silent = 1;
618 }
619 #endif
620
621 for (jobno = 1, jp = jobtab ; jobno <= njobs ; jobno++, jp++) {
622 if (!jp->used)
623 continue;
624 if (jp->nprocs == 0) {
625 if (!jobs_invalid)
626 freejob(jp);
627 continue;
628 }
629 if ((mode & SHOW_CHANGED) && !(jp->flags & JOBCHANGED))
630 continue;
631 if (silent && (jp->flags & JOBCHANGED)) {
632 jp->flags &= ~JOBCHANGED;
633 continue;
634 }
635 showjob(out, jp, mode);
636 }
637 }
638
639 /*
640 * Mark a job structure as unused.
641 */
642
643 STATIC void
644 freejob(struct job *jp)
645 {
646 INTOFF;
647 if (jp->ps != &jp->ps0) {
648 ckfree(jp->ps);
649 jp->ps = &jp->ps0;
650 }
651 jp->nprocs = 0;
652 jp->used = 0;
653 #if JOBS
654 set_curjob(jp, 0);
655 #endif
656 INTON;
657 }
658
659 /*
660 * Extract the status of a completed job (for $?)
661 */
662 STATIC int
663 jobstatus(const struct job *jp, int raw)
664 {
665 int status = 0;
666 int retval;
667
668 if ((jp->flags & JPIPEFAIL) && jp->nprocs) {
669 int i;
670
671 for (i = 0; i < jp->nprocs; i++)
672 if (jp->ps[i].status != 0)
673 status = jp->ps[i].status;
674 } else
675 status = jp->ps[jp->nprocs ? jp->nprocs - 1 : 0].status;
676
677 if (raw)
678 return status;
679
680 if (WIFEXITED(status))
681 retval = WEXITSTATUS(status);
682 #if JOBS
683 else if (WIFSTOPPED(status))
684 retval = WSTOPSIG(status) + 128;
685 #endif
686 else {
687 /* XXX: limits number of signals */
688 retval = WTERMSIG(status) + 128;
689 }
690
691 return retval;
692 }
693
694
695
696 int
697 waitcmd(int argc, char **argv)
698 {
699 struct job *job, *last;
700 int retval;
701 struct job *jp;
702 int i;
703 int any = 0;
704 int found;
705 char *pid = NULL, *fpid;
706 char **arg;
707 char idstring[20];
708
709 while ((i = nextopt("np:")) != '\0') {
710 switch (i) {
711 case 'n':
712 any = 1;
713 break;
714 case 'p':
715 if (pid)
716 error("more than one -p unsupported");
717 pid = optionarg;
718 break;
719 }
720 }
721
722 if (pid != NULL) {
723 if (!validname(pid, '\0', NULL))
724 error("invalid name: -p '%s'", pid);
725 if (unsetvar(pid, 0))
726 error("%s readonly", pid);
727 }
728
729 /*
730 * If we have forked, and not yet created any new jobs, then
731 * we have no children, whatever jobtab claims,
732 * so simply return in that case.
733 *
734 * The return code is 127 if we had any pid args (none are found)
735 * or if we had -n (nothing exited), but 0 for plain old "wait".
736 */
737 if (jobs_invalid) {
738 CTRACE(DBG_WAIT, ("builtin wait%s%s in child, invalid jobtab\n",
739 any ? " -n" : "", *argptr ? " pid..." : ""));
740 return (any || *argptr) ? 127 : 0;
741 }
742
743 /*
744 * clear stray flags left from previous waitcmd
745 * or set them instead if anything will do ("wait -n")
746 */
747 for (jp = jobtab, i = njobs ; --i >= 0 ; jp++) {
748 if (any && *argptr == NULL)
749 jp->flags |= JOBWANTED;
750 else
751 jp->flags &= ~JOBWANTED;
752 jp->ref = NULL;
753 }
754
755 CTRACE(DBG_WAIT,
756 ("builtin wait%s%s\n", any ? " -n" : "", *argptr ? " pid..." : ""));
757
758 /*
759 * First, validate the jobnum args, count how many refer to
760 * (different) running jobs, and if we had -n, and found that one has
761 * already finished, we return that one. Otherwise remember
762 * which ones we are looking for (JOBWANTED).
763 */
764 found = 0;
765 last = NULL;
766 for (arg = argptr; *arg; arg++) {
767 last = jp = getjob(*arg, 1);
768 if (!jp)
769 continue;
770 if (jp->ref == NULL)
771 jp->ref = *arg;
772 if (any && jp->state == JOBDONE) {
773 /*
774 * We just want any of them, and this one is
775 * ready for consumption, bon apetit ...
776 */
777 retval = jobstatus(jp, 0);
778 if (pid)
779 setvar(pid, *arg, 0);
780 if (!iflag)
781 freejob(jp);
782 CTRACE(DBG_WAIT, ("wait -n found %s already done: %d\n", *arg, retval));
783 return retval;
784 }
785 if (!(jp->flags & JOBWANTED)) {
786 /*
787 * It is possible to list the same job several
788 * times - the obvious "wait 1 1 1" or
789 * "wait %% %2 102" where job 2 is current and pid 102
790 * However many times it is requested, it is found once.
791 */
792 found++;
793 jp->flags |= JOBWANTED;
794 }
795 job = jp;
796 }
797
798 VTRACE(DBG_WAIT, ("wait %s%s%sfound %d candidates (last %s)\n",
799 any ? "-n " : "", *argptr ? *argptr : "",
800 argptr[0] && argptr[1] ? "... " : " ", found,
801 job && job->used ? (job->ref ? job->ref : "<no-arg>") : "none"));
802
803 /*
804 * If we were given a list of jobnums:
805 * and none of those exist, then we're done.
806 */
807 if (*argptr && found == 0)
808 return 127;
809
810 /*
811 * Otherwise we need to wait for something to complete
812 * When it does, we check and see if it is one of the
813 * jobs we're waiting on, and if so, we clean it up.
814 * If we had -n, then we're done, otherwise we do it all again
815 * until all we had listed are done, of if there were no
816 * jobnum args, all are done.
817 */
818
819 retval = any || *argptr ? 127 : 0;
820 fpid = NULL;
821 for (;;) {
822 VTRACE(DBG_WAIT, ("wait waiting (%d remain): ", found));
823 job = NULL;
824 for (jp = jobtab, i = njobs; --i >= 0; jp++) {
825 if (jp->used && jp->flags & JOBWANTED &&
826 jp->state == JOBDONE) {
827 job = jp;
828 break;
829 }
830 if (jp->used && jp->state == JOBRUNNING)
831 job = jp;
832 }
833 if (i < 0 && job == NULL) {
834 CTRACE(DBG_WAIT, ("nothing running (ret: %d) fpid %s\n",
835 retval, fpid ? fpid : "unset"));
836 if (pid && fpid)
837 setvar(pid, fpid, 0);
838 return retval;
839 }
840 jp = job;
841 VTRACE(DBG_WAIT, ("found @%d/%d state: %d\n", njobs-i, njobs,
842 jp->state));
843
844 /*
845 * There is at least 1 job running, so we can
846 * safely wait() (blocking) for something to exit.
847 */
848 if (jp->state == JOBRUNNING) {
849 job = NULL;
850 if ((i = dowait(WBLOCK|WNOFREE, NULL, &job)) == -1)
851 return 128 + lastsig();
852
853 /*
854 * This happens if an interloper has died
855 * (eg: a child of the executable that exec'd us)
856 * Simply go back and start all over again
857 * (this is rare).
858 */
859 if (job == NULL)
860 continue;
861
862 /*
863 * one of the reported job's processes exited,
864 * but there are more still running, back for more
865 */
866 if (job->state == JOBRUNNING)
867 continue;
868 } else
869 job = jp; /* we want this, and it is done */
870
871 if (job->flags & JOBWANTED) {
872 int rv;
873
874 job->flags &= ~JOBWANTED; /* got it */
875 rv = jobstatus(job, 0);
876 VTRACE(DBG_WAIT, (
877 "wanted %d (%s) done: st=%d", i,
878 job->ref ? job->ref : "", rv));
879 if (any || job == last) {
880 retval = rv;
881 fpid = job->ref;
882
883 VTRACE(DBG_WAIT, (" save"));
884 if (pid) {
885 /*
886 * don't need fpid unless we are going
887 * to return it.
888 */
889 if (fpid == NULL) {
890 /*
891 * this only happens with "wait -n"
892 * (that is, no pid args)
893 */
894 snprintf(idstring, sizeof idstring,
895 "%d", job->ps[ job->nprocs ?
896 job->nprocs-1 :
897 0 ].pid);
898 fpid = idstring;
899 }
900 VTRACE(DBG_WAIT, (" (for %s)", fpid));
901 }
902 }
903
904 if (job->state == JOBDONE) {
905 VTRACE(DBG_WAIT, (" free"));
906 freejob(job);
907 }
908
909 if (any || (found > 0 && --found == 0)) {
910 if (pid && fpid)
911 setvar(pid, fpid, 0);
912 VTRACE(DBG_WAIT, (" return %d\n", retval));
913 return retval;
914 }
915 VTRACE(DBG_WAIT, ("\n"));
916 continue;
917 }
918
919 /* this is to handle "wait" (no args) */
920 if (found == 0 && job->state == JOBDONE) {
921 VTRACE(DBG_JOBS|DBG_WAIT, ("Cleanup: %d\n", i));
922 freejob(job);
923 }
924 }
925 }
926
927
928 int
929 jobidcmd(int argc, char **argv)
930 {
931 struct job *jp;
932 int i;
933 int pg = 0, onep = 0, job = 0;
934
935 while ((i = nextopt("gjp"))) {
936 switch (i) {
937 case 'g': pg = 1; break;
938 case 'j': job = 1; break;
939 case 'p': onep = 1; break;
940 }
941 }
942 CTRACE(DBG_JOBS, ("jobidcmd%s%s%s%s %s\n", pg ? " -g" : "",
943 onep ? " -p" : "", job ? " -j" : "", jobs_invalid ? " [inv]" : "",
944 *argptr ? *argptr : "<implicit %%>"));
945 if (pg + onep + job > 1)
946 error("-g -j and -p options cannot be combined");
947
948 if (argptr[0] && argptr[1])
949 error("usage: jobid [-g|-p|-r] jobid");
950
951 jp = getjob(*argptr, 0);
952 if (job) {
953 out1fmt("%%%zu\n", (size_t)(jp - jobtab + 1));
954 return 0;
955 }
956 if (pg) {
957 if (jp->pgrp != 0) {
958 out1fmt("%ld\n", (long)jp->pgrp);
959 return 0;
960 }
961 return 1;
962 }
963 if (onep) {
964 i = jp->nprocs - 1;
965 if (i < 0)
966 return 1;
967 out1fmt("%ld\n", (long)jp->ps[i].pid);
968 return 0;
969 }
970 for (i = 0 ; i < jp->nprocs ; ) {
971 out1fmt("%ld", (long)jp->ps[i].pid);
972 out1c(++i < jp->nprocs ? ' ' : '\n');
973 }
974 return 0;
975 }
976
977 int
978 getjobpgrp(const char *name)
979 {
980 struct job *jp;
981
982 if (jobs_invalid)
983 error("No such job: %s", name);
984 jp = getjob(name, 1);
985 if (jp == 0)
986 return 0;
987 return -jp->pgrp;
988 }
989
990 /*
991 * Convert a job name to a job structure.
992 */
993
994 STATIC struct job *
995 getjob(const char *name, int noerror)
996 {
997 int jobno = -1;
998 struct job *jp;
999 int pid;
1000 int i;
1001 const char *err_msg = "No such job: %s";
1002
1003 if (name == NULL) {
1004 #if JOBS
1005 jobno = curjob;
1006 #endif
1007 err_msg = "No current job";
1008 } else if (name[0] == '%') {
1009 if (is_number(name + 1)) {
1010 jobno = number(name + 1) - 1;
1011 } else if (!name[1] || !name[2]) {
1012 switch (name[1]) {
1013 #if JOBS
1014 case 0:
1015 case '+':
1016 case '%':
1017 jobno = curjob;
1018 err_msg = "No current job";
1019 break;
1020 case '-':
1021 jobno = curjob;
1022 if (jobno != -1)
1023 jobno = jobtab[jobno].prev_job;
1024 err_msg = "No previous job";
1025 break;
1026 #endif
1027 default:
1028 goto check_pattern;
1029 }
1030 } else {
1031 struct job *found;
1032 check_pattern:
1033 found = NULL;
1034 for (jp = jobtab, i = njobs ; --i >= 0 ; jp++) {
1035 if (!jp->used || jp->nprocs <= 0)
1036 continue;
1037 if ((name[1] == '?'
1038 && strstr(jp->ps[0].cmd, name + 2))
1039 || prefix(name + 1, jp->ps[0].cmd)) {
1040 if (found) {
1041 err_msg = "%s: ambiguous";
1042 found = 0;
1043 break;
1044 }
1045 found = jp;
1046 }
1047 }
1048 if (found)
1049 return found;
1050 }
1051
1052 } else if (is_number(name)) {
1053 pid = number(name);
1054 for (jp = jobtab, i = njobs ; --i >= 0 ; jp++) {
1055 if (jp->used && jp->nprocs > 0
1056 && jp->ps[jp->nprocs - 1].pid == pid)
1057 return jp;
1058 }
1059 }
1060
1061 if (jobno >= 0 && jobno < njobs) {
1062 jp = jobtab + jobno;
1063 if (jp->used)
1064 return jp;
1065 }
1066 if (!noerror)
1067 error(err_msg, name);
1068 return 0;
1069 }
1070
1071
1072 /*
1073 * Find out if there are any running (that is, unwaited upon)
1074 * background children of the current shell.
1075 *
1076 * Return 1/0 (yes, no).
1077 *
1078 * Needed as we cannot optimise away sub-shell creation if
1079 * we have such a child, or a "wait" in that sub-shell would
1080 * observe the already existing job.
1081 */
1082 int
1083 anyjobs(void)
1084 {
1085 struct job *jp;
1086 int i;
1087
1088 if (jobs_invalid)
1089 return 0;
1090
1091 for (i = njobs, jp = jobtab ; --i >= 0 ; jp++) {
1092 if (jp->used)
1093 return 1;
1094 }
1095
1096 return 0;
1097 }
1098
1099 /*
1100 * Return a new job structure,
1101 */
1102
1103 struct job *
1104 makejob(union node *node, int nprocs)
1105 {
1106 int i;
1107 struct job *jp;
1108
1109 if (jobs_invalid) {
1110 VTRACE(DBG_JOBS, ("makejob(%p, %d) clearing jobtab (%d)\n",
1111 (void *)node, nprocs, njobs));
1112 for (i = njobs, jp = jobtab ; --i >= 0 ; jp++) {
1113 if (jp->used)
1114 freejob(jp);
1115 }
1116 jobs_invalid = 0;
1117 }
1118
1119 for (i = njobs, jp = jobtab ; ; jp++) {
1120 if (--i < 0) {
1121 INTOFF;
1122 if (njobs == 0) {
1123 jobtab = ckmalloc(4 * sizeof jobtab[0]);
1124 } else {
1125 jp = ckmalloc((njobs + 4) * sizeof jobtab[0]);
1126 memcpy(jp, jobtab, njobs * sizeof jp[0]);
1127 /* Relocate `ps' pointers */
1128 for (i = 0; i < njobs; i++)
1129 if (jp[i].ps == &jobtab[i].ps0)
1130 jp[i].ps = &jp[i].ps0;
1131 ckfree(jobtab);
1132 jobtab = jp;
1133 }
1134 jp = jobtab + njobs;
1135 for (i = 4 ; --i >= 0 ; njobs++) {
1136 jobtab[njobs].used = 0;
1137 jobtab[njobs].prev_job = -1;
1138 }
1139 INTON;
1140 break;
1141 }
1142 if (jp->used == 0)
1143 break;
1144 }
1145 INTOFF;
1146 jp->state = JOBRUNNING;
1147 jp->used = 1;
1148 jp->flags = pipefail ? JPIPEFAIL : 0;
1149 jp->nprocs = 0;
1150 jp->pgrp = 0;
1151 #if JOBS
1152 jp->jobctl = jobctl;
1153 set_curjob(jp, 1);
1154 #endif
1155 if (nprocs > 1) {
1156 jp->ps = ckmalloc(nprocs * sizeof (struct procstat));
1157 } else {
1158 jp->ps = &jp->ps0;
1159 }
1160 INTON;
1161 VTRACE(DBG_JOBS, ("makejob(%p, %d)%s returns %%%d\n", (void *)node,
1162 nprocs, (jp->flags&JPIPEFAIL)?" PF":"", jp - jobtab + 1));
1163 return jp;
1164 }
1165
1166
1167 /*
1168 * Fork off a subshell. If we are doing job control, give the subshell its
1169 * own process group. Jp is a job structure that the job is to be added to.
1170 * N is the command that will be evaluated by the child. Both jp and n may
1171 * be NULL. The mode parameter can be one of the following:
1172 * FORK_FG - Fork off a foreground process.
1173 * FORK_BG - Fork off a background process.
1174 * FORK_NOJOB - Like FORK_FG, but don't give the process its own
1175 * process group even if job control is on.
1176 *
1177 * When job control is turned off, background processes have their standard
1178 * input redirected to /dev/null (except for the second and later processes
1179 * in a pipeline).
1180 */
1181
1182 int
1183 forkshell(struct job *jp, union node *n, int mode)
1184 {
1185 pid_t pid;
1186 int serrno;
1187
1188 CTRACE(DBG_JOBS, ("forkshell(%%%d, %p, %d) called\n",
1189 jp - jobtab, n, mode));
1190
1191 switch ((pid = fork())) {
1192 case -1:
1193 serrno = errno;
1194 VTRACE(DBG_JOBS, ("Fork failed, errno=%d\n", serrno));
1195 error("Cannot fork (%s)", strerror(serrno));
1196 break;
1197 case 0:
1198 SHELL_FORKED();
1199 forkchild(jp, n, mode, 0);
1200 return 0;
1201 default:
1202 return forkparent(jp, n, mode, pid);
1203 }
1204 }
1205
1206 int
1207 forkparent(struct job *jp, union node *n, int mode, pid_t pid)
1208 {
1209 int pgrp;
1210
1211 if (rootshell && mode != FORK_NOJOB && mflag) {
1212 if (jp == NULL || jp->nprocs == 0)
1213 pgrp = pid;
1214 else
1215 pgrp = jp->ps[0].pid;
1216 jp->pgrp = pgrp;
1217 /* This can fail because we are doing it in the child also */
1218 (void)setpgid(pid, pgrp);
1219 }
1220 if (mode == FORK_BG)
1221 backgndpid = pid; /* set $! */
1222 if (jp) {
1223 struct procstat *ps = &jp->ps[jp->nprocs++];
1224 ps->pid = pid;
1225 ps->status = -1;
1226 ps->cmd[0] = 0;
1227 if (/* iflag && rootshell && */ n)
1228 commandtext(ps, n);
1229 }
1230 CTRACE(DBG_JOBS, ("In parent shell: child = %d (mode %d)\n",pid,mode));
1231 return pid;
1232 }
1233
1234 void
1235 forkchild(struct job *jp, union node *n, int mode, int vforked)
1236 {
1237 int wasroot;
1238 int pgrp;
1239 const char *devnull = _PATH_DEVNULL;
1240 const char *nullerr = "Can't open %s";
1241
1242 wasroot = rootshell;
1243 CTRACE(DBG_JOBS, ("Child shell %d %sforked from %d (mode %d)\n",
1244 getpid(), vforked?"v":"", getppid(), mode));
1245
1246 if (!vforked) {
1247 rootshell = 0;
1248 handler = &main_handler;
1249 }
1250
1251 closescript(vforked);
1252 clear_traps(vforked);
1253 #if JOBS
1254 if (!vforked)
1255 jobctl = 0; /* do job control only in root shell */
1256 if (wasroot && mode != FORK_NOJOB && mflag) {
1257 if (jp == NULL || jp->nprocs == 0)
1258 pgrp = getpid();
1259 else
1260 pgrp = jp->ps[0].pid;
1261 /* This can fail because we are doing it in the parent also */
1262 (void)setpgid(0, pgrp);
1263 if (mode == FORK_FG) {
1264 if (tcsetpgrp(ttyfd, pgrp) == -1)
1265 error("Cannot set tty process group (%s) at %d",
1266 strerror(errno), __LINE__);
1267 }
1268 setsignal(SIGTSTP, vforked);
1269 setsignal(SIGTTOU, vforked);
1270 } else if (mode == FORK_BG) {
1271 ignoresig(SIGINT, vforked);
1272 ignoresig(SIGQUIT, vforked);
1273 if ((jp == NULL || jp->nprocs == 0) &&
1274 ! fd0_redirected_p ()) {
1275 close(0);
1276 if (open(devnull, O_RDONLY) != 0)
1277 error(nullerr, devnull);
1278 }
1279 }
1280 #else
1281 if (mode == FORK_BG) {
1282 ignoresig(SIGINT, vforked);
1283 ignoresig(SIGQUIT, vforked);
1284 if ((jp == NULL || jp->nprocs == 0) &&
1285 ! fd0_redirected_p ()) {
1286 close(0);
1287 if (open(devnull, O_RDONLY) != 0)
1288 error(nullerr, devnull);
1289 }
1290 }
1291 #endif
1292 if (wasroot && iflag) {
1293 setsignal(SIGINT, vforked);
1294 setsignal(SIGQUIT, vforked);
1295 setsignal(SIGTERM, vforked);
1296 }
1297
1298 if (!vforked)
1299 jobs_invalid = 1;
1300 }
1301
1302 /*
1303 * Wait for job to finish.
1304 *
1305 * Under job control we have the problem that while a child process is
1306 * running interrupts generated by the user are sent to the child but not
1307 * to the shell. This means that an infinite loop started by an inter-
1308 * active user may be hard to kill. With job control turned off, an
1309 * interactive user may place an interactive program inside a loop. If
1310 * the interactive program catches interrupts, the user doesn't want
1311 * these interrupts to also abort the loop. The approach we take here
1312 * is to have the shell ignore interrupt signals while waiting for a
1313 * forground process to terminate, and then send itself an interrupt
1314 * signal if the child process was terminated by an interrupt signal.
1315 * Unfortunately, some programs want to do a bit of cleanup and then
1316 * exit on interrupt; unless these processes terminate themselves by
1317 * sending a signal to themselves (instead of calling exit) they will
1318 * confuse this approach.
1319 */
1320
1321 int
1322 waitforjob(struct job *jp)
1323 {
1324 #if JOBS
1325 int mypgrp = getpgrp();
1326 #endif
1327 int status;
1328 int st;
1329
1330 INTOFF;
1331 VTRACE(DBG_JOBS, ("waitforjob(%%%d) called\n", jp - jobtab + 1));
1332 while (jp->state == JOBRUNNING) {
1333 dowait(WBLOCK, jp, NULL);
1334 }
1335 #if JOBS
1336 if (jp->jobctl) {
1337 if (tcsetpgrp(ttyfd, mypgrp) == -1)
1338 error("Cannot set tty process group (%s) at %d",
1339 strerror(errno), __LINE__);
1340 }
1341 if (jp->state == JOBSTOPPED && curjob != jp - jobtab)
1342 set_curjob(jp, 2);
1343 #endif
1344 status = jobstatus(jp, 1);
1345
1346 /* convert to 8 bits */
1347 if (WIFEXITED(status))
1348 st = WEXITSTATUS(status);
1349 #if JOBS
1350 else if (WIFSTOPPED(status))
1351 st = WSTOPSIG(status) + 128;
1352 #endif
1353 else
1354 st = WTERMSIG(status) + 128;
1355
1356 VTRACE(DBG_JOBS, ("waitforjob: job %d, nproc %d, status %d, st %x\n",
1357 jp - jobtab + 1, jp->nprocs, status, st));
1358 #if JOBS
1359 if (jp->jobctl) {
1360 /*
1361 * This is truly gross.
1362 * If we're doing job control, then we did a TIOCSPGRP which
1363 * caused us (the shell) to no longer be in the controlling
1364 * session -- so we wouldn't have seen any ^C/SIGINT. So, we
1365 * intuit from the subprocess exit status whether a SIGINT
1366 * occurred, and if so interrupt ourselves. Yuck. - mycroft
1367 */
1368 if (WIFSIGNALED(status) && WTERMSIG(status) == SIGINT)
1369 raise(SIGINT);
1370 }
1371 #endif
1372 if (! JOBS || jp->state == JOBDONE)
1373 freejob(jp);
1374 INTON;
1375 return st;
1376 }
1377
1378
1379
1380 /*
1381 * Wait for a process (any process) to terminate.
1382 *
1383 * If "job" is given (not NULL), then its jobcontrol status (and mflag)
1384 * are used to determine if we wait for stopping/continuing processes or
1385 * only terminating ones, and the decision whether to report to stdout
1386 * or not varies depending what happened, and whether the affected job
1387 * is the one that was requested or not.
1388 *
1389 * If "changed" is not NULL, then the job which changed because a
1390 * process terminated/stopped will be reported by setting *changed,
1391 * if there is any such job, otherwise we set *changed = NULL.
1392 */
1393
1394 STATIC int
1395 dowait(int flags, struct job *job, struct job **changed)
1396 {
1397 int pid;
1398 int status;
1399 struct procstat *sp;
1400 struct job *jp;
1401 struct job *thisjob;
1402 int done;
1403 int stopped;
1404 int err;
1405
1406 VTRACE(DBG_JOBS|DBG_PROCS, ("dowait(%x) called for job %d%s\n",
1407 flags, (job ? job-jobtab+1 : 0), changed ? " [report change]":""));
1408
1409 if (changed != NULL)
1410 *changed = NULL;
1411
1412 /*
1413 * First deal with the kernel, collect info on any (one) of our
1414 * children that has changed state since we last asked.
1415 * (loop if we're interrupted by a signal that we aren't processing)
1416 */
1417 do {
1418 err = 0;
1419 pid = waitproc(flags & WBLOCK, job, &status);
1420 if (pid == -1)
1421 err = errno;
1422 VTRACE(DBG_JOBS|DBG_PROCS,
1423 ("wait returns pid %d (e:%d), status %#x (ps=%d)\n",
1424 pid, err, status, pendingsigs));
1425 } while (pid == -1 && err == EINTR && pendingsigs == 0);
1426
1427 /*
1428 * if nothing exited/stopped/..., we have nothing else to do
1429 */
1430 if (pid <= 0)
1431 return pid;
1432
1433 /*
1434 * Otherwise, try to find the process, somewhere in our job table
1435 */
1436 INTOFF;
1437 thisjob = NULL;
1438 for (jp = jobtab ; jp < jobtab + njobs ; jp++) {
1439 if (jp->used) {
1440 /*
1441 * For each job that is in use (this is one)
1442 */
1443 done = 1; /* assume it is finished */
1444 stopped = 1; /* and has stopped */
1445
1446 /*
1447 * Now scan all our child processes of the job
1448 */
1449 for (sp = jp->ps ; sp < jp->ps + jp->nprocs ; sp++) {
1450 if (sp->pid == -1)
1451 continue;
1452 /*
1453 * If the process that changed is the one
1454 * we're looking at, and it was previously
1455 * running (-1) or was stopped (anything else
1456 * and it must have already finished earlier,
1457 * so cannot be the process that just changed)
1458 * then we update its status
1459 */
1460 if (sp->pid == pid &&
1461 (sp->status==-1 || WIFSTOPPED(sp->status))) {
1462 VTRACE(DBG_JOBS | DBG_PROCS,
1463 ("Job %d: changing status of proc %d from %#x to %#x\n",
1464 jp - jobtab + 1, pid,
1465 sp->status, status));
1466
1467 /*
1468 * If the process continued,
1469 * then update its status to running
1470 * and mark the job running as well.
1471 *
1472 * If it was anything but running
1473 * before, flag it as a change for
1474 * reporting purposes later
1475 */
1476 if (WIFCONTINUED(status)) {
1477 if (sp->status != -1)
1478 jp->flags |= JOBCHANGED;
1479 sp->status = -1;
1480 jp->state = 0;
1481 } else {
1482 /* otherwise update status */
1483 sp->status = status;
1484 }
1485
1486 /*
1487 * We now know the affected job
1488 */
1489 thisjob = jp;
1490 if (changed != NULL)
1491 *changed = jp;
1492 }
1493 /*
1494 * After any update that might have just
1495 * happened, if this process is running,
1496 * the job is not stopped, or if the process
1497 * simply stopped (not terminated) then the
1498 * job is certainly not completed (done).
1499 */
1500 if (sp->status == -1)
1501 stopped = 0;
1502 else if (WIFSTOPPED(sp->status))
1503 done = 0;
1504 }
1505
1506 /*
1507 * Once we have examined all processes for the
1508 * job, if we still show it as stopped, then...
1509 */
1510 if (stopped) { /* stopped or done */
1511 /*
1512 * it might be stopped, or finished, decide:
1513 */
1514 int state = done ? JOBDONE : JOBSTOPPED;
1515
1516 /*
1517 * If that wasn't the same as it was before
1518 * then update its state, and if it just
1519 * completed, make it be the current job (%%)
1520 */
1521 if (jp->state != state) {
1522 VTRACE(DBG_JOBS,
1523 ("Job %d: changing state from %d to %d\n",
1524 jp - jobtab + 1, jp->state, state));
1525 jp->state = state;
1526 #if JOBS
1527 if (done)
1528 set_curjob(jp, 0);
1529 #endif
1530 }
1531 }
1532 }
1533 }
1534
1535 /*
1536 * Now we have scanned all jobs. If we found the job that
1537 * the process that changed state belonged to (we occasionally
1538 * fork processes without associating them with a job, when one
1539 * of those finishes, we simply ignore it, the zombie has been
1540 * cleaned up, which is all that matters) then we need to
1541 * determine if we should say something about it to stdout
1542 */
1543
1544 if (thisjob &&
1545 (thisjob->state != JOBRUNNING || thisjob->flags & JOBCHANGED)) {
1546 int mode = 0;
1547
1548 if (!rootshell || !iflag)
1549 mode = SHOW_SIGNALLED;
1550 if ((job == thisjob && (flags & WNOFREE) == 0) ||
1551 job != thisjob)
1552 mode = SHOW_SIGNALLED | SHOW_NO_FREE;
1553 if (mode && (flags & WSILENT) == 0)
1554 showjob(out2, thisjob, mode);
1555 else {
1556 VTRACE(DBG_JOBS,
1557 ("Not printing status for %p [%d], "
1558 "mode=%#x rootshell=%d, job=%p [%d]\n",
1559 thisjob, (thisjob ? (thisjob-jobtab+1) : 0),
1560 mode, rootshell, job, (job ? (job-jobtab+1) : 0)));
1561 thisjob->flags |= JOBCHANGED;
1562 }
1563 }
1564
1565 INTON;
1566 /*
1567 * Finally tell our caller that something happened (in general all
1568 * anyone tests for is <= 0 (or >0) so the actual pid value here
1569 * doesn't matter much, but we know it is >0 and we may as well
1570 * give back something meaningful
1571 */
1572 return pid;
1573 }
1574
1575
1576
1577 /*
1578 * Do a wait system call. If job control is compiled in, we accept
1579 * stopped processes. If block is zero, we return a value of zero
1580 * rather than blocking.
1581 *
1582 * System V doesn't have a non-blocking wait system call. It does
1583 * have a SIGCLD signal that is sent to a process when one of its
1584 * children dies. The obvious way to use SIGCLD would be to install
1585 * a handler for SIGCLD which simply bumped a counter when a SIGCLD
1586 * was received, and have waitproc bump another counter when it got
1587 * the status of a process. Waitproc would then know that a wait
1588 * system call would not block if the two counters were different.
1589 * This approach doesn't work because if a process has children that
1590 * have not been waited for, System V will send it a SIGCLD when it
1591 * installs a signal handler for SIGCLD. What this means is that when
1592 * a child exits, the shell will be sent SIGCLD signals continuously
1593 * until is runs out of stack space, unless it does a wait call before
1594 * restoring the signal handler. The code below takes advantage of
1595 * this (mis)feature by installing a signal handler for SIGCLD and
1596 * then checking to see whether it was called. If there are any
1597 * children to be waited for, it will be.
1598 *
1599 * If neither SYSV nor BSD is defined, we don't implement nonblocking
1600 * waits at all. In this case, the user will not be informed when
1601 * a background process until the next time she runs a real program
1602 * (as opposed to running a builtin command or just typing return),
1603 * and the jobs command may give out of date information.
1604 */
1605
1606 #ifdef SYSV
1607 STATIC int gotsigchild;
1608
1609 STATIC int onsigchild() {
1610 gotsigchild = 1;
1611 }
1612 #endif
1613
1614
1615 STATIC int
1616 waitproc(int block, struct job *jp, int *status)
1617 {
1618 #ifdef BSD
1619 int flags = 0;
1620
1621 #if JOBS
1622 if (mflag || (jp != NULL && jp->jobctl))
1623 flags |= WUNTRACED | WCONTINUED;
1624 #endif
1625 if (block == 0)
1626 flags |= WNOHANG;
1627 VTRACE(DBG_WAIT, ("waitproc: doing waitpid(flags=%#x)\n", flags));
1628 return waitpid(-1, status, flags);
1629 #else
1630 #ifdef SYSV
1631 int (*save)();
1632
1633 if (block == 0) {
1634 gotsigchild = 0;
1635 save = signal(SIGCLD, onsigchild);
1636 signal(SIGCLD, save);
1637 if (gotsigchild == 0)
1638 return 0;
1639 }
1640 return wait(status);
1641 #else
1642 if (block == 0)
1643 return 0;
1644 return wait(status);
1645 #endif
1646 #endif
1647 }
1648
1649 /*
1650 * return 1 if there are stopped jobs, otherwise 0
1651 */
1652 int job_warning = 0;
1653 int
1654 stoppedjobs(void)
1655 {
1656 int jobno;
1657 struct job *jp;
1658
1659 if (job_warning || jobs_invalid)
1660 return (0);
1661 for (jobno = 1, jp = jobtab; jobno <= njobs; jobno++, jp++) {
1662 if (jp->used == 0)
1663 continue;
1664 if (jp->state == JOBSTOPPED) {
1665 out2str("You have stopped jobs.\n");
1666 job_warning = 2;
1667 return (1);
1668 }
1669 }
1670
1671 return (0);
1672 }
1673
1674 /*
1675 * Return a string identifying a command (to be printed by the
1676 * jobs command).
1677 */
1678
1679 STATIC char *cmdnextc;
1680 STATIC int cmdnleft;
1681
1682 void
1683 commandtext(struct procstat *ps, union node *n)
1684 {
1685 int len;
1686
1687 cmdnextc = ps->cmd;
1688 if (iflag || mflag || sizeof(ps->cmd) <= 60)
1689 len = sizeof(ps->cmd);
1690 else if (sizeof ps->cmd <= 400)
1691 len = 50;
1692 else if (sizeof ps->cmd <= 800)
1693 len = 80;
1694 else
1695 len = sizeof(ps->cmd) / 10;
1696 cmdnleft = len;
1697 cmdtxt(n);
1698 if (cmdnleft <= 0) {
1699 char *p = ps->cmd + len - 4;
1700 p[0] = '.';
1701 p[1] = '.';
1702 p[2] = '.';
1703 p[3] = 0;
1704 } else
1705 *cmdnextc = '\0';
1706
1707 VTRACE(DBG_JOBS,
1708 ("commandtext: ps->cmd %p, end %p, left %d\n\t\"%s\"\n",
1709 ps->cmd, cmdnextc, cmdnleft, ps->cmd));
1710 }
1711
1712
1713 STATIC void
1714 cmdtxt(union node *n)
1715 {
1716 union node *np;
1717 struct nodelist *lp;
1718 const char *p;
1719 int i;
1720
1721 if (n == NULL || cmdnleft <= 0)
1722 return;
1723 switch (n->type) {
1724 case NSEMI:
1725 cmdtxt(n->nbinary.ch1);
1726 cmdputs("; ");
1727 cmdtxt(n->nbinary.ch2);
1728 break;
1729 case NAND:
1730 cmdtxt(n->nbinary.ch1);
1731 cmdputs(" && ");
1732 cmdtxt(n->nbinary.ch2);
1733 break;
1734 case NOR:
1735 cmdtxt(n->nbinary.ch1);
1736 cmdputs(" || ");
1737 cmdtxt(n->nbinary.ch2);
1738 break;
1739 case NDNOT:
1740 cmdputs("! ");
1741 /* FALLTHROUGH */
1742 case NNOT:
1743 cmdputs("! ");
1744 cmdtxt(n->nnot.com);
1745 break;
1746 case NPIPE:
1747 for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) {
1748 cmdtxt(lp->n);
1749 if (lp->next)
1750 cmdputs(" | ");
1751 }
1752 if (n->npipe.backgnd)
1753 cmdputs(" &");
1754 break;
1755 case NSUBSHELL:
1756 cmdputs("(");
1757 cmdtxt(n->nredir.n);
1758 cmdputs(")");
1759 break;
1760 case NREDIR:
1761 case NBACKGND:
1762 cmdtxt(n->nredir.n);
1763 break;
1764 case NIF:
1765 cmdputs("if ");
1766 cmdtxt(n->nif.test);
1767 cmdputs("; then ");
1768 cmdtxt(n->nif.ifpart);
1769 if (n->nif.elsepart) {
1770 cmdputs("; else ");
1771 cmdtxt(n->nif.elsepart);
1772 }
1773 cmdputs("; fi");
1774 break;
1775 case NWHILE:
1776 cmdputs("while ");
1777 goto until;
1778 case NUNTIL:
1779 cmdputs("until ");
1780 until:
1781 cmdtxt(n->nbinary.ch1);
1782 cmdputs("; do ");
1783 cmdtxt(n->nbinary.ch2);
1784 cmdputs("; done");
1785 break;
1786 case NFOR:
1787 cmdputs("for ");
1788 cmdputs(n->nfor.var);
1789 cmdputs(" in ");
1790 cmdlist(n->nfor.args, 1);
1791 cmdputs("; do ");
1792 cmdtxt(n->nfor.body);
1793 cmdputs("; done");
1794 break;
1795 case NCASE:
1796 cmdputs("case ");
1797 cmdputs(n->ncase.expr->narg.text);
1798 cmdputs(" in ");
1799 for (np = n->ncase.cases; np; np = np->nclist.next) {
1800 cmdtxt(np->nclist.pattern);
1801 cmdputs(") ");
1802 cmdtxt(np->nclist.body);
1803 switch (n->type) { /* switch (not if) for later */
1804 case NCLISTCONT:
1805 cmdputs(";& ");
1806 break;
1807 default:
1808 cmdputs(";; ");
1809 break;
1810 }
1811 }
1812 cmdputs("esac");
1813 break;
1814 case NDEFUN:
1815 cmdputs(n->narg.text);
1816 cmdputs("() { ... }");
1817 break;
1818 case NCMD:
1819 cmdlist(n->ncmd.args, 1);
1820 cmdlist(n->ncmd.redirect, 0);
1821 if (n->ncmd.backgnd)
1822 cmdputs(" &");
1823 break;
1824 case NARG:
1825 cmdputs(n->narg.text);
1826 break;
1827 case NTO:
1828 p = ">"; i = 1; goto redir;
1829 case NCLOBBER:
1830 p = ">|"; i = 1; goto redir;
1831 case NAPPEND:
1832 p = ">>"; i = 1; goto redir;
1833 case NTOFD:
1834 p = ">&"; i = 1; goto redir;
1835 case NFROM:
1836 p = "<"; i = 0; goto redir;
1837 case NFROMFD:
1838 p = "<&"; i = 0; goto redir;
1839 case NFROMTO:
1840 p = "<>"; i = 0; goto redir;
1841 redir:
1842 if (n->nfile.fd != i)
1843 cmdputi(n->nfile.fd);
1844 cmdputs(p);
1845 if (n->type == NTOFD || n->type == NFROMFD) {
1846 if (n->ndup.dupfd < 0)
1847 cmdputs("-");
1848 else
1849 cmdputi(n->ndup.dupfd);
1850 } else {
1851 cmdtxt(n->nfile.fname);
1852 }
1853 break;
1854 case NHERE:
1855 case NXHERE:
1856 cmdputs("<<...");
1857 break;
1858 default:
1859 cmdputs("???");
1860 break;
1861 }
1862 }
1863
1864 STATIC void
1865 cmdlist(union node *np, int sep)
1866 {
1867 for (; np; np = np->narg.next) {
1868 if (!sep)
1869 cmdputs(" ");
1870 cmdtxt(np);
1871 if (sep && np->narg.next)
1872 cmdputs(" ");
1873 }
1874 }
1875
1876
1877 STATIC void
1878 cmdputs(const char *s)
1879 {
1880 const char *p, *str = 0;
1881 char c, cc[2] = " ";
1882 char *nextc;
1883 int nleft;
1884 int subtype = 0;
1885 int quoted = 0;
1886 static char vstype[16][4] = { "", "}", "-", "+", "?", "=",
1887 "#", "##", "%", "%%", "}" };
1888
1889 p = s;
1890 nextc = cmdnextc;
1891 nleft = cmdnleft;
1892 while (nleft > 0 && (c = *p++) != 0) {
1893 switch (c) {
1894 case CTLNONL:
1895 c = '\0';
1896 break;
1897 case CTLESC:
1898 c = *p++;
1899 break;
1900 case CTLVAR:
1901 subtype = *p++;
1902 if (subtype & VSLINENO) { /* undo LINENO hack */
1903 if ((subtype & VSTYPE) == VSLENGTH)
1904 str = "${#LINENO"; /*}*/
1905 else
1906 str = "${LINENO"; /*}*/
1907 while (is_digit(*p))
1908 p++;
1909 } else if ((subtype & VSTYPE) == VSLENGTH)
1910 str = "${#"; /*}*/
1911 else
1912 str = "${"; /*}*/
1913 if (!(subtype & VSQUOTE) != !(quoted & 1)) {
1914 quoted ^= 1;
1915 c = '"';
1916 } else {
1917 c = *str++;
1918 }
1919 break;
1920 case CTLENDVAR: /*{*/
1921 c = '}';
1922 if (quoted & 1)
1923 str = "\"";
1924 quoted >>= 1;
1925 subtype = 0;
1926 break;
1927 case CTLBACKQ:
1928 c = '$';
1929 str = "(...)";
1930 break;
1931 case CTLBACKQ+CTLQUOTE:
1932 c = '"';
1933 str = "$(...)\"";
1934 break;
1935 case CTLARI:
1936 c = '$';
1937 if (*p == ' ')
1938 p++;
1939 str = "(("; /*))*/
1940 break;
1941 case CTLENDARI: /*((*/
1942 c = ')';
1943 str = ")";
1944 break;
1945 case CTLQUOTEMARK:
1946 quoted ^= 1;
1947 c = '"';
1948 break;
1949 case CTLQUOTEEND:
1950 quoted >>= 1;
1951 c = '"';
1952 break;
1953 case '=':
1954 if (subtype == 0)
1955 break;
1956 str = vstype[subtype & VSTYPE];
1957 if (subtype & VSNUL)
1958 c = ':';
1959 else
1960 c = *str++; /*{*/
1961 if (c != '}')
1962 quoted <<= 1;
1963 else if (*p == CTLENDVAR)
1964 c = *str++;
1965 subtype = 0;
1966 break;
1967 case '\'':
1968 case '\\':
1969 case '"':
1970 case '$':
1971 /* These can only happen inside quotes */
1972 cc[0] = c;
1973 str = cc;
1974 c = '\\';
1975 break;
1976 default:
1977 break;
1978 }
1979 if (c != '\0') do { /* c == 0 implies nothing in str */
1980 *nextc++ = c;
1981 } while (--nleft > 0 && str && (c = *str++));
1982 str = 0;
1983 }
1984 if ((quoted & 1) && nleft) {
1985 *nextc++ = '"';
1986 nleft--;
1987 }
1988 cmdnleft = nleft;
1989 cmdnextc = nextc;
1990 }
1991