Magellan Linux

Contents of /trunk/mkinitrd-magellan/klibc/usr/dash/jobs.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1122 - (show annotations) (download)
Wed Aug 18 21:11:40 2010 UTC (13 years, 8 months ago) by niro
File MIME type: text/plain
File size: 29063 byte(s)
-updated to klibc-1.5.19
1 /*-
2 * Copyright (c) 1991, 1993
3 * The Regents of the University of California. All rights reserved.
4 * Copyright (c) 1997-2005
5 * Herbert Xu <herbert@gondor.apana.org.au>. 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 <fcntl.h>
36 #include <signal.h>
37 #include <unistd.h>
38 #include <stdlib.h>
39 #include <paths.h>
40 #include <sys/types.h>
41 #include <sys/param.h>
42 #ifdef BSD
43 #include <sys/wait.h>
44 #include <sys/time.h>
45 #include <sys/resource.h>
46 #endif
47 #include <sys/ioctl.h>
48
49 #include "shell.h"
50 #if JOBS
51 #include <termios.h>
52 #undef CEOF /* syntax.h redefines this */
53 #endif
54 #include "redir.h"
55 #include "show.h"
56 #include "main.h"
57 #include "parser.h"
58 #include "nodes.h"
59 #include "jobs.h"
60 #include "options.h"
61 #include "trap.h"
62 #include "syntax.h"
63 #include "input.h"
64 #include "output.h"
65 #include "memalloc.h"
66 #include "error.h"
67 #include "mystring.h"
68 #include "system.h"
69
70 /* mode flags for set_curjob */
71 #define CUR_DELETE 2
72 #define CUR_RUNNING 1
73 #define CUR_STOPPED 0
74
75 /* mode flags for dowait */
76 #define DOWAIT_NORMAL 0
77 #define DOWAIT_BLOCK 1
78 #define DOWAIT_WAITCMD 2
79
80 /* array of jobs */
81 static struct job *jobtab;
82 /* size of array */
83 static unsigned njobs;
84 /* pid of last background process */
85 pid_t backgndpid;
86
87 #if JOBS
88 /* pgrp of shell on invocation */
89 static int initialpgrp;
90 /* control terminal */
91 static int ttyfd = -1;
92 #endif
93
94 /* current job */
95 static struct job *curjob;
96 /* number of presumed living untracked jobs */
97 static int jobless;
98
99 STATIC void set_curjob(struct job *, unsigned);
100 STATIC int jobno(const struct job *);
101 STATIC int sprint_status(char *, int, int);
102 STATIC void freejob(struct job *);
103 STATIC struct job *getjob(const char *, int);
104 STATIC struct job *growjobtab(void);
105 STATIC void forkchild(struct job *, union node *, int);
106 STATIC void forkparent(struct job *, union node *, int, pid_t);
107 STATIC int dowait(int, struct job *);
108 #ifdef SYSV
109 STATIC int onsigchild(void);
110 #endif
111 STATIC int waitproc(int, int *);
112 STATIC char *commandtext(union node *);
113 STATIC void cmdtxt(union node *);
114 STATIC void cmdlist(union node *, int);
115 STATIC void cmdputs(const char *);
116 STATIC void showpipe(struct job *, struct output *);
117 STATIC int getstatus(struct job *);
118
119 #if JOBS
120 static int restartjob(struct job *, int);
121 static void xtcsetpgrp(int, pid_t);
122 #endif
123
124 STATIC void
125 set_curjob(struct job *jp, unsigned mode)
126 {
127 struct job *jp1;
128 struct job **jpp, **curp;
129
130 /* first remove from list */
131 jpp = curp = &curjob;
132 do {
133 jp1 = *jpp;
134 if (jp1 == jp)
135 break;
136 jpp = &jp1->prev_job;
137 } while (1);
138 *jpp = jp1->prev_job;
139
140 /* Then re-insert in correct position */
141 jpp = curp;
142 switch (mode) {
143 default:
144 #ifdef DEBUG
145 abort();
146 #endif
147 case CUR_DELETE:
148 /* job being deleted */
149 break;
150 case CUR_RUNNING:
151 /* newly created job or backgrounded job,
152 put after all stopped jobs. */
153 do {
154 jp1 = *jpp;
155 if (!JOBS || !jp1 || jp1->state != JOBSTOPPED)
156 break;
157 jpp = &jp1->prev_job;
158 } while (1);
159 /* FALLTHROUGH */
160 #if JOBS
161 case CUR_STOPPED:
162 #endif
163 /* newly stopped job - becomes curjob */
164 jp->prev_job = *jpp;
165 *jpp = jp;
166 break;
167 }
168 }
169
170 #if JOBS
171 /*
172 * Turn job control on and off.
173 *
174 * Note: This code assumes that the third arg to ioctl is a character
175 * pointer, which is true on Berkeley systems but not System V. Since
176 * System V doesn't have job control yet, this isn't a problem now.
177 *
178 * Called with interrupts off.
179 */
180
181 int jobctl;
182
183 void
184 setjobctl(int on)
185 {
186 int fd;
187 int pgrp;
188
189 if (on == jobctl || rootshell == 0)
190 return;
191 if (on) {
192 int ofd;
193 ofd = fd = open(_PATH_TTY, O_RDWR);
194 if (fd < 0) {
195 fd += 3;
196 while (!isatty(fd))
197 if (--fd < 0)
198 goto out;
199 }
200 fd = savefd(fd, ofd);
201 do { /* while we are in the background */
202 if ((pgrp = tcgetpgrp(fd)) < 0) {
203 out:
204 sh_warnx("can't access tty; job control turned off");
205 mflag = on = 0;
206 goto close;
207 }
208 if (pgrp == getpgrp())
209 break;
210 killpg(0, SIGTTIN);
211 } while (1);
212 initialpgrp = pgrp;
213
214 setsignal(SIGTSTP);
215 setsignal(SIGTTOU);
216 setsignal(SIGTTIN);
217 pgrp = rootpid;
218 setpgid(0, pgrp);
219 xtcsetpgrp(fd, pgrp);
220 } else {
221 /* turning job control off */
222 fd = ttyfd;
223 pgrp = initialpgrp;
224 xtcsetpgrp(fd, pgrp);
225 setpgid(0, pgrp);
226 setsignal(SIGTSTP);
227 setsignal(SIGTTOU);
228 setsignal(SIGTTIN);
229 close:
230 close(fd);
231 fd = -1;
232 }
233 ttyfd = fd;
234 jobctl = on;
235 }
236 #endif
237
238
239 int
240 killcmd(argc, argv)
241 int argc;
242 char **argv;
243 {
244 int signo = -1;
245 int list = 0;
246 int i;
247 pid_t pid;
248 struct job *jp;
249
250 if (argc <= 1) {
251 usage:
252 sh_error(
253 "Usage: kill [-s sigspec | -signum | -sigspec] [pid | job]... or\n"
254 "kill -l [exitstatus]"
255 );
256 }
257
258 if (**++argv == '-') {
259 signo = decode_signal(*argv + 1, 1);
260 if (signo < 0) {
261 int c;
262
263 while ((c = nextopt("ls:")) != '\0')
264 switch (c) {
265 default:
266 #ifdef DEBUG
267 abort();
268 #endif
269 case 'l':
270 list = 1;
271 break;
272 case 's':
273 signo = decode_signal(optionarg, 1);
274 if (signo < 0) {
275 sh_error(
276 "invalid signal number or name: %s",
277 optionarg
278 );
279 }
280 break;
281 }
282 argv = argptr;
283 } else
284 argv++;
285 }
286
287 if (!list && signo < 0)
288 signo = SIGTERM;
289
290 if ((signo < 0 || !*argv) ^ list) {
291 goto usage;
292 }
293
294 if (list) {
295 struct output *out;
296
297 out = out1;
298 if (!*argv) {
299 outstr("0\n", out);
300 for (i = 1; i < NSIG; i++) {
301 outfmt(out, snlfmt, signal_name(i));
302 }
303 return 0;
304 }
305 signo = number(*argv);
306 if (signo > 128)
307 signo -= 128;
308 if (0 < signo && signo < NSIG)
309 outfmt(out, snlfmt, signal_name(signo));
310 else
311 sh_error("invalid signal number or exit status: %s",
312 *argv);
313 return 0;
314 }
315
316 i = 0;
317 do {
318 if (**argv == '%') {
319 jp = getjob(*argv, 0);
320 pid = -jp->ps[0].pid;
321 } else
322 pid = **argv == '-' ?
323 -number(*argv + 1) : number(*argv);
324 if (kill(pid, signo) != 0) {
325 sh_warnx("%s\n", strerror(errno));
326 i = 1;
327 }
328 } while (*++argv);
329
330 return i;
331 }
332
333 STATIC int
334 jobno(const struct job *jp)
335 {
336 return jp - jobtab + 1;
337 }
338
339 #if JOBS
340 int
341 fgcmd(int argc, char **argv)
342 {
343 struct job *jp;
344 struct output *out;
345 int mode;
346 int retval;
347
348 mode = (**argv == 'f') ? FORK_FG : FORK_BG;
349 nextopt(nullstr);
350 argv = argptr;
351 out = out1;
352 do {
353 jp = getjob(*argv, 1);
354 if (mode == FORK_BG) {
355 set_curjob(jp, CUR_RUNNING);
356 outfmt(out, "[%d] ", jobno(jp));
357 }
358 outstr(jp->ps->cmd, out);
359 showpipe(jp, out);
360 retval = restartjob(jp, mode);
361 } while (*argv && *++argv);
362 return retval;
363 }
364
365 int bgcmd(int argc, char **argv)
366 #ifdef HAVE_ALIAS_ATTRIBUTE
367 __attribute__((__alias__("fgcmd")));
368 #else
369 {
370 return fgcmd(argc, argv);
371 }
372 #endif
373
374
375 STATIC int
376 restartjob(struct job *jp, int mode)
377 {
378 struct procstat *ps;
379 int i;
380 int status;
381 pid_t pgid;
382
383 INTOFF;
384 if (jp->state == JOBDONE)
385 goto out;
386 jp->state = JOBRUNNING;
387 pgid = jp->ps->pid;
388 if (mode == FORK_FG)
389 xtcsetpgrp(ttyfd, pgid);
390 killpg(pgid, SIGCONT);
391 ps = jp->ps;
392 i = jp->nprocs;
393 do {
394 if (WIFSTOPPED(ps->status)) {
395 ps->status = -1;
396 }
397 } while (ps++, --i);
398 out:
399 status = (mode == FORK_FG) ? waitforjob(jp) : 0;
400 INTON;
401 return status;
402 }
403 #endif
404
405 STATIC int
406 sprint_status(char *s, int status, int sigonly)
407 {
408 int col;
409 int st;
410
411 col = 0;
412 st = WEXITSTATUS(status);
413 if (!WIFEXITED(status)) {
414 #if JOBS
415 st = WSTOPSIG(status);
416 if (!WIFSTOPPED(status))
417 #endif
418 st = WTERMSIG(status);
419 if (sigonly) {
420 if (st == SIGINT || st == SIGPIPE)
421 goto out;
422 #if JOBS
423 if (WIFSTOPPED(status))
424 goto out;
425 #endif
426 }
427 col = fmtstr(s, 32, strsignal(st));
428 if (WCOREDUMP(status)) {
429 col += fmtstr(s + col, 16, " (core dumped)");
430 }
431 } else if (!sigonly) {
432 if (st)
433 col = fmtstr(s, 16, "Done(%d)", st);
434 else
435 col = fmtstr(s, 16, "Done");
436 }
437
438 out:
439 return col;
440 }
441
442 static void
443 showjob(struct output *out, struct job *jp, int mode)
444 {
445 struct procstat *ps;
446 struct procstat *psend;
447 int col;
448 int indent;
449 char s[80];
450
451 ps = jp->ps;
452
453 if (mode & SHOW_PGID) {
454 /* just output process (group) id of pipeline */
455 outfmt(out, "%d\n", ps->pid);
456 return;
457 }
458
459 col = fmtstr(s, 16, "[%d] ", jobno(jp));
460 indent = col;
461
462 if (jp == curjob)
463 s[col - 2] = '+';
464 else if (curjob && jp == curjob->prev_job)
465 s[col - 2] = '-';
466
467 if (mode & SHOW_PID)
468 col += fmtstr(s + col, 16, "%d ", ps->pid);
469
470 psend = ps + jp->nprocs;
471
472 if (jp->state == JOBRUNNING) {
473 scopy("Running", s + col);
474 col += strlen("Running");
475 } else {
476 int status = psend[-1].status;
477 #if JOBS
478 if (jp->state == JOBSTOPPED)
479 status = jp->stopstatus;
480 #endif
481 col += sprint_status(s + col, status, 0);
482 }
483
484 goto start;
485
486 do {
487 /* for each process */
488 col = fmtstr(s, 48, " |\n%*c%d ", indent, ' ', ps->pid) - 3;
489
490 start:
491 outfmt(
492 out, "%s%*c%s",
493 s, 33 - col >= 0 ? 33 - col : 0, ' ', ps->cmd
494 );
495 if (!(mode & SHOW_PID)) {
496 showpipe(jp, out);
497 break;
498 }
499 if (++ps == psend) {
500 outcslow('\n', out);
501 break;
502 }
503 } while (1);
504
505 jp->changed = 0;
506
507 if (jp->state == JOBDONE) {
508 TRACE(("showjob: freeing job %d\n", jobno(jp)));
509 freejob(jp);
510 }
511 }
512
513
514 int
515 jobscmd(int argc, char **argv)
516 {
517 int mode, m;
518 struct output *out;
519
520 mode = 0;
521 while ((m = nextopt("lp")))
522 if (m == 'l')
523 mode = SHOW_PID;
524 else
525 mode = SHOW_PGID;
526
527 out = out1;
528 argv = argptr;
529 if (*argv)
530 do
531 showjob(out, getjob(*argv,0), mode);
532 while (*++argv);
533 else
534 showjobs(out, mode);
535
536 return 0;
537 }
538
539
540 /*
541 * Print a list of jobs. If "change" is nonzero, only print jobs whose
542 * statuses have changed since the last call to showjobs.
543 */
544
545 void
546 showjobs(struct output *out, int mode)
547 {
548 struct job *jp;
549
550 TRACE(("showjobs(%x) called\n", mode));
551
552 /* If not even one one job changed, there is nothing to do */
553 while (dowait(DOWAIT_NORMAL, NULL) > 0)
554 continue;
555
556 for (jp = curjob; jp; jp = jp->prev_job) {
557 if (!(mode & SHOW_CHANGED) || jp->changed)
558 showjob(out, jp, mode);
559 }
560 }
561
562 /*
563 * Mark a job structure as unused.
564 */
565
566 STATIC void
567 freejob(struct job *jp)
568 {
569 struct procstat *ps;
570 int i;
571
572 INTOFF;
573 for (i = jp->nprocs, ps = jp->ps ; --i >= 0 ; ps++) {
574 if (ps->cmd != nullstr)
575 ckfree(ps->cmd);
576 }
577 if (jp->ps != &jp->ps0)
578 ckfree(jp->ps);
579 jp->used = 0;
580 set_curjob(jp, CUR_DELETE);
581 INTON;
582 }
583
584
585
586 int
587 waitcmd(int argc, char **argv)
588 {
589 struct job *job;
590 int retval;
591 struct job *jp;
592
593 nextopt(nullstr);
594 retval = 0;
595
596 argv = argptr;
597 if (!*argv) {
598 /* wait for all jobs */
599 for (;;) {
600 jp = curjob;
601 while (1) {
602 if (!jp) {
603 /* no running procs */
604 goto out;
605 }
606 if (jp->state == JOBRUNNING)
607 break;
608 jp->waited = 1;
609 jp = jp->prev_job;
610 }
611 if (dowait(DOWAIT_WAITCMD, 0) <= 0)
612 goto sigout;
613 }
614 }
615
616 retval = 127;
617 do {
618 if (**argv != '%') {
619 pid_t pid = number(*argv);
620 job = curjob;
621 goto start;
622 do {
623 if (job->ps[job->nprocs - 1].pid == pid)
624 break;
625 job = job->prev_job;
626 start:
627 if (!job)
628 goto repeat;
629 } while (1);
630 } else
631 job = getjob(*argv, 0);
632 /* loop until process terminated or stopped */
633 while (job->state == JOBRUNNING)
634 if (dowait(DOWAIT_WAITCMD, 0) <= 0)
635 goto sigout;
636 job->waited = 1;
637 retval = getstatus(job);
638 repeat:
639 ;
640 } while (*++argv);
641
642 out:
643 return retval;
644
645 sigout:
646 retval = 128 + pendingsigs;
647 goto out;
648 }
649
650
651
652 /*
653 * Convert a job name to a job structure.
654 */
655
656 STATIC struct job *
657 getjob(const char *name, int getctl)
658 {
659 struct job *jp;
660 struct job *found;
661 const char *err_msg = "No such job: %s";
662 unsigned num;
663 int c;
664 const char *p;
665 char *(*match)(const char *, const char *);
666
667 jp = curjob;
668 p = name;
669 if (!p)
670 goto currentjob;
671
672 if (*p != '%')
673 goto err;
674
675 c = *++p;
676 if (!c)
677 goto currentjob;
678
679 if (!p[1]) {
680 if (c == '+' || c == '%') {
681 currentjob:
682 err_msg = "No current job";
683 goto check;
684 } else if (c == '-') {
685 if (jp)
686 jp = jp->prev_job;
687 err_msg = "No previous job";
688 check:
689 if (!jp)
690 goto err;
691 goto gotit;
692 }
693 }
694
695 if (is_number(p)) {
696 num = atoi(p);
697 if (num < njobs) {
698 jp = jobtab + num - 1;
699 if (jp->used)
700 goto gotit;
701 goto err;
702 }
703 }
704
705 match = prefix;
706 if (*p == '?') {
707 match = strstr;
708 p++;
709 }
710
711 found = 0;
712 while (1) {
713 if (!jp)
714 goto err;
715 if (match(jp->ps[0].cmd, p)) {
716 if (found)
717 goto err;
718 found = jp;
719 err_msg = "%s: ambiguous";
720 }
721 jp = jp->prev_job;
722 }
723
724 gotit:
725 #if JOBS
726 err_msg = "job %s not created under job control";
727 if (getctl && jp->jobctl == 0)
728 goto err;
729 #endif
730 return jp;
731 err:
732 sh_error(err_msg, name);
733 }
734
735
736
737 /*
738 * Return a new job structure.
739 * Called with interrupts off.
740 */
741
742 struct job *
743 makejob(union node *node, int nprocs)
744 {
745 int i;
746 struct job *jp;
747
748 for (i = njobs, jp = jobtab ; ; jp++) {
749 if (--i < 0) {
750 jp = growjobtab();
751 break;
752 }
753 if (jp->used == 0)
754 break;
755 if (jp->state != JOBDONE || !jp->waited)
756 continue;
757 if (jobctl)
758 continue;
759 freejob(jp);
760 break;
761 }
762 memset(jp, 0, sizeof(*jp));
763 #if JOBS
764 if (jobctl)
765 jp->jobctl = 1;
766 #endif
767 jp->prev_job = curjob;
768 curjob = jp;
769 jp->used = 1;
770 jp->ps = &jp->ps0;
771 if (nprocs > 1) {
772 jp->ps = ckmalloc(nprocs * sizeof (struct procstat));
773 }
774 TRACE(("makejob(0x%lx, %d) returns %%%d\n", (long)node, nprocs,
775 jobno(jp)));
776 return jp;
777 }
778
779 STATIC struct job *
780 growjobtab(void)
781 {
782 size_t len;
783 ptrdiff_t offset;
784 struct job *jp, *jq;
785
786 len = njobs * sizeof(*jp);
787 jq = jobtab;
788 jp = ckrealloc(jq, len + 4 * sizeof(*jp));
789
790 offset = (char *)jp - (char *)jq;
791 if (offset) {
792 /* Relocate pointers */
793 size_t l = len;
794
795 jq = (struct job *)((char *)jq + l);
796 while (l) {
797 l -= sizeof(*jp);
798 jq--;
799 #define joff(p) ((struct job *)((char *)(p) + l))
800 #define jmove(p) (p) = (void *)((char *)(p) + offset)
801 if (likely(joff(jp)->ps == &jq->ps0))
802 jmove(joff(jp)->ps);
803 if (joff(jp)->prev_job)
804 jmove(joff(jp)->prev_job);
805 }
806 if (curjob)
807 jmove(curjob);
808 #undef joff
809 #undef jmove
810 }
811
812 njobs += 4;
813 jobtab = jp;
814 jp = (struct job *)((char *)jp + len);
815 jq = jp + 3;
816 do {
817 jq->used = 0;
818 } while (--jq >= jp);
819 return jp;
820 }
821
822
823 /*
824 * Fork off a subshell. If we are doing job control, give the subshell its
825 * own process group. Jp is a job structure that the job is to be added to.
826 * N is the command that will be evaluated by the child. Both jp and n may
827 * be NULL. The mode parameter can be one of the following:
828 * FORK_FG - Fork off a foreground process.
829 * FORK_BG - Fork off a background process.
830 * FORK_NOJOB - Like FORK_FG, but don't give the process its own
831 * process group even if job control is on.
832 *
833 * When job control is turned off, background processes have their standard
834 * input redirected to /dev/null (except for the second and later processes
835 * in a pipeline).
836 *
837 * Called with interrupts off.
838 */
839
840 STATIC inline void
841 forkchild(struct job *jp, union node *n, int mode)
842 {
843 int oldlvl;
844
845 TRACE(("Child shell %d\n", getpid()));
846 oldlvl = shlvl;
847 shlvl++;
848
849 closescript();
850 clear_traps();
851 #if JOBS
852 /* do job control only in root shell */
853 jobctl = 0;
854 if (mode != FORK_NOJOB && jp->jobctl && !oldlvl) {
855 pid_t pgrp;
856
857 if (jp->nprocs == 0)
858 pgrp = getpid();
859 else
860 pgrp = jp->ps[0].pid;
861 /* This can fail because we are doing it in the parent also */
862 (void)setpgid(0, pgrp);
863 if (mode == FORK_FG)
864 xtcsetpgrp(ttyfd, pgrp);
865 setsignal(SIGTSTP);
866 setsignal(SIGTTOU);
867 } else
868 #endif
869 if (mode == FORK_BG) {
870 ignoresig(SIGINT);
871 ignoresig(SIGQUIT);
872 if (jp->nprocs == 0) {
873 close(0);
874 if (open(_PATH_DEVNULL, O_RDONLY) != 0)
875 sh_error("Can't open %s", _PATH_DEVNULL);
876 }
877 }
878 if (!oldlvl && iflag) {
879 setsignal(SIGINT);
880 setsignal(SIGQUIT);
881 setsignal(SIGTERM);
882 }
883 for (jp = curjob; jp; jp = jp->prev_job)
884 freejob(jp);
885 jobless = 0;
886 }
887
888 STATIC inline void
889 forkparent(struct job *jp, union node *n, int mode, pid_t pid)
890 {
891 TRACE(("In parent shell: child = %d\n", pid));
892 if (!jp) {
893 while (jobless && dowait(DOWAIT_NORMAL, 0) > 0);
894 jobless++;
895 return;
896 }
897 #if JOBS
898 if (mode != FORK_NOJOB && jp->jobctl) {
899 int pgrp;
900
901 if (jp->nprocs == 0)
902 pgrp = pid;
903 else
904 pgrp = jp->ps[0].pid;
905 /* This can fail because we are doing it in the child also */
906 (void)setpgid(pid, pgrp);
907 }
908 #endif
909 if (mode == FORK_BG) {
910 backgndpid = pid; /* set $! */
911 set_curjob(jp, CUR_RUNNING);
912 }
913 if (jp) {
914 struct procstat *ps = &jp->ps[jp->nprocs++];
915 ps->pid = pid;
916 ps->status = -1;
917 ps->cmd = nullstr;
918 if (jobctl && n)
919 ps->cmd = commandtext(n);
920 }
921 }
922
923 int
924 forkshell(struct job *jp, union node *n, int mode)
925 {
926 int pid;
927
928 TRACE(("forkshell(%%%d, %p, %d) called\n", jobno(jp), n, mode));
929 pid = fork();
930 if (pid < 0) {
931 TRACE(("Fork failed, errno=%d", errno));
932 if (jp)
933 freejob(jp);
934 sh_error("Cannot fork");
935 }
936 if (pid == 0)
937 forkchild(jp, n, mode);
938 else
939 forkparent(jp, n, mode, pid);
940 return pid;
941 }
942
943 /*
944 * Wait for job to finish.
945 *
946 * Under job control we have the problem that while a child process is
947 * running interrupts generated by the user are sent to the child but not
948 * to the shell. This means that an infinite loop started by an inter-
949 * active user may be hard to kill. With job control turned off, an
950 * interactive user may place an interactive program inside a loop. If
951 * the interactive program catches interrupts, the user doesn't want
952 * these interrupts to also abort the loop. The approach we take here
953 * is to have the shell ignore interrupt signals while waiting for a
954 * forground process to terminate, and then send itself an interrupt
955 * signal if the child process was terminated by an interrupt signal.
956 * Unfortunately, some programs want to do a bit of cleanup and then
957 * exit on interrupt; unless these processes terminate themselves by
958 * sending a signal to themselves (instead of calling exit) they will
959 * confuse this approach.
960 *
961 * Called with interrupts off.
962 */
963
964 int
965 waitforjob(struct job *jp)
966 {
967 int st;
968
969 TRACE(("waitforjob(%%%d) called\n", jobno(jp)));
970 while (jp->state == JOBRUNNING) {
971 dowait(DOWAIT_BLOCK, jp);
972 }
973 st = getstatus(jp);
974 #if JOBS
975 if (jp->jobctl) {
976 xtcsetpgrp(ttyfd, rootpid);
977 /*
978 * This is truly gross.
979 * If we're doing job control, then we did a TIOCSPGRP which
980 * caused us (the shell) to no longer be in the controlling
981 * session -- so we wouldn't have seen any ^C/SIGINT. So, we
982 * intuit from the subprocess exit status whether a SIGINT
983 * occurred, and if so interrupt ourselves. Yuck. - mycroft
984 */
985 if (jp->sigint)
986 raise(SIGINT);
987 }
988 #endif
989 if (! JOBS || jp->state == JOBDONE)
990 freejob(jp);
991 return st;
992 }
993
994
995
996 /*
997 * Wait for a process to terminate.
998 */
999
1000 STATIC int
1001 dowait(int block, struct job *job)
1002 {
1003 int pid;
1004 int status;
1005 struct job *jp;
1006 struct job *thisjob = NULL;
1007 int state;
1008
1009 INTOFF;
1010 TRACE(("dowait(%d) called\n", block));
1011 pid = waitproc(block, &status);
1012 TRACE(("wait returns pid %d, status=%d\n", pid, status));
1013 if (pid <= 0)
1014 goto out;
1015
1016 for (jp = curjob; jp; jp = jp->prev_job) {
1017 struct procstat *sp;
1018 struct procstat *spend;
1019 if (jp->state == JOBDONE)
1020 continue;
1021 state = JOBDONE;
1022 spend = jp->ps + jp->nprocs;
1023 sp = jp->ps;
1024 do {
1025 if (sp->pid == pid) {
1026 TRACE(("Job %d: changing status of proc %d from 0x%x to 0x%x\n", jobno(jp), pid, sp->status, status));
1027 sp->status = status;
1028 thisjob = jp;
1029 }
1030 if (sp->status == -1)
1031 state = JOBRUNNING;
1032 #if JOBS
1033 if (state == JOBRUNNING)
1034 continue;
1035 if (WIFSTOPPED(sp->status)) {
1036 jp->stopstatus = sp->status;
1037 state = JOBSTOPPED;
1038 }
1039 #endif
1040 } while (++sp < spend);
1041 if (thisjob)
1042 goto gotjob;
1043 }
1044 if (!JOBS || !WIFSTOPPED(status))
1045 jobless--;
1046 goto out;
1047
1048 gotjob:
1049 if (state != JOBRUNNING) {
1050 thisjob->changed = 1;
1051
1052 if (thisjob->state != state) {
1053 TRACE(("Job %d: changing state from %d to %d\n", jobno(thisjob), thisjob->state, state));
1054 thisjob->state = state;
1055 #if JOBS
1056 if (state == JOBSTOPPED) {
1057 set_curjob(thisjob, CUR_STOPPED);
1058 }
1059 #endif
1060 }
1061 }
1062
1063 out:
1064 INTON;
1065
1066 if (thisjob && thisjob == job) {
1067 char s[48 + 1];
1068 int len;
1069
1070 len = sprint_status(s, status, 1);
1071 if (len) {
1072 s[len] = '\n';
1073 s[len + 1] = 0;
1074 outstr(s, out2);
1075 }
1076 }
1077 return pid;
1078 }
1079
1080
1081
1082 /*
1083 * Do a wait system call. If job control is compiled in, we accept
1084 * stopped processes. If block is zero, we return a value of zero
1085 * rather than blocking.
1086 *
1087 * System V doesn't have a non-blocking wait system call. It does
1088 * have a SIGCLD signal that is sent to a process when one of it's
1089 * children dies. The obvious way to use SIGCLD would be to install
1090 * a handler for SIGCLD which simply bumped a counter when a SIGCLD
1091 * was received, and have waitproc bump another counter when it got
1092 * the status of a process. Waitproc would then know that a wait
1093 * system call would not block if the two counters were different.
1094 * This approach doesn't work because if a process has children that
1095 * have not been waited for, System V will send it a SIGCLD when it
1096 * installs a signal handler for SIGCLD. What this means is that when
1097 * a child exits, the shell will be sent SIGCLD signals continuously
1098 * until is runs out of stack space, unless it does a wait call before
1099 * restoring the signal handler. The code below takes advantage of
1100 * this (mis)feature by installing a signal handler for SIGCLD and
1101 * then checking to see whether it was called. If there are any
1102 * children to be waited for, it will be.
1103 *
1104 * If neither SYSV nor BSD is defined, we don't implement nonblocking
1105 * waits at all. In this case, the user will not be informed when
1106 * a background process until the next time she runs a real program
1107 * (as opposed to running a builtin command or just typing return),
1108 * and the jobs command may give out of date information.
1109 */
1110
1111 #ifdef SYSV
1112 STATIC int gotsigchild;
1113
1114 STATIC int onsigchild() {
1115 gotsigchild = 1;
1116 }
1117 #endif
1118
1119
1120 STATIC int
1121 waitproc(int block, int *status)
1122 {
1123 sigset_t mask, oldmask;
1124 int flags = block == DOWAIT_BLOCK ? 0 : WNOHANG;
1125 int err;
1126 int sig;
1127
1128 #if JOBS
1129 if (jobctl)
1130 flags |= WUNTRACED;
1131 #endif
1132
1133 do {
1134 err = wait3(status, flags, NULL);
1135 if (err || !block)
1136 break;
1137
1138 block = 0;
1139
1140 sigfillset(&mask);
1141 sigprocmask(SIG_SETMASK, &mask, &oldmask);
1142
1143 while (!(sig = pendingsigs))
1144 sigsuspend(&oldmask);
1145
1146 sigclearmask();
1147 } while (sig == SIGCHLD);
1148
1149 return err;
1150 }
1151
1152 /*
1153 * return 1 if there are stopped jobs, otherwise 0
1154 */
1155 int job_warning;
1156 int
1157 stoppedjobs(void)
1158 {
1159 struct job *jp;
1160 int retval;
1161
1162 retval = 0;
1163 if (job_warning)
1164 goto out;
1165 jp = curjob;
1166 if (jp && jp->state == JOBSTOPPED) {
1167 out2str("You have stopped jobs.\n");
1168 job_warning = 2;
1169 retval++;
1170 }
1171
1172 out:
1173 return retval;
1174 }
1175
1176 /*
1177 * Return a string identifying a command (to be printed by the
1178 * jobs command).
1179 */
1180
1181 STATIC char *cmdnextc;
1182
1183 STATIC char *
1184 commandtext(union node *n)
1185 {
1186 char *name;
1187
1188 STARTSTACKSTR(cmdnextc);
1189 cmdtxt(n);
1190 name = stackblock();
1191 TRACE(("commandtext: name %p, end %p\n\t\"%s\"\n",
1192 name, cmdnextc, ps->cmd));
1193 return savestr(name);
1194 }
1195
1196
1197 STATIC void
1198 cmdtxt(union node *n)
1199 {
1200 union node *np;
1201 struct nodelist *lp;
1202 const char *p;
1203 char s[2];
1204
1205 if (!n)
1206 return;
1207 switch (n->type) {
1208 default:
1209 #if DEBUG
1210 abort();
1211 #endif
1212 case NPIPE:
1213 lp = n->npipe.cmdlist;
1214 for (;;) {
1215 cmdtxt(lp->n);
1216 lp = lp->next;
1217 if (!lp)
1218 break;
1219 cmdputs(" | ");
1220 }
1221 break;
1222 case NSEMI:
1223 p = "; ";
1224 goto binop;
1225 case NAND:
1226 p = " && ";
1227 goto binop;
1228 case NOR:
1229 p = " || ";
1230 binop:
1231 cmdtxt(n->nbinary.ch1);
1232 cmdputs(p);
1233 n = n->nbinary.ch2;
1234 goto donode;
1235 case NREDIR:
1236 case NBACKGND:
1237 n = n->nredir.n;
1238 goto donode;
1239 case NNOT:
1240 cmdputs("!");
1241 n = n->nnot.com;
1242 donode:
1243 cmdtxt(n);
1244 break;
1245 case NIF:
1246 cmdputs("if ");
1247 cmdtxt(n->nif.test);
1248 cmdputs("; then ");
1249 if (n->nif.elsepart) {
1250 cmdtxt(n->nif.ifpart);
1251 cmdputs("; else ");
1252 n = n->nif.elsepart;
1253 } else {
1254 n = n->nif.ifpart;
1255 }
1256 p = "; fi";
1257 goto dotail;
1258 case NSUBSHELL:
1259 cmdputs("(");
1260 n = n->nredir.n;
1261 p = ")";
1262 goto dotail;
1263 case NWHILE:
1264 p = "while ";
1265 goto until;
1266 case NUNTIL:
1267 p = "until ";
1268 until:
1269 cmdputs(p);
1270 cmdtxt(n->nbinary.ch1);
1271 n = n->nbinary.ch2;
1272 p = "; done";
1273 dodo:
1274 cmdputs("; do ");
1275 dotail:
1276 cmdtxt(n);
1277 goto dotail2;
1278 case NFOR:
1279 cmdputs("for ");
1280 cmdputs(n->nfor.var);
1281 cmdputs(" in ");
1282 cmdlist(n->nfor.args, 1);
1283 n = n->nfor.body;
1284 p = "; done";
1285 goto dodo;
1286 case NDEFUN:
1287 cmdputs(n->narg.text);
1288 p = "() { ... }";
1289 goto dotail2;
1290 case NCMD:
1291 cmdlist(n->ncmd.args, 1);
1292 cmdlist(n->ncmd.redirect, 0);
1293 break;
1294 case NARG:
1295 p = n->narg.text;
1296 dotail2:
1297 cmdputs(p);
1298 break;
1299 case NHERE:
1300 case NXHERE:
1301 p = "<<...";
1302 goto dotail2;
1303 case NCASE:
1304 cmdputs("case ");
1305 cmdputs(n->ncase.expr->narg.text);
1306 cmdputs(" in ");
1307 for (np = n->ncase.cases; np; np = np->nclist.next) {
1308 cmdtxt(np->nclist.pattern);
1309 cmdputs(") ");
1310 cmdtxt(np->nclist.body);
1311 cmdputs(";; ");
1312 }
1313 p = "esac";
1314 goto dotail2;
1315 case NTO:
1316 p = ">";
1317 goto redir;
1318 case NCLOBBER:
1319 p = ">|";
1320 goto redir;
1321 case NAPPEND:
1322 p = ">>";
1323 goto redir;
1324 case NTOFD:
1325 p = ">&";
1326 goto redir;
1327 case NFROM:
1328 p = "<";
1329 goto redir;
1330 case NFROMFD:
1331 p = "<&";
1332 goto redir;
1333 case NFROMTO:
1334 p = "<>";
1335 redir:
1336 s[0] = n->nfile.fd + '0';
1337 s[1] = '\0';
1338 cmdputs(s);
1339 cmdputs(p);
1340 if (n->type == NTOFD || n->type == NFROMFD) {
1341 s[0] = n->ndup.dupfd + '0';
1342 p = s;
1343 goto dotail2;
1344 } else {
1345 n = n->nfile.fname;
1346 goto donode;
1347 }
1348 }
1349 }
1350
1351 STATIC void
1352 cmdlist(union node *np, int sep)
1353 {
1354 for (; np; np = np->narg.next) {
1355 if (!sep)
1356 cmdputs(spcstr);
1357 cmdtxt(np);
1358 if (sep && np->narg.next)
1359 cmdputs(spcstr);
1360 }
1361 }
1362
1363
1364 STATIC void
1365 cmdputs(const char *s)
1366 {
1367 const char *p, *str;
1368 char cc[2] = " ";
1369 char *nextc;
1370 signed char c;
1371 int subtype = 0;
1372 int quoted = 0;
1373 static const char vstype[VSTYPE + 1][4] = {
1374 "", "}", "-", "+", "?", "=",
1375 "%", "%%", "#", "##",
1376 };
1377
1378 nextc = makestrspace((strlen(s) + 1) * 8, cmdnextc);
1379 p = s;
1380 while ((c = *p++) != 0) {
1381 str = 0;
1382 switch (c) {
1383 case CTLESC:
1384 c = *p++;
1385 break;
1386 case CTLVAR:
1387 subtype = *p++;
1388 if ((subtype & VSTYPE) == VSLENGTH)
1389 str = "${#";
1390 else
1391 str = "${";
1392 goto dostr;
1393 case CTLENDVAR:
1394 str = "\"}" + !(quoted & 1);
1395 quoted >>= 1;
1396 subtype = 0;
1397 goto dostr;
1398 case CTLBACKQ:
1399 str = "$(...)";
1400 goto dostr;
1401 case CTLARI:
1402 str = "$((";
1403 goto dostr;
1404 case CTLENDARI:
1405 str = "))";
1406 goto dostr;
1407 case CTLQUOTEMARK:
1408 quoted ^= 1;
1409 c = '"';
1410 break;
1411 case '=':
1412 if (subtype == 0)
1413 break;
1414 if ((subtype & VSTYPE) != VSNORMAL)
1415 quoted <<= 1;
1416 str = vstype[subtype & VSTYPE];
1417 if (subtype & VSNUL)
1418 c = ':';
1419 else
1420 goto checkstr;
1421 break;
1422 case '\'':
1423 case '\\':
1424 case '"':
1425 case '$':
1426 /* These can only happen inside quotes */
1427 cc[0] = c;
1428 str = cc;
1429 c = '\\';
1430 break;
1431 default:
1432 break;
1433 }
1434 USTPUTC(c, nextc);
1435 checkstr:
1436 if (!str)
1437 continue;
1438 dostr:
1439 while ((c = *str++)) {
1440 USTPUTC(c, nextc);
1441 }
1442 }
1443 if (quoted & 1) {
1444 USTPUTC('"', nextc);
1445 }
1446 *nextc = 0;
1447 cmdnextc = nextc;
1448 }
1449
1450
1451 STATIC void
1452 showpipe(struct job *jp, struct output *out)
1453 {
1454 struct procstat *sp;
1455 struct procstat *spend;
1456
1457 spend = jp->ps + jp->nprocs;
1458 for (sp = jp->ps + 1; sp < spend; sp++)
1459 outfmt(out, " | %s", sp->cmd);
1460 outcslow('\n', out);
1461 flushall();
1462 }
1463
1464
1465 #if JOBS
1466 STATIC void
1467 xtcsetpgrp(int fd, pid_t pgrp)
1468 {
1469 if (tcsetpgrp(fd, pgrp))
1470 sh_error("Cannot set tty process group (%s)", strerror(errno));
1471 }
1472 #endif
1473
1474
1475 STATIC int
1476 getstatus(struct job *job) {
1477 int status;
1478 int retval;
1479
1480 status = job->ps[job->nprocs - 1].status;
1481 retval = WEXITSTATUS(status);
1482 if (!WIFEXITED(status)) {
1483 #if JOBS
1484 retval = WSTOPSIG(status);
1485 if (!WIFSTOPPED(status))
1486 #endif
1487 {
1488 /* XXX: limits number of signals */
1489 retval = WTERMSIG(status);
1490 #if JOBS
1491 if (retval == SIGINT)
1492 job->sigint = 1;
1493 #endif
1494 }
1495 retval += 128;
1496 }
1497 TRACE(("getstatus: job %d, nproc %d, status %x, retval %x\n",
1498 jobno(job), job->nprocs, status, retval));
1499 return retval;
1500 }