1 /*
2 * jobs.c - job control
3 *
4 * This file is part of zsh, the Z shell.
5 *
6 * Copyright (c) 1992-1997 Paul Falstad
7 * All rights reserved.
8 *
9 * Permission is hereby granted, without written agreement and without
10 * license or royalty fees, to use, copy, modify, and distribute this
11 * software and to distribute modified versions of this software for any
12 * purpose, provided that the above copyright notice and the following
13 * two paragraphs appear in all copies of this software.
14 *
15 * In no event shall Paul Falstad or the Zsh Development Group be liable
16 * to any party for direct, indirect, special, incidental, or consequential
17 * damages arising out of the use of this software and its documentation,
18 * even if Paul Falstad and the Zsh Development Group have been advised of
19 * the possibility of such damage.
20 *
21 * Paul Falstad and the Zsh Development Group specifically disclaim any
22 * warranties, including, but not limited to, the implied warranties of
23 * merchantability and fitness for a particular purpose. The software
24 * provided hereunder is on an "as is" basis, and Paul Falstad and the
25 * Zsh Development Group have no obligation to provide maintenance,
26 * support, updates, enhancements, or modifications.
27 *
28 */
29
30 #include "zsh.mdh"
31 #include "jobs.pro"
32
33 /*
34 * Job control in zsh
35 * ==================
36 *
37 * A 'job' represents a pipeline; see the section JOBS in zshmisc(1)) for an
38 * introduction. The 'struct job's are allocated in the array 'jobtab' which
39 * has 'jobtabsize' elements. The job whose processes we are currently
40 * preparing to execute is identified by the global variable 'thisjob'.
41 *
42 * A 'superjob' is a job that represents a complex shell construct that has been
43 * backgrounded. For example, if one runs '() { vi; echo }', a job is created
44 * for the pipeline 'vi'. If one then backgrounds vi (with ^Z / SIGTSTP),
45 * the shell forks; the parent shell returns to the interactive prompt and
46 * the child shell becomes a new job in the parent shell. The job representing
47 * the child shell to the parent shell is a superjob (STAT_SUPERJOB); the 'vi'
48 * job is marked as a subjob (STAT_SUBJOB) in the parent shell. When the child
49 * shell is resumed (with fg / SIGCONT), it forwards the signal to vi and,
50 * after vi exits, continues executing the remainder of the function.
51 * (See workers/43565.)
52 */
53
54 /* the process group of the shell at startup (equal to mypgprp, except
55 when we started without being process group leader */
56
57 /**/
58 mod_export pid_t origpgrp;
59
60 /* the process group of the shell */
61
62 /**/
63 mod_export pid_t mypgrp;
64
65 /* the last process group to attach to the terminal */
66
67 /**/
68 pid_t last_attached_pgrp;
69
70 /* the job we are working on, or -1 if none */
71
72 /**/
73 mod_export int thisjob;
74
75 /* the current job (%+) */
76
77 /**/
78 mod_export int curjob;
79
80 /* the previous job (%-) */
81
82 /**/
83 mod_export int prevjob;
84
85 /* the job table */
86
87 /**/
88 mod_export struct job *jobtab;
89
90 /* Size of the job table. */
91
92 /**/
93 mod_export int jobtabsize;
94
95 /* The highest numbered job in the jobtable */
96
97 /**/
98 mod_export int maxjob;
99
100 /* If we have entered a subshell, the original shell's job table. */
101 static struct job *oldjobtab;
102
103 /* The size of that. */
104 static int oldmaxjob;
105
106 /* shell timings */
107
108 /**/
109 #ifdef HAVE_GETRUSAGE
110 /**/
111 static struct rusage child_usage;
112 /**/
113 #else
114 /**/
115 static struct tms shtms;
116 /**/
117 #endif
118
119 /* 1 if ttyctl -f has been executed */
120
121 /**/
122 mod_export int ttyfrozen;
123
124 /* Previous values of errflag and breaks if the signal handler had to
125 * change them. And a flag saying if it did that. */
126
127 /**/
128 int prev_errflag, prev_breaks, errbrk_saved;
129
130 /**/
131 int numpipestats, pipestats[MAX_PIPESTATS];
132
133 /* Diff two timevals for elapsed-time computations */
134
135 /**/
136 static struct timeval *
dtime(struct timeval * dt,struct timeval * t1,struct timeval * t2)137 dtime(struct timeval *dt, struct timeval *t1, struct timeval *t2)
138 {
139 dt->tv_sec = t2->tv_sec - t1->tv_sec;
140 dt->tv_usec = t2->tv_usec - t1->tv_usec;
141 if (dt->tv_usec < 0) {
142 dt->tv_usec += 1000000.0;
143 dt->tv_sec -= 1.0;
144 }
145 return dt;
146 }
147
148 /* change job table entry from stopped to running */
149
150 /**/
151 void
makerunning(Job jn)152 makerunning(Job jn)
153 {
154 Process pn;
155
156 jn->stat &= ~STAT_STOPPED;
157 for (pn = jn->procs; pn; pn = pn->next) {
158 #if 0
159 if (WIFSTOPPED(pn->status) &&
160 (!(jn->stat & STAT_SUPERJOB) || pn->next))
161 pn->status = SP_RUNNING;
162 #endif
163 if (WIFSTOPPED(pn->status))
164 pn->status = SP_RUNNING;
165 }
166
167 if (jn->stat & STAT_SUPERJOB)
168 makerunning(jobtab + jn->other);
169 }
170
171 /* Find process and job associated with pid. *
172 * Return 1 if search was successful, else return 0. */
173
174 /**/
175 int
findproc(pid_t pid,Job * jptr,Process * pptr,int aux)176 findproc(pid_t pid, Job *jptr, Process *pptr, int aux)
177 {
178 Process pn;
179 int i;
180
181 *jptr = NULL;
182 *pptr = NULL;
183 for (i = 1; i <= maxjob; i++)
184 {
185 /*
186 * We are only interested in jobs with processes still
187 * marked as live. Careful in case there's an identical
188 * process number in a job we haven't quite got around
189 * to deleting.
190 */
191 if (jobtab[i].stat & STAT_DONE)
192 continue;
193
194 for (pn = aux ? jobtab[i].auxprocs : jobtab[i].procs;
195 pn; pn = pn->next)
196 {
197 /*
198 * Make sure we match a process that's still running.
199 *
200 * When a job contains two pids, one terminated pid and one
201 * running pid, then the condition (jobtab[i].stat &
202 * STAT_DONE) will not stop these pids from being candidates
203 * for the findproc result (which is supposed to be a
204 * RUNNING pid), and if the terminated pid is an identical
205 * process number for the pid identifying the running
206 * process we are trying to find (after pid number
207 * wrapping), then we need to avoid returning the terminated
208 * pid, otherwise the shell would block and wait forever for
209 * the termination of the process which pid we were supposed
210 * to return in a different job.
211 */
212 if (pn->pid == pid) {
213 *pptr = pn;
214 *jptr = jobtab + i;
215 if (pn->status == SP_RUNNING)
216 return 1;
217 }
218 }
219 }
220
221 return (*pptr && *jptr);
222 }
223
224 /* Does the given job number have any processes? */
225
226 /**/
227 int
hasprocs(int job)228 hasprocs(int job)
229 {
230 Job jn;
231
232 if (job < 0) {
233 DPUTS(1, "job number invalid in hasprocs");
234 return 0;
235 }
236 jn = jobtab + job;
237
238 return jn->procs || jn->auxprocs;
239 }
240
241 /* Find the super-job of a sub-job. */
242
243 /**/
244 static int
super_job(int sub)245 super_job(int sub)
246 {
247 int i;
248
249 for (i = 1; i <= maxjob; i++)
250 if ((jobtab[i].stat & STAT_SUPERJOB) &&
251 jobtab[i].other == sub &&
252 jobtab[i].gleader)
253 return i;
254 return 0;
255 }
256
257 /**/
258 static int
handle_sub(int job,int fg)259 handle_sub(int job, int fg)
260 {
261 /* job: superjob; sj: subjob. */
262 Job jn = jobtab + job, sj = jobtab + jn->other;
263
264 if ((sj->stat & STAT_DONE) || (!sj->procs && !sj->auxprocs)) {
265 struct process *p;
266
267 for (p = sj->procs; p; p = p->next) {
268 if (WIFSIGNALED(p->status)) {
269 if (jn->gleader != mypgrp && jn->procs->next)
270 killpg(jn->gleader, WTERMSIG(p->status));
271 else
272 kill(jn->procs->pid, WTERMSIG(p->status));
273 kill(sj->other, SIGCONT);
274 kill(sj->other, WTERMSIG(p->status));
275 break;
276 }
277 }
278 if (!p) {
279 int cp;
280
281 jn->stat &= ~STAT_SUPERJOB;
282 jn->stat |= STAT_WASSUPER;
283
284 if ((cp = ((WIFEXITED(jn->procs->status) ||
285 WIFSIGNALED(jn->procs->status)) &&
286 killpg(jn->gleader, 0) == -1))) {
287 Process p;
288 for (p = jn->procs; p->next; p = p->next);
289 jn->gleader = p->pid;
290 }
291 /* This deleted the job too early if the parent
292 shell waited for a command in a list that will
293 be executed by the sub-shell (e.g.: if we have
294 `ls|if true;then sleep 20;cat;fi' and ^Z the
295 sleep, the rest will be executed by a sub-shell,
296 but the parent shell gets notified for the
297 sleep.
298 deletejob(sj, 0); */
299 /* If this super-job contains only the sub-shell,
300 we have to attach the tty to its process group
301 now. */
302 if ((fg || thisjob == job) &&
303 (!jn->procs->next || cp || jn->procs->pid != jn->gleader))
304 attachtty(jn->gleader);
305 kill(sj->other, SIGCONT);
306 if (jn->stat & STAT_DISOWN)
307 {
308 deletejob(jn, 1);
309 }
310 }
311 curjob = jn - jobtab;
312 } else if (sj->stat & STAT_STOPPED) {
313 struct process *p;
314
315 jn->stat |= STAT_STOPPED;
316 for (p = jn->procs; p; p = p->next)
317 if (p->status == SP_RUNNING ||
318 (!WIFEXITED(p->status) && !WIFSIGNALED(p->status)))
319 p->status = sj->procs->status;
320 curjob = jn - jobtab;
321 printjob(jn, !!isset(LONGLISTJOBS), 1);
322 return 1;
323 }
324 return 0;
325 }
326
327
328 /* Get the latest usage information */
329
330 /**/
331 void
get_usage(void)332 get_usage(void)
333 {
334 #ifdef HAVE_GETRUSAGE
335 getrusage(RUSAGE_CHILDREN, &child_usage);
336 #else
337 times(&shtms);
338 #endif
339 }
340
341
342 #if !defined HAVE_WAIT3 || !defined HAVE_GETRUSAGE
343 /* Update status of process that we have just WAIT'ed for */
344
345 /**/
346 void
update_process(Process pn,int status)347 update_process(Process pn, int status)
348 {
349 struct timezone dummy_tz;
350 #ifdef HAVE_GETRUSAGE
351 struct timeval childs = child_usage.ru_stime;
352 struct timeval childu = child_usage.ru_utime;
353 #else
354 long childs = shtms.tms_cstime;
355 long childu = shtms.tms_cutime;
356 #endif
357
358 /* get time-accounting info */
359 get_usage();
360 gettimeofday(&pn->endtime, &dummy_tz); /* record time process exited */
361
362 pn->status = status; /* save the status returned by WAIT */
363 #ifdef HAVE_GETRUSAGE
364 dtime(&pn->ti.ru_stime, &childs, &child_usage.ru_stime);
365 dtime(&pn->ti.ru_utime, &childu, &child_usage.ru_utime);
366 #else
367 pn->ti.st = shtms.tms_cstime - childs; /* compute process system space time */
368 pn->ti.ut = shtms.tms_cutime - childu; /* compute process user space time */
369 #endif
370 }
371 #endif
372
373 /*
374 * Called when the current shell is behaving as if it received
375 * a interactively generated signal (sig).
376 *
377 * As we got the signal or are pretending we did, we need to pretend
378 * anything attached to a CURSH process got it, too.
379 */
380 /**/
381 void
check_cursh_sig(int sig)382 check_cursh_sig(int sig)
383 {
384 int i, j;
385
386 if (!errflag)
387 return;
388 for (i = 1; i <= maxjob; i++) {
389 if ((jobtab[i].stat & (STAT_CURSH|STAT_DONE)) ==
390 STAT_CURSH) {
391 for (j = 0; j < 2; j++) {
392 Process pn = j ? jobtab[i].auxprocs : jobtab[i].procs;
393 for (; pn; pn = pn->next) {
394 if (pn->status == SP_RUNNING) {
395 kill(pn->pid, sig);
396 }
397 }
398 }
399 }
400 }
401 }
402
403 /**/
404 void
storepipestats(Job jn,int inforeground,int fixlastval)405 storepipestats(Job jn, int inforeground, int fixlastval)
406 {
407 int i, pipefail = 0, jpipestats[MAX_PIPESTATS];
408 Process p;
409
410 for (p = jn->procs, i = 0; p && i < MAX_PIPESTATS; p = p->next, i++) {
411 jpipestats[i] = (WIFSIGNALED(p->status) ?
412 0200 | WTERMSIG(p->status) :
413 (WIFSTOPPED(p->status) ?
414 0200 | WEXITSTATUS(p->status) :
415 WEXITSTATUS(p->status)));
416 if (jpipestats[i])
417 pipefail = jpipestats[i];
418 }
419 if (inforeground) {
420 memcpy(pipestats, jpipestats, sizeof(int)*i);
421 if ((jn->stat & STAT_CURSH) && i < MAX_PIPESTATS)
422 pipestats[i++] = lastval;
423 numpipestats = i;
424 }
425
426 if (fixlastval) {
427 if (jn->stat & STAT_CURSH) {
428 if (!lastval && isset(PIPEFAIL))
429 lastval = pipefail;
430 } else if (isset(PIPEFAIL))
431 lastval = pipefail;
432 }
433 }
434
435 /* Update status of job, possibly printing it */
436
437 /**/
438 void
update_job(Job jn)439 update_job(Job jn)
440 {
441 Process pn;
442 int job;
443 int val = 0, status = 0;
444 int somestopped = 0, inforeground = 0;
445
446 for (pn = jn->auxprocs; pn; pn = pn->next) {
447 #ifdef WIFCONTINUED
448 if (WIFCONTINUED(pn->status))
449 pn->status = SP_RUNNING;
450 #endif
451 if (pn->status == SP_RUNNING)
452 return;
453 }
454
455 for (pn = jn->procs; pn; pn = pn->next) {
456 #ifdef WIFCONTINUED
457 if (WIFCONTINUED(pn->status)) {
458 jn->stat &= ~STAT_STOPPED;
459 pn->status = SP_RUNNING;
460 }
461 #endif
462 if (pn->status == SP_RUNNING) /* some processes in this job are running */
463 return; /* so no need to update job table entry */
464 if (WIFSTOPPED(pn->status)) /* some processes are stopped */
465 somestopped = 1; /* so job is not done, but entry needs updating */
466 if (!pn->next) /* last job in pipeline determines exit status */
467 val = (WIFSIGNALED(pn->status) ?
468 0200 | WTERMSIG(pn->status) :
469 (WIFSTOPPED(pn->status) ?
470 0200 | WEXITSTATUS(pn->status) :
471 WEXITSTATUS(pn->status)));
472 if (pn->pid == jn->gleader) /* if this process is process group leader */
473 status = pn->status;
474 }
475
476 job = jn - jobtab; /* compute job number */
477
478 if (somestopped) {
479 if (jn->stty_in_env && !jn->ty) {
480 jn->ty = (struct ttyinfo *) zalloc(sizeof(struct ttyinfo));
481 gettyinfo(jn->ty);
482 }
483 if (jn->stat & STAT_SUBJOB) {
484 /* If we have `cat foo|while read a; grep $a bar;done'
485 * and have hit ^Z, the sub-job is stopped, but the
486 * super-job may still be running, waiting to be stopped
487 * or to exit. So we have to send it a SIGTSTP. */
488 int i;
489
490 jn->stat |= STAT_CHANGED | STAT_STOPPED;
491 if ((i = super_job(job))) {
492 Job sjn = &jobtab[i];
493 killpg(sjn->gleader, SIGTSTP);
494 /*
495 * Job may already be stopped if it consists of only the
496 * forked shell waiting for the subjob -- so mark as
497 * stopped immediately. This ensures we send it (and,
498 * crucially, the subjob, as the visible job used with
499 * fg/bg is the superjob) a SIGCONT if we need it.
500 */
501 sjn->stat |= STAT_CHANGED | STAT_STOPPED;
502 if (isset(NOTIFY) && (sjn->stat & STAT_LOCKED) &&
503 !(sjn->stat & STAT_NOPRINT)) {
504 /*
505 * Print the subjob state, which we don't usually
506 * do, so the user knows something has stopped.
507 * So as not to be confusing, we actually output
508 * the user-visible superjob.
509 */
510 if (printjob(sjn, !!isset(LONGLISTJOBS), 0) &&
511 zleactive)
512 zleentry(ZLE_CMD_REFRESH);
513 }
514 }
515 return;
516 }
517 if (jn->stat & STAT_STOPPED)
518 return;
519 }
520 { /* job is done or stopped, remember return value */
521 lastval2 = val;
522 /* If last process was run in the current shell, keep old status
523 * and let it handle its own traps, but always allow the test
524 * for the pgrp.
525 */
526 if (jn->stat & STAT_CURSH)
527 inforeground = 1;
528 else if (job == thisjob) {
529 lastval = val;
530 inforeground = 2;
531 }
532 }
533
534 if (shout && shout != stderr && !ttyfrozen && !jn->stty_in_env &&
535 !zleactive && job == thisjob && !somestopped &&
536 !(jn->stat & STAT_NOSTTY))
537 gettyinfo(&shttyinfo);
538
539 if (isset(MONITOR)) {
540 pid_t pgrp = gettygrp(); /* get process group of tty */
541
542 /* is this job in the foreground of an interactive shell? */
543 if (mypgrp != pgrp && inforeground &&
544 (jn->gleader == pgrp || (pgrp > 1 && kill(-pgrp, 0) == -1))) {
545 if (list_pipe) {
546 if (somestopped || (pgrp > 1 && kill(-pgrp, 0) == -1)) {
547 attachtty(mypgrp);
548 /* check window size and adjust if necessary */
549 adjustwinsize(0);
550 } else {
551 /*
552 * Oh, dear, we're right in the middle of some confusion
553 * of shell jobs on the righthand side of a pipeline, so
554 * it's death to call attachtty() just yet. Mark the
555 * fact in the job, so that the attachtty() will be called
556 * when the job is finally deleted.
557 */
558 jn->stat |= STAT_ATTACH;
559 }
560 /* If we have `foo|while true; (( x++ )); done', and hit
561 * ^C, we have to stop the loop, too. */
562 if ((val & 0200) && inforeground == 1 &&
563 ((val & ~0200) == SIGINT || (val & ~0200) == SIGQUIT)) {
564 if (!errbrk_saved) {
565 errbrk_saved = 1;
566 prev_breaks = breaks;
567 prev_errflag = errflag;
568 }
569 breaks = loops;
570 errflag |= ERRFLAG_INT;
571 inerrflush();
572 }
573 } else {
574 attachtty(mypgrp);
575 /* check window size and adjust if necessary */
576 adjustwinsize(0);
577 }
578 }
579 } else if (list_pipe && (val & 0200) && inforeground == 1 &&
580 ((val & ~0200) == SIGINT || (val & ~0200) == SIGQUIT)) {
581 if (!errbrk_saved) {
582 errbrk_saved = 1;
583 prev_breaks = breaks;
584 prev_errflag = errflag;
585 }
586 breaks = loops;
587 errflag |= ERRFLAG_INT;
588 inerrflush();
589 }
590 if (somestopped && jn->stat & STAT_SUPERJOB)
591 return;
592 jn->stat |= (somestopped) ? STAT_CHANGED | STAT_STOPPED :
593 STAT_CHANGED | STAT_DONE;
594 if (jn->stat & (STAT_DONE|STAT_STOPPED)) {
595 /* This may be redundant with printjob() but note that inforeground
596 * is true here for STAT_CURSH jobs even when job != thisjob, most
597 * likely because thisjob = -1 from exec.c:execsimple() trickery.
598 * However, if we reset lastval here we break it for printjob().
599 */
600 storepipestats(jn, inforeground, 0);
601 }
602 if (!inforeground &&
603 (jn->stat & (STAT_SUBJOB | STAT_DONE)) == (STAT_SUBJOB | STAT_DONE)) {
604 int su;
605
606 if ((su = super_job(jn - jobtab)))
607 handle_sub(su, 0);
608 }
609 if ((jn->stat & (STAT_DONE | STAT_STOPPED)) == STAT_STOPPED) {
610 prevjob = curjob;
611 curjob = job;
612 }
613 if ((isset(NOTIFY) || job == thisjob) && (jn->stat & STAT_LOCKED)) {
614 if (printjob(jn, !!isset(LONGLISTJOBS), 0) &&
615 zleactive)
616 zleentry(ZLE_CMD_REFRESH);
617 }
618 if (sigtrapped[SIGCHLD] && job != thisjob)
619 dotrap(SIGCHLD);
620
621 /* When MONITOR is set, the foreground process runs in a different *
622 * process group from the shell, so the shell will not receive *
623 * terminal signals, therefore we pretend that the shell got *
624 * the signal too. */
625 if (inforeground == 2 && isset(MONITOR) && WIFSIGNALED(status)) {
626 int sig = WTERMSIG(status);
627
628 if (sig == SIGINT || sig == SIGQUIT) {
629 if (sigtrapped[sig]) {
630 dotrap(sig);
631 /* We keep the errflag as set or not by dotrap.
632 * This is to fulfil the promise to carry on
633 * with the jobs if trap returns zero.
634 * Setting breaks = loops ensures a consistent return
635 * status if inside a loop. Maybe the code in loops
636 * should be changed.
637 */
638 if (errflag)
639 breaks = loops;
640 } else {
641 breaks = loops;
642 errflag |= ERRFLAG_INT;
643 }
644 check_cursh_sig(sig);
645 }
646 }
647 }
648
649 /* set the previous job to something reasonable */
650
651 /**/
652 static void
setprevjob(void)653 setprevjob(void)
654 {
655 int i;
656
657 for (i = maxjob; i; i--)
658 if ((jobtab[i].stat & STAT_INUSE) && (jobtab[i].stat & STAT_STOPPED) &&
659 !(jobtab[i].stat & STAT_SUBJOB) && i != curjob && i != thisjob) {
660 prevjob = i;
661 return;
662 }
663
664 for (i = maxjob; i; i--)
665 if ((jobtab[i].stat & STAT_INUSE) && !(jobtab[i].stat & STAT_SUBJOB) &&
666 i != curjob && i != thisjob) {
667 prevjob = i;
668 return;
669 }
670
671 prevjob = -1;
672 }
673
674 /**/
675 long
get_clktck(void)676 get_clktck(void)
677 {
678 static long clktck;
679
680 #ifdef _SC_CLK_TCK
681 if (!clktck)
682 /* fetch clock ticks per second from *
683 * sysconf only the first time */
684 clktck = sysconf(_SC_CLK_TCK);
685 #else
686 # ifdef __NeXT__
687 /* NeXTStep 3.3 defines CLK_TCK wrongly */
688 clktck = 60;
689 # else
690 # ifdef CLK_TCK
691 clktck = CLK_TCK;
692 # else
693 # ifdef HZ
694 clktck = HZ;
695 # else
696 clktck = 60;
697 # endif
698 # endif
699 # endif
700 #endif
701
702 return clktck;
703 }
704
705 /**/
706 static void
printhhmmss(double secs)707 printhhmmss(double secs)
708 {
709 int mins = (int) secs / 60;
710 int hours = mins / 60;
711
712 secs -= 60 * mins;
713 mins -= 60 * hours;
714 if (hours)
715 fprintf(stderr, "%d:%02d:%05.2f", hours, mins, secs);
716 else if (mins)
717 fprintf(stderr, "%d:%05.2f", mins, secs);
718 else
719 fprintf(stderr, "%.3f", secs);
720 }
721
722 static void
printtime(struct timeval * real,child_times_t * ti,char * desc)723 printtime(struct timeval *real, child_times_t *ti, char *desc)
724 {
725 char *s;
726 double elapsed_time, user_time, system_time;
727 #ifdef HAVE_GETRUSAGE
728 double total_time;
729 #endif
730 int percent, desclen;
731
732 if (!desc)
733 {
734 desc = "";
735 desclen = 0;
736 }
737 else
738 {
739 desc = dupstring(desc);
740 unmetafy(desc, &desclen);
741 }
742
743 /* go ahead and compute these, since almost every TIMEFMT will have them */
744 elapsed_time = real->tv_sec + real->tv_usec / 1000000.0;
745
746 long clktck = get_clktck();
747 #ifdef HAVE_GETRUSAGE
748 user_time = ti->ru_utime.tv_sec + ti->ru_utime.tv_usec / 1000000.0;
749 system_time = ti->ru_stime.tv_sec + ti->ru_stime.tv_usec / 1000000.0;
750 total_time = user_time + system_time;
751 percent = 100.0 * total_time / elapsed_time;
752 total_time *= (double) clktck;
753 #else
754 {
755 user_time = ti->ut / (double) clktck;
756 system_time = ti->st / (double) clktck;
757 percent = 100.0 * (ti->ut + ti->st)
758 / (clktck * real->tv_sec + clktck * real->tv_usec / 1000000.0);
759 }
760 #endif
761
762 queue_signals();
763 if (!(s = getsparam("TIMEFMT")))
764 s = DEFAULT_TIMEFMT;
765 else
766 s = unmetafy(s, NULL);
767
768 for (; *s; s++)
769 if (*s == '%')
770 switch (*++s) {
771 case 'E':
772 fprintf(stderr, "%4.2fs", elapsed_time);
773 break;
774 case 'U':
775 fprintf(stderr, "%4.2fs", user_time);
776 break;
777 case 'S':
778 fprintf(stderr, "%4.2fs", system_time);
779 break;
780 case 'm':
781 switch (*++s) {
782 case 'E':
783 fprintf(stderr, "%0.fms", elapsed_time * 1000.0);
784 break;
785 case 'U':
786 fprintf(stderr, "%0.fms", user_time * 1000.0);
787 break;
788 case 'S':
789 fprintf(stderr, "%0.fms", system_time * 1000.0);
790 break;
791 default:
792 fprintf(stderr, "%%m");
793 s--;
794 break;
795 }
796 break;
797 case 'u':
798 switch (*++s) {
799 case 'E':
800 fprintf(stderr, "%0.fus", elapsed_time * 1000000.0);
801 break;
802 case 'U':
803 fprintf(stderr, "%0.fus", user_time * 1000000.0);
804 break;
805 case 'S':
806 fprintf(stderr, "%0.fus", system_time * 1000000.0);
807 break;
808 default:
809 fprintf(stderr, "%%u");
810 s--;
811 break;
812 }
813 break;
814 case '*':
815 switch (*++s) {
816 case 'E':
817 printhhmmss(elapsed_time);
818 break;
819 case 'U':
820 printhhmmss(user_time);
821 break;
822 case 'S':
823 printhhmmss(system_time);
824 break;
825 default:
826 fprintf(stderr, "%%*");
827 s--;
828 break;
829 }
830 break;
831 case 'P':
832 fprintf(stderr, "%d%%", percent);
833 break;
834 #ifdef HAVE_STRUCT_RUSAGE_RU_NSWAP
835 case 'W':
836 fprintf(stderr, "%ld", ti->ru_nswap);
837 break;
838 #endif
839 #ifdef HAVE_STRUCT_RUSAGE_RU_IXRSS
840 case 'X':
841 fprintf(stderr, "%ld",
842 total_time ?
843 (long)(ti->ru_ixrss / total_time) :
844 (long)0);
845 break;
846 #endif
847 #ifdef HAVE_STRUCT_RUSAGE_RU_IDRSS
848 case 'D':
849 fprintf(stderr, "%ld",
850 total_time ?
851 (long) ((ti->ru_idrss
852 #ifdef HAVE_STRUCT_RUSAGE_RU_ISRSS
853 + ti->ru_isrss
854 #endif
855 ) / total_time) :
856 (long)0);
857 break;
858 #endif
859 #if defined(HAVE_STRUCT_RUSAGE_RU_IDRSS) || \
860 defined(HAVE_STRUCT_RUSAGE_RU_ISRSS) || \
861 defined(HAVE_STRUCT_RUSAGE_RU_IXRSS)
862 case 'K':
863 /* treat as D if X not available */
864 fprintf(stderr, "%ld",
865 total_time ?
866 (long) ((
867 #ifdef HAVE_STRUCT_RUSAGE_RU_IXRSS
868 ti->ru_ixrss
869 #else
870 0
871 #endif
872 #ifdef HAVE_STRUCT_RUSAGE_RU_IDRSS
873 + ti->ru_idrss
874 #endif
875 #ifdef HAVE_STRUCT_RUSAGE_RU_ISRSS
876 + ti->ru_isrss
877 #endif
878 ) / total_time) :
879 (long)0);
880 break;
881 #endif
882 #ifdef HAVE_STRUCT_RUSAGE_RU_MAXRSS
883 case 'M':
884 fprintf(stderr, "%ld", ti->ru_maxrss);
885 break;
886 #endif
887 #ifdef HAVE_STRUCT_RUSAGE_RU_MAJFLT
888 case 'F':
889 fprintf(stderr, "%ld", ti->ru_majflt);
890 break;
891 #endif
892 #ifdef HAVE_STRUCT_RUSAGE_RU_MINFLT
893 case 'R':
894 fprintf(stderr, "%ld", ti->ru_minflt);
895 break;
896 #endif
897 #ifdef HAVE_STRUCT_RUSAGE_RU_INBLOCK
898 case 'I':
899 fprintf(stderr, "%ld", ti->ru_inblock);
900 break;
901 #endif
902 #ifdef HAVE_STRUCT_RUSAGE_RU_OUBLOCK
903 case 'O':
904 fprintf(stderr, "%ld", ti->ru_oublock);
905 break;
906 #endif
907 #ifdef HAVE_STRUCT_RUSAGE_RU_MSGRCV
908 case 'r':
909 fprintf(stderr, "%ld", ti->ru_msgrcv);
910 break;
911 #endif
912 #ifdef HAVE_STRUCT_RUSAGE_RU_MSGSND
913 case 's':
914 fprintf(stderr, "%ld", ti->ru_msgsnd);
915 break;
916 #endif
917 #ifdef HAVE_STRUCT_RUSAGE_RU_NSIGNALS
918 case 'k':
919 fprintf(stderr, "%ld", ti->ru_nsignals);
920 break;
921 #endif
922 #ifdef HAVE_STRUCT_RUSAGE_RU_NVCSW
923 case 'w':
924 fprintf(stderr, "%ld", ti->ru_nvcsw);
925 break;
926 #endif
927 #ifdef HAVE_STRUCT_RUSAGE_RU_NIVCSW
928 case 'c':
929 fprintf(stderr, "%ld", ti->ru_nivcsw);
930 break;
931 #endif
932 case 'J':
933 fwrite(desc, sizeof(char), desclen, stderr);
934 break;
935 case '%':
936 putc('%', stderr);
937 break;
938 case '\0':
939 s--;
940 break;
941 default:
942 fprintf(stderr, "%%%c", *s);
943 break;
944 } else
945 putc(*s, stderr);
946 unqueue_signals();
947 putc('\n', stderr);
948 fflush(stderr);
949 }
950
951 /**/
952 static void
dumptime(Job jn)953 dumptime(Job jn)
954 {
955 Process pn;
956 struct timeval dtimeval;
957
958 if (!jn->procs)
959 return;
960 for (pn = jn->procs; pn; pn = pn->next)
961 printtime(dtime(&dtimeval, &pn->bgtime, &pn->endtime), &pn->ti,
962 pn->text);
963 }
964
965 /* Check whether shell should report the amount of time consumed *
966 * by job. This will be the case if we have preceded the command *
967 * with the keyword time, or if REPORTTIME is non-negative and the *
968 * amount of time consumed by the job is greater than REPORTTIME */
969
970 /**/
971 static int
should_report_time(Job j)972 should_report_time(Job j)
973 {
974 struct value vbuf;
975 Value v;
976 char *s = "REPORTTIME";
977 int save_errflag = errflag;
978 zlong reporttime = -1;
979 #ifdef HAVE_GETRUSAGE
980 char *sm = "REPORTMEMORY";
981 zlong reportmemory = -1;
982 #endif
983
984 /* if the time keyword was used */
985 if (j->stat & STAT_TIMED)
986 return 1;
987
988 queue_signals();
989 errflag = 0;
990 if ((v = getvalue(&vbuf, &s, 0)))
991 reporttime = getintvalue(v);
992 #ifdef HAVE_GETRUSAGE
993 if ((v = getvalue(&vbuf, &sm, 0)))
994 reportmemory = getintvalue(v);
995 #endif
996 errflag = save_errflag;
997 unqueue_signals();
998 if (reporttime < 0
999 #ifdef HAVE_GETRUSAGE
1000 && reportmemory < 0
1001 #endif
1002 )
1003 return 0;
1004 /* can this ever happen? */
1005 if (!j->procs)
1006 return 0;
1007 if (zleactive)
1008 return 0;
1009
1010 if (reporttime >= 0)
1011 {
1012 #ifdef HAVE_GETRUSAGE
1013 reporttime -= j->procs->ti.ru_utime.tv_sec +
1014 j->procs->ti.ru_stime.tv_sec;
1015 if (j->procs->ti.ru_utime.tv_usec +
1016 j->procs->ti.ru_stime.tv_usec >= 1000000)
1017 reporttime--;
1018 if (reporttime <= 0)
1019 return 1;
1020 #else
1021 {
1022 clktck = get_clktck();
1023 if ((j->procs->ti.ut + j->procs->ti.st) / clktck >= reporttime)
1024 return 1;
1025 }
1026 #endif
1027 }
1028
1029 #ifdef HAVE_GETRUSAGE
1030 if (reportmemory >= 0 &&
1031 j->procs->ti.ru_maxrss / 1024 > reportmemory)
1032 return 1;
1033 #endif
1034
1035 return 0;
1036 }
1037
1038 /* !(lng & 3) means jobs *
1039 * (lng & 1) means jobs -l *
1040 * (lng & 2) means jobs -p
1041 * (lng & 4) means jobs -d
1042 *
1043 * synch = 0 means asynchronous
1044 * synch = 1 means synchronous
1045 * synch = 2 means called synchronously from jobs
1046 * synch = 3 means called synchronously from bg or fg
1047 *
1048 * Returns 1 if some output was done.
1049 *
1050 * The function also deletes the job if it was done, even it
1051 * is not printed.
1052 */
1053
1054 /**/
1055 int
printjob(Job jn,int lng,int synch)1056 printjob(Job jn, int lng, int synch)
1057 {
1058 Process pn;
1059 int job, len = 9, sig, sflag = 0, llen;
1060 int conted = 0, lineleng = zterm_columns, skip = 0, doputnl = 0;
1061 int doneprint = 0, skip_print = 0;
1062 FILE *fout = (synch == 2 || !shout) ? stdout : shout;
1063
1064 if (synch > 1 && oldjobtab != NULL)
1065 job = jn - oldjobtab;
1066 else
1067 job = jn - jobtab;
1068 DPUTS3(job < 0 || job > (oldjobtab && synch > 1 ? oldmaxjob : maxjob),
1069 "bogus job number, jn = %L, jobtab = %L, oldjobtab = %L",
1070 (long)jn, (long)jobtab, (long)oldjobtab);
1071
1072 if (jn->stat & STAT_NOPRINT)
1073 skip_print = 1;
1074
1075 if (lng < 0) {
1076 conted = 1;
1077 lng = !!isset(LONGLISTJOBS);
1078 }
1079
1080 if (jn->stat & STAT_SUPERJOB &&
1081 jn->other)
1082 {
1083 Job sjn = &jobtab[jn->other];
1084 if (sjn->procs || sjn->auxprocs)
1085 {
1086 /*
1087 * A subjob still has process, which must finish before
1088 * further execution of the superjob, which the user wants to
1089 * know about. So report the status of the subjob as if it
1090 * were the user-visible superjob.
1091 */
1092 jn = sjn;
1093 }
1094 }
1095
1096 /* find length of longest signame, check to see */
1097 /* if we really need to print this job */
1098
1099 for (pn = jn->procs; pn; pn = pn->next) {
1100 if (jn->stat & STAT_SUPERJOB &&
1101 jn->procs->status == SP_RUNNING && !pn->next)
1102 pn->status = SP_RUNNING;
1103 if (pn->status != SP_RUNNING) {
1104 if (WIFSIGNALED(pn->status)) {
1105 sig = WTERMSIG(pn->status);
1106 llen = strlen(sigmsg(sig));
1107 if (WCOREDUMP(pn->status))
1108 llen += 14;
1109 if (llen > len)
1110 len = llen;
1111 if (sig != SIGINT && sig != SIGPIPE)
1112 sflag = 1;
1113 if (job == thisjob && sig == SIGINT)
1114 doputnl = 1;
1115 if (isset(PRINTEXITVALUE) && isset(SHINSTDIN)) {
1116 sflag = 1;
1117 skip_print = 0;
1118 }
1119 } else if (WIFSTOPPED(pn->status)) {
1120 sig = WSTOPSIG(pn->status);
1121 if ((int)strlen(sigmsg(sig)) > len)
1122 len = strlen(sigmsg(sig));
1123 if (job == thisjob && sig == SIGTSTP)
1124 doputnl = 1;
1125 } else if (isset(PRINTEXITVALUE) && isset(SHINSTDIN) &&
1126 WEXITSTATUS(pn->status)) {
1127 sflag = 1;
1128 skip_print = 0;
1129 }
1130 }
1131 }
1132
1133 if (skip_print) {
1134 if (jn->stat & STAT_DONE) {
1135 /* This looks silly, but see update_job() */
1136 if (synch <= 1)
1137 storepipestats(jn, job == thisjob, job == thisjob);
1138 if (should_report_time(jn))
1139 dumptime(jn);
1140 deletejob(jn, 0);
1141 if (job == curjob) {
1142 curjob = prevjob;
1143 prevjob = job;
1144 }
1145 if (job == prevjob)
1146 setprevjob();
1147 }
1148 return 0;
1149 }
1150
1151 /*
1152 * - Always print if called from jobs
1153 * - Otherwise, require MONITOR option ("jobbing") and some
1154 * change of state
1155 * - also either the shell is interactive or this is synchronous.
1156 */
1157 if (synch == 2 ||
1158 ((interact || synch) && jobbing &&
1159 ((jn->stat & STAT_STOPPED) || sflag || job != thisjob))) {
1160 int len2, fline = 1;
1161 /* POSIX requires just the job text for bg and fg */
1162 int plainfmt = (synch == 3) && isset(POSIXJOBS);
1163 /* use special format for current job, except in `jobs' */
1164 int thisfmt = job == thisjob && synch != 2;
1165 Process qn;
1166
1167 if (!synch)
1168 zleentry(ZLE_CMD_TRASH);
1169 if (doputnl && !synch) {
1170 doneprint = 1;
1171 putc('\n', fout);
1172 }
1173 for (pn = jn->procs; pn;) {
1174 len2 = (thisfmt ? 5 : 10) + len; /* 2 spaces */
1175 if (lng & 3)
1176 qn = pn->next;
1177 else
1178 for (qn = pn->next; qn; qn = qn->next) {
1179 if (qn->status != pn->status)
1180 break;
1181 if ((int)strlen(qn->text) + len2 + ((qn->next) ? 3 : 0)
1182 > lineleng)
1183 break;
1184 len2 += strlen(qn->text) + 2;
1185 }
1186 doneprint = 1;
1187 if (!plainfmt) {
1188 if (!thisfmt || lng) {
1189 if (fline)
1190 fprintf(fout, "[%ld] %c ",
1191 (long)job,
1192 (job == curjob) ? '+'
1193 : (job == prevjob) ? '-' : ' ');
1194 else
1195 fprintf(fout, (job > 9) ? " " : " ");
1196 } else
1197 fprintf(fout, "zsh: ");
1198 if (lng & 1)
1199 fprintf(fout, "%ld ", (long) pn->pid);
1200 else if (lng & 2) {
1201 pid_t x = jn->gleader;
1202
1203 fprintf(fout, "%ld ", (long) x);
1204 do
1205 skip++;
1206 while ((x /= 10));
1207 skip++;
1208 lng &= ~3;
1209 } else
1210 fprintf(fout, "%*s", skip, "");
1211 if (pn->status == SP_RUNNING) {
1212 if (!conted)
1213 fprintf(fout, "running%*s", len - 7 + 2, "");
1214 else
1215 fprintf(fout, "continued%*s", len - 9 + 2, "");
1216 }
1217 else if (WIFEXITED(pn->status)) {
1218 if (WEXITSTATUS(pn->status))
1219 fprintf(fout, "exit %-4d%*s", WEXITSTATUS(pn->status),
1220 len - 9 + 2, "");
1221 else
1222 fprintf(fout, "done%*s", len - 4 + 2, "");
1223 } else if (WIFSTOPPED(pn->status))
1224 fprintf(fout, "%-*s", len + 2,
1225 sigmsg(WSTOPSIG(pn->status)));
1226 else if (WCOREDUMP(pn->status))
1227 fprintf(fout, "%s (core dumped)%*s",
1228 sigmsg(WTERMSIG(pn->status)),
1229 (int)(len - 14 + 2 -
1230 strlen(sigmsg(WTERMSIG(pn->status)))), "");
1231 else
1232 fprintf(fout, "%-*s", len + 2,
1233 sigmsg(WTERMSIG(pn->status)));
1234 }
1235 for (; pn != qn; pn = pn->next) {
1236 char *txt = dupstring(pn->text);
1237 int txtlen;
1238 unmetafy(txt, &txtlen);
1239 fwrite(txt, sizeof(char), txtlen, fout);
1240 if (pn->next)
1241 fputs(" | ", fout);
1242 }
1243 putc('\n', fout);
1244 fline = 0;
1245 }
1246 fflush(fout);
1247 } else if (doputnl && interact && !synch) {
1248 doneprint = 1;
1249 putc('\n', fout);
1250 fflush(fout);
1251 }
1252
1253 /* print "(pwd now: foo)" messages: with (lng & 4) we are printing
1254 * the directory where the job is running, otherwise the current directory
1255 */
1256
1257 if ((lng & 4) || (interact && job == thisjob &&
1258 jn->pwd && strcmp(jn->pwd, pwd))) {
1259 doneprint = 1;
1260 fprintf(fout, "(pwd %s: ", (lng & 4) ? "" : "now");
1261 fprintdir(((lng & 4) && jn->pwd) ? jn->pwd : pwd, fout);
1262 fprintf(fout, ")\n");
1263 fflush(fout);
1264 }
1265
1266 /* delete job if done */
1267
1268 if (jn->stat & STAT_DONE) {
1269 /* This looks silly, but see update_job() */
1270 if (synch <= 1)
1271 storepipestats(jn, job == thisjob, job == thisjob);
1272 if (should_report_time(jn))
1273 dumptime(jn);
1274 deletejob(jn, 0);
1275 if (job == curjob) {
1276 curjob = prevjob;
1277 prevjob = job;
1278 }
1279 if (job == prevjob)
1280 setprevjob();
1281 } else
1282 jn->stat &= ~STAT_CHANGED;
1283
1284 return doneprint;
1285 }
1286
1287 /* Add a file to be deleted or fd to be closed to the current job */
1288
1289 /**/
1290 void
addfilelist(const char * name,int fd)1291 addfilelist(const char *name, int fd)
1292 {
1293 Jobfile jf = (Jobfile)zalloc(sizeof(struct jobfile));
1294 LinkList ll = jobtab[thisjob].filelist;
1295
1296 if (!ll)
1297 ll = jobtab[thisjob].filelist = znewlinklist();
1298 if (name)
1299 {
1300 jf->u.name = ztrdup(name);
1301 jf->is_fd = 0;
1302 }
1303 else
1304 {
1305 jf->u.fd = fd;
1306 jf->is_fd = 1;
1307 }
1308 zaddlinknode(ll, jf);
1309 }
1310
1311 /* Clean up pipes no longer needed associated with a job */
1312
1313 /**/
1314 void
pipecleanfilelist(LinkList filelist,int proc_subst_only)1315 pipecleanfilelist(LinkList filelist, int proc_subst_only)
1316 {
1317 LinkNode node;
1318
1319 if (!filelist)
1320 return;
1321 node = firstnode(filelist);
1322 while (node) {
1323 Jobfile jf = (Jobfile)getdata(node);
1324 if (jf->is_fd &&
1325 (!proc_subst_only || fdtable[jf->u.fd] == FDT_PROC_SUBST)) {
1326 LinkNode next = nextnode(node);
1327 zclose(jf->u.fd);
1328 (void)remnode(filelist, node);
1329 zfree(jf, sizeof(*jf));
1330 node = next;
1331 } else
1332 incnode(node);
1333 }
1334 }
1335
1336 /* Finished with list of files for a job */
1337
1338 /**/
1339 void
deletefilelist(LinkList file_list,int disowning)1340 deletefilelist(LinkList file_list, int disowning)
1341 {
1342 Jobfile jf;
1343 if (file_list) {
1344 while ((jf = (Jobfile)getlinknode(file_list))) {
1345 if (jf->is_fd) {
1346 if (!disowning)
1347 zclose(jf->u.fd);
1348 } else {
1349 if (!disowning)
1350 unlink(jf->u.name);
1351 zsfree(jf->u.name);
1352 }
1353 zfree(jf, sizeof(*jf));
1354 }
1355 zfree(file_list, sizeof(struct linklist));
1356 }
1357 }
1358
1359 /**/
1360 void
freejob(Job jn,int deleting)1361 freejob(Job jn, int deleting)
1362 {
1363 struct process *pn, *nx;
1364
1365 pn = jn->procs;
1366 jn->procs = NULL;
1367 for (; pn; pn = nx) {
1368 nx = pn->next;
1369 zfree(pn, sizeof(struct process));
1370 }
1371
1372 pn = jn->auxprocs;
1373 jn->auxprocs = NULL;
1374 for (; pn; pn = nx) {
1375 nx = pn->next;
1376 zfree(pn, sizeof(struct process));
1377 }
1378
1379 if (jn->ty)
1380 zfree(jn->ty, sizeof(struct ttyinfo));
1381 if (jn->pwd)
1382 zsfree(jn->pwd);
1383 jn->pwd = NULL;
1384 if (jn->stat & STAT_WASSUPER) {
1385 /* careful in case we shrink and move the job table */
1386 int job = jn - jobtab;
1387 if (deleting)
1388 deletejob(jobtab + jn->other, 0);
1389 else
1390 freejob(jobtab + jn->other, 0);
1391 jn = jobtab + job;
1392 }
1393 jn->gleader = jn->other = 0;
1394 jn->stat = jn->stty_in_env = 0;
1395 jn->filelist = NULL;
1396 jn->ty = NULL;
1397
1398 /* Find the new highest job number. */
1399 if (maxjob == jn - jobtab) {
1400 while (maxjob && !(jobtab[maxjob].stat & STAT_INUSE))
1401 maxjob--;
1402 }
1403 }
1404
1405 /*
1406 * We are actually finished with this job, rather
1407 * than freeing it to make space.
1408 *
1409 * If "disowning" is set, files associated with the job are not
1410 * actually deleted --- and won't be as there is nothing left
1411 * to clear up.
1412 */
1413
1414 /**/
1415 void
deletejob(Job jn,int disowning)1416 deletejob(Job jn, int disowning)
1417 {
1418 deletefilelist(jn->filelist, disowning);
1419 if (jn->stat & STAT_ATTACH) {
1420 attachtty(mypgrp);
1421 adjustwinsize(0);
1422 }
1423 if (jn->stat & STAT_SUPERJOB) {
1424 Job jno = jobtab + jn->other;
1425 if (jno->stat & STAT_SUBJOB)
1426 jno->stat |= STAT_SUBJOB_ORPHANED;
1427 }
1428
1429 freejob(jn, 1);
1430 }
1431
1432 /*
1433 * Add a process to the current job.
1434 * The third argument is 1 if we are adding a process which is not
1435 * part of the main pipeline but an auxiliary process used for
1436 * handling MULTIOS or process substitution. We will wait for it
1437 * but not display job information about it.
1438 */
1439
1440 /**/
1441 void
addproc(pid_t pid,char * text,int aux,struct timeval * bgtime,int gleader,int list_pipe_job_used)1442 addproc(pid_t pid, char *text, int aux, struct timeval *bgtime,
1443 int gleader, int list_pipe_job_used)
1444 {
1445 Process pn, *pnlist;
1446
1447 DPUTS(thisjob == -1, "No valid job in addproc.");
1448 pn = (Process) zshcalloc(sizeof *pn);
1449 pn->pid = pid;
1450 if (text)
1451 strcpy(pn->text, text);
1452 else
1453 *pn->text = '\0';
1454 pn->status = SP_RUNNING;
1455 pn->next = NULL;
1456
1457 if (!aux)
1458 {
1459 pn->bgtime = *bgtime;
1460 /*
1461 * if this is the first process we are adding to
1462 * the job, then it's the group leader.
1463 *
1464 * Exception: if the forked subshell reported its own group
1465 * leader, set that. If it reported the use of list_pipe_job,
1466 * set it for that, too.
1467 */
1468 if (gleader != -1) {
1469 jobtab[thisjob].gleader = gleader;
1470 if (list_pipe_job_used != -1)
1471 jobtab[list_pipe_job_used].gleader = gleader;
1472 /*
1473 * Record here this is the latest process group to grab the
1474 * terminal as attachtty() was run in the subshell.
1475 */
1476 last_attached_pgrp = gleader;
1477 } else if (!jobtab[thisjob].gleader)
1478 jobtab[thisjob].gleader = pid;
1479 /* attach this process to end of process list of current job */
1480 pnlist = &jobtab[thisjob].procs;
1481 }
1482 else
1483 pnlist = &jobtab[thisjob].auxprocs;
1484
1485 if (*pnlist) {
1486 Process n;
1487
1488 for (n = *pnlist; n->next; n = n->next);
1489 n->next = pn;
1490 } else {
1491 /* first process for this job */
1492 *pnlist = pn;
1493 }
1494 /* If the first process in the job finished before any others were *
1495 * added, maybe STAT_DONE got set incorrectly. This can happen if *
1496 * a $(...) was waited for and the last existing job in the *
1497 * pipeline was already finished. We need to be very careful that *
1498 * there was no call to printjob() between then and now, else *
1499 * the job will already have been deleted from the table. */
1500 jobtab[thisjob].stat &= ~STAT_DONE;
1501 }
1502
1503 /* Check if we have files to delete. We need to check this to see *
1504 * if it's all right to exec a command without forking in the last *
1505 * component of subshells or after the `-c' option. */
1506
1507 /**/
1508 int
havefiles(void)1509 havefiles(void)
1510 {
1511 int i;
1512
1513 for (i = 1; i <= maxjob; i++)
1514 if (jobtab[i].stat && jobtab[i].filelist)
1515 return 1;
1516 return 0;
1517
1518 }
1519
1520 /*
1521 * Wait for a particular process.
1522 * wait_cmd indicates this is from the interactive wait command,
1523 * in which case the behaviour is a little different: the command
1524 * itself can be interrupted by a trapped signal.
1525 */
1526
1527 /**/
1528 int
waitforpid(pid_t pid,int wait_cmd)1529 waitforpid(pid_t pid, int wait_cmd)
1530 {
1531 int first = 1, q = queue_signal_level();
1532
1533 /* child_block() around this loop in case #ifndef WNOHANG */
1534 dont_queue_signals();
1535 child_block(); /* unblocked in signal_suspend() */
1536 queue_traps(wait_cmd);
1537
1538 /* This function should never be called with a pid that is not a
1539 * child of the current shell. Consequently, if kill(0, pid)
1540 * fails here with ESRCH, the child has already been reaped. In
1541 * the loop body, we expect this to happen in signal_suspend()
1542 * via zhandler(), after which this test terminates the loop.
1543 */
1544 while (!errflag && (kill(pid, 0) >= 0 || errno != ESRCH)) {
1545 if (first)
1546 first = 0;
1547 else if (!wait_cmd)
1548 kill(pid, SIGCONT);
1549
1550 last_signal = -1;
1551 signal_suspend(SIGCHLD, wait_cmd);
1552 if (last_signal != SIGCHLD && wait_cmd && last_signal >= 0 &&
1553 (sigtrapped[last_signal] & ZSIG_TRAPPED)) {
1554 /* wait command interrupted, but no error: return */
1555 restore_queue_signals(q);
1556 return 128 + last_signal;
1557 }
1558 child_block();
1559 }
1560 unqueue_traps();
1561 child_unblock();
1562 restore_queue_signals(q);
1563
1564 return 0;
1565 }
1566
1567 /*
1568 * Wait for a job to finish.
1569 * wait_cmd indicates this is from the wait builtin; see
1570 * wait_cmd in waitforpid().
1571 */
1572
1573 /**/
1574 static int
zwaitjob(int job,int wait_cmd)1575 zwaitjob(int job, int wait_cmd)
1576 {
1577 int q = queue_signal_level();
1578 Job jn = jobtab + job;
1579
1580 child_block(); /* unblocked during signal_suspend() */
1581 queue_traps(wait_cmd);
1582 dont_queue_signals();
1583 if (jn->procs || jn->auxprocs) { /* if any forks were done */
1584 jn->stat |= STAT_LOCKED;
1585 if (jn->stat & STAT_CHANGED)
1586 printjob(jn, !!isset(LONGLISTJOBS), 1);
1587 if (jn->filelist) {
1588 /*
1589 * The main shell is finished with any file descriptors used
1590 * for process substitution associated with this job: close
1591 * them to indicate to listeners there's no more input.
1592 *
1593 * Note we can't safely delete temporary files yet as these
1594 * are directly visible to other processes. However,
1595 * we can't deadlock on the fact that those still exist, so
1596 * that's not a problem.
1597 */
1598 pipecleanfilelist(jn->filelist, 0);
1599 }
1600 while (!(errflag & ERRFLAG_ERROR) && jn->stat &&
1601 !(jn->stat & STAT_DONE) &&
1602 !(interact && (jn->stat & STAT_STOPPED))) {
1603 signal_suspend(SIGCHLD, wait_cmd);
1604 if (last_signal != SIGCHLD && wait_cmd && last_signal >= 0 &&
1605 (sigtrapped[last_signal] & ZSIG_TRAPPED))
1606 {
1607 /* builtin wait interrupted by trapped signal */
1608 restore_queue_signals(q);
1609 return 128 + last_signal;
1610 }
1611 /* Commenting this out makes ^C-ing a job started by a function
1612 stop the whole function again. But I guess it will stop
1613 something else from working properly, we have to find out
1614 what this might be. --oberon
1615
1616 When attempting to separate errors and interrupts, we
1617 assumed because of the previous comment it would be OK
1618 to remove ERRFLAG_ERROR and leave ERRFLAG_INT set, since
1619 that's the one related to ^C. But that doesn't work.
1620 There's something more here we don't understand. --pws
1621
1622 The change above to ignore ERRFLAG_INT in the loop test
1623 solves a problem wherein child processes that ignore the
1624 INT signal were never waited-for. Clearing the flag here
1625 still seems the wrong thing, but perhaps ERRFLAG_INT
1626 should be saved and restored around signal_suspend() to
1627 prevent it being lost within a signal trap? --Bart
1628
1629 errflag = 0; */
1630
1631 if (subsh)
1632 killjb(jn, SIGCONT);
1633 if (jn->stat & STAT_SUPERJOB)
1634 if (handle_sub(jn - jobtab, 1))
1635 break;
1636 child_block();
1637 }
1638 } else {
1639 deletejob(jn, 0);
1640 pipestats[0] = lastval;
1641 numpipestats = 1;
1642 }
1643 restore_queue_signals(q);
1644 unqueue_traps();
1645 child_unblock();
1646
1647 return 0;
1648 }
1649
waitonejob(Job jn)1650 static void waitonejob(Job jn)
1651 {
1652 if (jn->procs || jn->auxprocs)
1653 zwaitjob(jn - jobtab, 0);
1654 else {
1655 deletejob(jn, 0);
1656 pipestats[0] = lastval;
1657 numpipestats = 1;
1658 }
1659 }
1660
1661 /* wait for running job to finish */
1662
1663 /**/
1664 void
waitjobs(void)1665 waitjobs(void)
1666 {
1667 Job jn = jobtab + thisjob;
1668 DPUTS(thisjob == -1, "No valid job in waitjobs.");
1669
1670 /* If there's a subjob, it should finish first. */
1671 if (jn->stat & STAT_SUPERJOB)
1672 waitonejob(jobtab + jn->other);
1673 waitonejob(jn);
1674
1675 thisjob = -1;
1676 }
1677
1678 /* clear job table when entering subshells */
1679
1680 /**/
1681 mod_export void
clearjobtab(int monitor)1682 clearjobtab(int monitor)
1683 {
1684 int i;
1685
1686 if (isset(POSIXJOBS))
1687 oldmaxjob = 0;
1688 for (i = 1; i <= maxjob; i++) {
1689 /*
1690 * See if there is a jobtable worth saving.
1691 * We never free the saved version; it only happens
1692 * once for each subshell of a shell with job control,
1693 * so doesn't create a leak.
1694 */
1695 if (monitor && !isset(POSIXJOBS) && jobtab[i].stat)
1696 oldmaxjob = i+1;
1697 else if (jobtab[i].stat & STAT_INUSE)
1698 freejob(jobtab + i, 0);
1699 }
1700
1701 if (monitor && oldmaxjob) {
1702 int sz = oldmaxjob * sizeof(struct job);
1703 if (oldjobtab)
1704 free(oldjobtab);
1705 oldjobtab = (struct job *)zalloc(sz);
1706 memcpy(oldjobtab, jobtab, sz);
1707
1708 /* Don't report any job we're part of */
1709 if (thisjob != -1 && thisjob < oldmaxjob)
1710 memset(oldjobtab+thisjob, 0, sizeof(struct job));
1711 }
1712
1713 memset(jobtab, 0, jobtabsize * sizeof(struct job)); /* zero out table */
1714 maxjob = 0;
1715
1716 /*
1717 * Although we don't have job control in subshells, we
1718 * sometimes needs control structures for other purposes such
1719 * as multios. Grab a job for this purpose; any will do
1720 * since we've freed them all up (so there's no question
1721 * of problems with the job table size here).
1722 */
1723 thisjob = initjob();
1724 }
1725
initnewjob(int i)1726 static int initnewjob(int i)
1727 {
1728 jobtab[i].stat = STAT_INUSE;
1729 if (jobtab[i].pwd) {
1730 zsfree(jobtab[i].pwd);
1731 jobtab[i].pwd = NULL;
1732 }
1733 jobtab[i].gleader = 0;
1734
1735 if (i > maxjob)
1736 maxjob = i;
1737
1738 return i;
1739 }
1740
1741 /* Get a free entry in the job table and initialize it. */
1742
1743 /**/
1744 int
initjob(void)1745 initjob(void)
1746 {
1747 int i;
1748
1749 for (i = 1; i <= maxjob; i++)
1750 if (!jobtab[i].stat)
1751 return initnewjob(i);
1752 if (maxjob + 1 < jobtabsize)
1753 return initnewjob(maxjob+1);
1754
1755 if (expandjobtab())
1756 return initnewjob(i);
1757
1758 zerr("job table full or recursion limit exceeded");
1759 return -1;
1760 }
1761
1762 /**/
1763 void
setjobpwd(void)1764 setjobpwd(void)
1765 {
1766 int i;
1767
1768 for (i = 1; i <= maxjob; i++)
1769 if (jobtab[i].stat && !jobtab[i].pwd)
1770 jobtab[i].pwd = ztrdup(pwd);
1771 }
1772
1773 /* print pids for & */
1774
1775 /**/
1776 void
spawnjob(void)1777 spawnjob(void)
1778 {
1779 Process pn;
1780
1781 DPUTS(thisjob == -1, "No valid job in spawnjob.");
1782 /* if we are not in a subshell */
1783 if (!subsh) {
1784 if (curjob == -1 || !(jobtab[curjob].stat & STAT_STOPPED)) {
1785 curjob = thisjob;
1786 setprevjob();
1787 } else if (prevjob == -1 || !(jobtab[prevjob].stat & STAT_STOPPED))
1788 prevjob = thisjob;
1789 if (jobbing && jobtab[thisjob].procs) {
1790 FILE *fout = shout ? shout : stdout;
1791 fprintf(fout, "[%d]", thisjob);
1792 for (pn = jobtab[thisjob].procs; pn; pn = pn->next)
1793 fprintf(fout, " %ld", (long) pn->pid);
1794 fprintf(fout, "\n");
1795 fflush(fout);
1796 }
1797 }
1798 if (!hasprocs(thisjob))
1799 deletejob(jobtab + thisjob, 0);
1800 else {
1801 jobtab[thisjob].stat |= STAT_LOCKED;
1802 pipecleanfilelist(jobtab[thisjob].filelist, 0);
1803 }
1804 thisjob = -1;
1805 }
1806
1807 /**/
1808 void
shelltime(void)1809 shelltime(void)
1810 {
1811 struct timezone dummy_tz;
1812 struct timeval dtimeval, now;
1813 child_times_t ti;
1814 #ifndef HAVE_GETRUSAGE
1815 struct tms buf;
1816 #endif
1817
1818 gettimeofday(&now, &dummy_tz);
1819
1820 #ifdef HAVE_GETRUSAGE
1821 getrusage(RUSAGE_SELF, &ti);
1822 #else
1823 times(&buf);
1824
1825 ti.ut = buf.tms_utime;
1826 ti.st = buf.tms_stime;
1827 #endif
1828 printtime(dtime(&dtimeval, &shtimer, &now), &ti, "shell");
1829
1830 #ifdef HAVE_GETRUSAGE
1831 getrusage(RUSAGE_CHILDREN, &ti);
1832 #else
1833 ti.ut = buf.tms_cutime;
1834 ti.st = buf.tms_cstime;
1835 #endif
1836 printtime(&dtimeval, &ti, "children");
1837
1838 }
1839
1840 /* see if jobs need printing */
1841
1842 /**/
1843 void
scanjobs(void)1844 scanjobs(void)
1845 {
1846 int i;
1847
1848 for (i = 1; i <= maxjob; i++)
1849 if (jobtab[i].stat & STAT_CHANGED)
1850 printjob(jobtab + i, !!isset(LONGLISTJOBS), 1);
1851 }
1852
1853 /**** job control builtins ****/
1854
1855 /* This simple function indicates whether or not s may represent *
1856 * a number. It returns true iff s consists purely of digits and *
1857 * minuses. Note that minus may appear more than once, and the empty *
1858 * string will produce a `true' response. */
1859
1860 /**/
1861 static int
isanum(char * s)1862 isanum(char *s)
1863 {
1864 while (*s == '-' || idigit(*s))
1865 s++;
1866 return *s == '\0';
1867 }
1868
1869 /* Make sure we have a suitable current and previous job set. */
1870
1871 /**/
1872 static void
setcurjob(void)1873 setcurjob(void)
1874 {
1875 if (curjob == thisjob ||
1876 (curjob != -1 && !(jobtab[curjob].stat & STAT_INUSE))) {
1877 curjob = prevjob;
1878 setprevjob();
1879 if (curjob == thisjob ||
1880 (curjob != -1 && !((jobtab[curjob].stat & STAT_INUSE) &&
1881 curjob != thisjob))) {
1882 curjob = prevjob;
1883 setprevjob();
1884 }
1885 }
1886 }
1887
1888 /* Convert a job specifier ("%%", "%1", "%foo", "%?bar?", etc.) *
1889 * to a job number. */
1890
1891 /**/
1892 mod_export int
getjob(const char * s,const char * prog)1893 getjob(const char *s, const char *prog)
1894 {
1895 int jobnum, returnval, mymaxjob;
1896 Job myjobtab;
1897
1898 if (oldjobtab) {
1899 myjobtab = oldjobtab;
1900 mymaxjob = oldmaxjob;
1901 } else {
1902 myjobtab= jobtab;
1903 mymaxjob = maxjob;
1904 }
1905
1906 /* if there is no %, treat as a name */
1907 if (*s != '%')
1908 goto jump;
1909 s++;
1910 /* "%%", "%+" and "%" all represent the current job */
1911 if (*s == '%' || *s == '+' || !*s) {
1912 if (curjob == -1) {
1913 if (prog && !isset(POSIXBUILTINS))
1914 zwarnnam(prog, "no current job");
1915 returnval = -1;
1916 goto done;
1917 }
1918 returnval = curjob;
1919 goto done;
1920 }
1921 /* "%-" represents the previous job */
1922 if (*s == '-') {
1923 if (prevjob == -1) {
1924 if (prog && !isset(POSIXBUILTINS))
1925 zwarnnam(prog, "no previous job");
1926 returnval = -1;
1927 goto done;
1928 }
1929 returnval = prevjob;
1930 goto done;
1931 }
1932 /* a digit here means we have a job number */
1933 if (idigit(*s)) {
1934 jobnum = atoi(s);
1935 if (jobnum > 0 && jobnum <= mymaxjob && myjobtab[jobnum].stat &&
1936 !(myjobtab[jobnum].stat & STAT_SUBJOB) &&
1937 /*
1938 * If running jobs in a subshell, we are allowed to
1939 * refer to the "current" job (it's not really the
1940 * current job in the subshell). It's possible we
1941 * should reset thisjob to -1 on entering the subshell.
1942 */
1943 (myjobtab == oldjobtab || jobnum != thisjob)) {
1944 returnval = jobnum;
1945 goto done;
1946 }
1947 if (prog && !isset(POSIXBUILTINS))
1948 zwarnnam(prog, "%%%s: no such job", s);
1949 returnval = -1;
1950 goto done;
1951 }
1952 /* "%?" introduces a search string */
1953 if (*s == '?') {
1954 struct process *pn;
1955
1956 for (jobnum = mymaxjob; jobnum >= 0; jobnum--)
1957 if (myjobtab[jobnum].stat &&
1958 !(myjobtab[jobnum].stat & STAT_SUBJOB) &&
1959 jobnum != thisjob)
1960 for (pn = myjobtab[jobnum].procs; pn; pn = pn->next)
1961 if (strstr(pn->text, s + 1)) {
1962 returnval = jobnum;
1963 goto done;
1964 }
1965 if (prog && !isset(POSIXBUILTINS))
1966 zwarnnam(prog, "job not found: %s", s);
1967 returnval = -1;
1968 goto done;
1969 }
1970 jump:
1971 /* anything else is a job name, specified as a string that begins the
1972 job's command */
1973 if ((jobnum = findjobnam(s)) != -1) {
1974 returnval = jobnum;
1975 goto done;
1976 }
1977 /* if we get here, it is because none of the above succeeded and went
1978 to done */
1979 if (!isset(POSIXBUILTINS))
1980 zwarnnam(prog, "job not found: %s", s);
1981 returnval = -1;
1982 done:
1983 return returnval;
1984 }
1985
1986 #ifndef HAVE_SETPROCTITLE
1987 /* For jobs -Z (which modifies the shell's name as seen in ps listings). *
1988 * hackzero is the start of the safely writable space, and hackspace is *
1989 * its length, excluding a final NUL terminator that will always be left. */
1990
1991 static char *hackzero;
1992 static int hackspace;
1993 #endif
1994
1995
1996 /* Initialise job handling. */
1997
1998 /**/
1999 void
init_jobs(char ** argv,char ** envp)2000 init_jobs(char **argv, char **envp)
2001 {
2002 #ifndef HAVE_SETPROCTITLE
2003 char *p, *q;
2004 #endif
2005 size_t init_bytes = MAXJOBS_ALLOC*sizeof(struct job);
2006
2007 /*
2008 * Initialise the job table. If this fails, we're in trouble.
2009 */
2010 jobtab = (struct job *)zalloc(init_bytes);
2011 if (!jobtab) {
2012 zerr("failed to allocate job table, aborting.");
2013 exit(1);
2014 }
2015 jobtabsize = MAXJOBS_ALLOC;
2016 memset(jobtab, 0, init_bytes);
2017
2018 #ifndef HAVE_SETPROCTITLE
2019 /*
2020 * Initialise the jobs -Z system. The technique is borrowed from
2021 * perl: check through the argument and environment space, to see
2022 * how many of the strings are in contiguous space. This determines
2023 * the value of hackspace.
2024 */
2025 hackzero = *argv;
2026 p = strchr(hackzero, 0);
2027 while(*++argv) {
2028 q = *argv;
2029 if(q != p+1)
2030 goto done;
2031 p = strchr(q, 0);
2032 }
2033 #if !defined(HAVE_PUTENV) && !defined(USE_SET_UNSET_ENV)
2034 for(; *envp; envp++) {
2035 q = *envp;
2036 if(q != p+1)
2037 goto done;
2038 p = strchr(q, 0);
2039 }
2040 #endif
2041 done:
2042 hackspace = p - hackzero;
2043 #endif
2044 }
2045
2046
2047 /*
2048 * We have run out of space in the job table.
2049 * Expand it by an additional MAXJOBS_ALLOC slots.
2050 */
2051
2052 /*
2053 * An arbitrary limit on the absolute maximum size of the job table.
2054 * This prevents us taking over the entire universe.
2055 * Ought to be a multiple of MAXJOBS_ALLOC, but doesn't need to be.
2056 */
2057 #define MAX_MAXJOBS 1000
2058
2059 /**/
2060 int
expandjobtab(void)2061 expandjobtab(void)
2062 {
2063 int newsize = jobtabsize + MAXJOBS_ALLOC;
2064 struct job *newjobtab;
2065
2066 if (newsize > MAX_MAXJOBS)
2067 return 0;
2068
2069 newjobtab = (struct job *)zrealloc(jobtab, newsize * sizeof(struct job));
2070 if (!newjobtab)
2071 return 0;
2072
2073 /*
2074 * Clear the new section of the table; this is necessary for
2075 * the jobs to appear unused.
2076 */
2077 memset(newjobtab + jobtabsize, 0, MAXJOBS_ALLOC * sizeof(struct job));
2078
2079 jobtab = newjobtab;
2080 jobtabsize = newsize;
2081
2082 return 1;
2083 }
2084
2085
2086 /*
2087 * See if we can reduce the job table. We can if we go over
2088 * a MAXJOBS_ALLOC boundary. However, we leave a boundary,
2089 * currently 20 jobs, so that we have a place for immediate
2090 * expansion and don't play ping pong with the job table size.
2091 */
2092
2093 /**/
2094 void
maybeshrinkjobtab(void)2095 maybeshrinkjobtab(void)
2096 {
2097 int jobbound;
2098
2099 queue_signals();
2100 jobbound = maxjob + MAXJOBS_ALLOC - (maxjob % MAXJOBS_ALLOC);
2101 if (jobbound < jobtabsize && jobbound > maxjob + 20) {
2102 struct job *newjobtab;
2103
2104 /* Hope this can't fail, but anyway... */
2105 newjobtab = (struct job *)zrealloc(jobtab,
2106 jobbound*sizeof(struct job));
2107
2108 if (newjobtab) {
2109 jobtab = newjobtab;
2110 jobtabsize = jobbound;
2111 }
2112 }
2113 unqueue_signals();
2114 }
2115
2116 /*
2117 * Definitions for the background process stuff recorded below.
2118 * This would be more efficient as a hash, but
2119 * - that's quite heavyweight for something not needed very often
2120 * - we need some kind of ordering as POSIX allows us to limit
2121 * the size of the list to the value of _SC_CHILD_MAX and clearly
2122 * we want to clear the oldest first
2123 * - cases with a long list of background jobs where the user doesn't
2124 * wait for a large number, and then does wait for one (the only
2125 * inefficient case) are rare
2126 * - in the context of waiting for an external process, looping
2127 * over a list isn't so very inefficient.
2128 * Enough excuses already.
2129 */
2130
2131 /* Data in the link list, a key (process ID) / value (exit status) pair. */
2132 struct bgstatus {
2133 pid_t pid;
2134 int status;
2135 };
2136 typedef struct bgstatus *Bgstatus;
2137 /* The list of those entries */
2138 static LinkList bgstatus_list;
2139 /* Count of entries. Reaches value of _SC_CHILD_MAX and stops. */
2140 static long bgstatus_count;
2141
2142 /*
2143 * Remove and free a bgstatus entry.
2144 */
rembgstatus(LinkNode node)2145 static void rembgstatus(LinkNode node)
2146 {
2147 zfree(remnode(bgstatus_list, node), sizeof(struct bgstatus));
2148 bgstatus_count--;
2149 }
2150
2151 /*
2152 * Record the status of a background process that exited so we
2153 * can execute the builtin wait for it.
2154 *
2155 * We can't execute the wait builtin for something that exited in the
2156 * foreground as it's not visible to the user, so don't bother recording.
2157 */
2158
2159 /**/
2160 void
addbgstatus(pid_t pid,int status)2161 addbgstatus(pid_t pid, int status)
2162 {
2163 static long child_max;
2164 Bgstatus bgstatus_entry;
2165
2166 if (!child_max) {
2167 #ifdef _SC_CHILD_MAX
2168 child_max = sysconf(_SC_CHILD_MAX);
2169 if (!child_max) /* paranoia */
2170 #endif
2171 {
2172 /* Be inventive */
2173 child_max = 1024L;
2174 }
2175 }
2176
2177 if (!bgstatus_list) {
2178 bgstatus_list = znewlinklist();
2179 /*
2180 * We're not always robust about memory failures, but
2181 * this is pretty deep in the shell basics to be failing owing
2182 * to memory, and a failure to wait is reported loudly, so test
2183 * and fail silently here.
2184 */
2185 if (!bgstatus_list)
2186 return;
2187 }
2188 if (bgstatus_count == child_max) {
2189 /* Overflow. List is in order, remove first */
2190 rembgstatus(firstnode(bgstatus_list));
2191 }
2192 bgstatus_entry = (Bgstatus)zalloc(sizeof(*bgstatus_entry));
2193 if (!bgstatus_entry) {
2194 /* See note above */
2195 return;
2196 }
2197 bgstatus_entry->pid = pid;
2198 bgstatus_entry->status = status;
2199 if (!zaddlinknode(bgstatus_list, bgstatus_entry)) {
2200 zfree(bgstatus_entry, sizeof(*bgstatus_entry));
2201 return;
2202 }
2203 bgstatus_count++;
2204 }
2205
2206 /*
2207 * See if pid has a recorded exit status.
2208 * Note we make no guarantee that the PIDs haven't wrapped, so this
2209 * may not be the right process.
2210 *
2211 * This is only used by wait, which must only work on each
2212 * pid once, so we need to remove the entry if we find it.
2213 */
2214
getbgstatus(pid_t pid)2215 static int getbgstatus(pid_t pid)
2216 {
2217 LinkNode node;
2218 Bgstatus bgstatus_entry;
2219
2220 if (!bgstatus_list)
2221 return -1;
2222 for (node = firstnode(bgstatus_list); node; incnode(node)) {
2223 bgstatus_entry = (Bgstatus)getdata(node);
2224 if (bgstatus_entry->pid == pid) {
2225 int status = bgstatus_entry->status;
2226 rembgstatus(node);
2227 return status;
2228 }
2229 }
2230 return -1;
2231 }
2232
2233 /* bg, disown, fg, jobs, wait: most of the job control commands are *
2234 * here. They all take the same type of argument. Exception: wait can *
2235 * take a pid or a job specifier, whereas the others only work on jobs. */
2236
2237 /**/
2238 int
bin_fg(char * name,char ** argv,Options ops,int func)2239 bin_fg(char *name, char **argv, Options ops, int func)
2240 {
2241 int job, lng, firstjob = -1, retval = 0, ofunc = func;
2242
2243 if (OPT_ISSET(ops,'Z')) {
2244 int len;
2245
2246 if(isset(RESTRICTED)) {
2247 zwarnnam(name, "-Z is restricted");
2248 return 1;
2249 }
2250 if(!argv[0] || argv[1]) {
2251 zwarnnam(name, "-Z requires one argument");
2252 return 1;
2253 }
2254 queue_signals();
2255 unmetafy(*argv, &len);
2256 #ifdef HAVE_SETPROCTITLE
2257 setproctitle("%s", *argv);
2258 #else
2259 if(len > hackspace)
2260 len = hackspace;
2261 memcpy(hackzero, *argv, len);
2262 memset(hackzero + len, 0, hackspace - len);
2263 #endif
2264 unqueue_signals();
2265 return 0;
2266 }
2267
2268 if (func == BIN_JOBS) {
2269 lng = (OPT_ISSET(ops,'l')) ? 1 : (OPT_ISSET(ops,'p')) ? 2 : 0;
2270 if (OPT_ISSET(ops,'d'))
2271 lng |= 4;
2272 } else {
2273 lng = !!isset(LONGLISTJOBS);
2274 }
2275
2276 if ((func == BIN_FG || func == BIN_BG) && !jobbing) {
2277 /* oops... maybe bg and fg should have been disabled? */
2278 zwarnnam(name, "no job control in this shell.");
2279 return 1;
2280 }
2281
2282 queue_signals();
2283 /*
2284 * In case any processes changed state recently, wait for them.
2285 * This updates stopped processes (but we should have been
2286 * signalled about those, up to inevitable races), and also
2287 * continued processes if that feature is available.
2288 */
2289 wait_for_processes();
2290
2291 /* If necessary, update job table. */
2292 if (unset(NOTIFY))
2293 scanjobs();
2294
2295 if (func != BIN_JOBS || isset(MONITOR) || !oldmaxjob)
2296 setcurjob();
2297
2298 if (func == BIN_JOBS)
2299 /* If you immediately type "exit" after "jobs", this *
2300 * will prevent zexit from complaining about stopped jobs */
2301 stopmsg = 2;
2302 if (!*argv) {
2303 /* This block handles all of the default cases (no arguments). bg,
2304 fg and disown act on the current job, and jobs and wait act on all the
2305 jobs. */
2306 if (func == BIN_FG || func == BIN_BG || func == BIN_DISOWN) {
2307 /* W.r.t. the above comment, we'd better have a current job at this
2308 point or else. */
2309 if (curjob == -1 || (jobtab[curjob].stat & STAT_NOPRINT)) {
2310 zwarnnam(name, "no current job");
2311 unqueue_signals();
2312 return 1;
2313 }
2314 firstjob = curjob;
2315 } else if (func == BIN_JOBS) {
2316 /* List jobs. */
2317 struct job *jobptr;
2318 int curmaxjob, ignorejob;
2319 if (unset(MONITOR) && oldmaxjob) {
2320 jobptr = oldjobtab;
2321 curmaxjob = oldmaxjob ? oldmaxjob - 1 : 0;
2322 ignorejob = 0;
2323 } else {
2324 jobptr = jobtab;
2325 curmaxjob = maxjob;
2326 ignorejob = thisjob;
2327 }
2328 for (job = 0; job <= curmaxjob; job++, jobptr++)
2329 if (job != ignorejob && jobptr->stat) {
2330 if ((!OPT_ISSET(ops,'r') && !OPT_ISSET(ops,'s')) ||
2331 (OPT_ISSET(ops,'r') && OPT_ISSET(ops,'s')) ||
2332 (OPT_ISSET(ops,'r') &&
2333 !(jobptr->stat & STAT_STOPPED)) ||
2334 (OPT_ISSET(ops,'s') && jobptr->stat & STAT_STOPPED))
2335 printjob(jobptr, lng, 2);
2336 }
2337 unqueue_signals();
2338 return 0;
2339 } else { /* Must be BIN_WAIT, so wait for all jobs */
2340 for (job = 0; job <= maxjob; job++)
2341 if (job != thisjob && jobtab[job].stat &&
2342 !(jobtab[job].stat & STAT_NOPRINT))
2343 retval = zwaitjob(job, 1);
2344 unqueue_signals();
2345 return retval;
2346 }
2347 }
2348
2349 /* Defaults have been handled. We now have an argument or two, or three...
2350 In the default case for bg, fg and disown, the argument will be provided by
2351 the above routine. We now loop over the arguments. */
2352 for (; (firstjob != -1) || *argv; (void)(*argv && argv++)) {
2353 int stopped, ocj = thisjob, jstat;
2354
2355 func = ofunc;
2356
2357 if (func == BIN_WAIT && isanum(*argv)) {
2358 /* wait can take a pid; the others can't. */
2359 pid_t pid = (long)atoi(*argv);
2360 Job j;
2361 Process p;
2362
2363 if (findproc(pid, &j, &p, 0)) {
2364 if (j->stat & STAT_STOPPED)
2365 retval = (killjb(j, SIGCONT) != 0);
2366 if (retval == 0) {
2367 /*
2368 * returns 0 for normal exit, else signal+128
2369 * in which case we should return that status.
2370 */
2371 retval = waitforpid(pid, 1);
2372 }
2373 if (retval == 0) {
2374 if ((retval = getbgstatus(pid)) < 0) {
2375 retval = lastval2;
2376 }
2377 }
2378 } else if ((retval = getbgstatus(pid)) < 0) {
2379 if (!isset(POSIXBUILTINS))
2380 zwarnnam(name, "pid %d is not a child of this shell", pid);
2381 /* presumably lastval2 doesn't tell us a heck of a lot? */
2382 retval = 127;
2383 }
2384 thisjob = ocj;
2385 continue;
2386 }
2387 if (func != BIN_JOBS && oldjobtab != NULL) {
2388 zwarnnam(name, "can't manipulate jobs in subshell");
2389 unqueue_signals();
2390 return 1;
2391 }
2392 /* The only type of argument allowed now is a job spec. Check it. */
2393 job = (*argv) ? getjob(*argv, name) : firstjob;
2394 firstjob = -1;
2395 if (job == -1) {
2396 retval = 127;
2397 break;
2398 }
2399 jstat = oldjobtab ? oldjobtab[job].stat : jobtab[job].stat;
2400 if (!(jstat & STAT_INUSE) ||
2401 (jstat & STAT_NOPRINT)) {
2402 if (!isset(POSIXBUILTINS))
2403 zwarnnam(name, "%s: no such job", *argv);
2404 unqueue_signals();
2405 return 127;
2406 }
2407 /* If AUTO_CONTINUE is set (automatically make stopped jobs running
2408 * on disown), we actually do a bg and then delete the job table entry. */
2409
2410 if (isset(AUTOCONTINUE) && func == BIN_DISOWN &&
2411 jstat & STAT_STOPPED)
2412 func = BIN_BG;
2413
2414 /* We have a job number. Now decide what to do with it. */
2415 switch (func) {
2416 case BIN_FG:
2417 case BIN_BG:
2418 case BIN_WAIT:
2419 if (func == BIN_BG) {
2420 jobtab[job].stat |= STAT_NOSTTY;
2421 jobtab[job].stat &= ~STAT_CURSH;
2422 }
2423 if ((stopped = (jobtab[job].stat & STAT_STOPPED))) {
2424 makerunning(jobtab + job);
2425 if (func == BIN_BG) {
2426 /* Set $! to indicate this was backgrounded */
2427 Process pn = jobtab[job].procs;
2428 for (;;) {
2429 Process next = pn->next;
2430 if (!next) {
2431 lastpid = (zlong) pn->pid;
2432 break;
2433 }
2434 pn = next;
2435 }
2436 }
2437 } else if (func == BIN_BG) {
2438 /* Silly to bg a job already running. */
2439 zwarnnam(name, "job already in background");
2440 thisjob = ocj;
2441 unqueue_signals();
2442 return 1;
2443 }
2444 /* It's time to shuffle the jobs around! Reset the current job,
2445 and pick a sensible secondary job. */
2446 if (curjob == job) {
2447 curjob = prevjob;
2448 prevjob = (func == BIN_BG) ? -1 : job;
2449 }
2450 if (prevjob == job || prevjob == -1)
2451 setprevjob();
2452 if (curjob == -1) {
2453 curjob = prevjob;
2454 setprevjob();
2455 }
2456 if (func != BIN_WAIT)
2457 /* for bg and fg -- show the job we are operating on */
2458 printjob(jobtab + job, (stopped) ? -1 : lng, 3);
2459 if (func != BIN_BG) { /* fg or wait */
2460 if (jobtab[job].pwd && strcmp(jobtab[job].pwd, pwd)) {
2461 FILE *fout = (func == BIN_JOBS || !shout) ? stdout : shout;
2462 fprintf(fout, "(pwd : ");
2463 fprintdir(jobtab[job].pwd, fout);
2464 fprintf(fout, ")\n");
2465 fflush(fout);
2466 }
2467 if (func != BIN_WAIT) { /* fg */
2468 thisjob = job;
2469 if ((jobtab[job].stat & STAT_SUPERJOB) &&
2470 ((!jobtab[job].procs->next ||
2471 (jobtab[job].stat & STAT_SUBLEADER) ||
2472 killpg(jobtab[job].gleader, 0) == -1)) &&
2473 jobtab[jobtab[job].other].gleader)
2474 attachtty(jobtab[jobtab[job].other].gleader);
2475 else
2476 attachtty(jobtab[job].gleader);
2477 }
2478 }
2479 if (stopped) {
2480 if (func != BIN_BG && jobtab[job].ty)
2481 settyinfo(jobtab[job].ty);
2482 killjb(jobtab + job, SIGCONT);
2483 }
2484 if (func == BIN_WAIT)
2485 {
2486 retval = zwaitjob(job, 1);
2487 if (!retval)
2488 retval = lastval2;
2489 }
2490 else if (func != BIN_BG) {
2491 /*
2492 * HERE: there used not to be an "else" above. How
2493 * could it be right to wait for the foreground job
2494 * when we've just been told to wait for another
2495 * job (and done it)?
2496 */
2497 waitjobs();
2498 retval = lastval2;
2499 } else if (ofunc == BIN_DISOWN)
2500 deletejob(jobtab + job, 1);
2501 break;
2502 case BIN_JOBS:
2503 printjob(job + (oldjobtab ? oldjobtab : jobtab), lng, 2);
2504 break;
2505 case BIN_DISOWN:
2506 if (jobtab[job].stat & STAT_SUPERJOB) {
2507 jobtab[job].stat |= STAT_DISOWN;
2508 continue;
2509 }
2510 if (jobtab[job].stat & STAT_STOPPED) {
2511 char buf[20], *pids = "";
2512
2513 if (jobtab[job].stat & STAT_SUPERJOB) {
2514 Process pn;
2515
2516 for (pn = jobtab[jobtab[job].other].procs; pn; pn = pn->next) {
2517 sprintf(buf, " -%d", pn->pid);
2518 pids = dyncat(pids, buf);
2519 }
2520 for (pn = jobtab[job].procs; pn->next; pn = pn->next) {
2521 sprintf(buf, " %d", pn->pid);
2522 pids = dyncat(pids, buf);
2523 }
2524 if (!jobtab[jobtab[job].other].procs && pn) {
2525 sprintf(buf, " %d", pn->pid);
2526 pids = dyncat(pids, buf);
2527 }
2528 } else {
2529 sprintf(buf, " -%d", jobtab[job].gleader);
2530 pids = buf;
2531 }
2532 zwarnnam(name,
2533 #ifdef USE_SUSPENDED
2534 "warning: job is suspended, use `kill -CONT%s' to resume",
2535 #else
2536 "warning: job is stopped, use `kill -CONT%s' to resume",
2537 #endif
2538 pids);
2539 }
2540 deletejob(jobtab + job, 1);
2541 break;
2542 }
2543 thisjob = ocj;
2544 }
2545 unqueue_signals();
2546 return retval;
2547 }
2548
2549 static const struct {
2550 const char *name;
2551 int num;
2552 } alt_sigs[] = {
2553 #if defined(SIGCHLD) && defined(SIGCLD)
2554 #if SIGCHLD == SIGCLD
2555 { "CLD", SIGCLD },
2556 #endif
2557 #endif
2558 #if defined(SIGPOLL) && defined(SIGIO)
2559 #if SIGPOLL == SIGIO
2560 { "IO", SIGIO },
2561 #endif
2562 #endif
2563 #if !defined(SIGERR)
2564 /*
2565 * If SIGERR is not defined by the operating system, use it
2566 * as an alias for SIGZERR.
2567 */
2568 { "ERR", SIGZERR },
2569 #endif
2570 { NULL, 0 }
2571 };
2572
2573 /* kill: send a signal to a process. The process(es) may be specified *
2574 * by job specifier (see above) or pid. A signal, defaulting to *
2575 * SIGTERM, may be specified by name or number, preceded by a dash. */
2576
2577 /**/
2578 int
bin_kill(char * nam,char ** argv,UNUSED (Options ops),UNUSED (int func))2579 bin_kill(char *nam, char **argv, UNUSED(Options ops), UNUSED(int func))
2580 {
2581 int sig = SIGTERM;
2582 int returnval = 0;
2583
2584 /* check for, and interpret, a signal specifier */
2585 if (*argv && **argv == '-') {
2586 if (idigit((*argv)[1])) {
2587 char *endp;
2588 /* signal specified by number */
2589 sig = zstrtol(*argv + 1, &endp, 10);
2590 if (*endp) {
2591 zwarnnam(nam, "invalid signal number: %s", *argv);
2592 return 1;
2593 }
2594 } else if ((*argv)[1] != '-' || (*argv)[2]) {
2595 char *signame;
2596
2597 /* with argument "-l" display the list of signal names */
2598 if ((*argv)[1] == 'l' && (*argv)[2] == '\0') {
2599 if (argv[1]) {
2600 while (*++argv) {
2601 sig = zstrtol(*argv, &signame, 10);
2602 if (signame == *argv) {
2603 if (!strncmp(signame, "SIG", 3))
2604 signame += 3;
2605 for (sig = 1; sig <= SIGCOUNT; sig++)
2606 if (!strcasecmp(sigs[sig], signame))
2607 break;
2608 if (sig > SIGCOUNT) {
2609 int i;
2610
2611 for (i = 0; alt_sigs[i].name; i++)
2612 if (!strcasecmp(alt_sigs[i].name, signame))
2613 {
2614 sig = alt_sigs[i].num;
2615 break;
2616 }
2617 }
2618 if (sig > SIGCOUNT) {
2619 zwarnnam(nam, "unknown signal: SIG%s",
2620 signame);
2621 returnval++;
2622 } else
2623 printf("%d\n", sig);
2624 } else {
2625 if (*signame) {
2626 zwarnnam(nam, "unknown signal: SIG%s",
2627 signame);
2628 returnval++;
2629 } else {
2630 if (WIFSIGNALED(sig))
2631 sig = WTERMSIG(sig);
2632 else if (WIFSTOPPED(sig))
2633 sig = WSTOPSIG(sig);
2634 if (1 <= sig && sig <= SIGCOUNT)
2635 printf("%s\n", sigs[sig]);
2636 else
2637 printf("%d\n", sig);
2638 }
2639 }
2640 }
2641 return returnval;
2642 }
2643 printf("%s", sigs[1]);
2644 for (sig = 2; sig <= SIGCOUNT; sig++)
2645 printf(" %s", sigs[sig]);
2646 putchar('\n');
2647 return 0;
2648 }
2649
2650 if ((*argv)[1] == 'n' && (*argv)[2] == '\0') {
2651 char *endp;
2652
2653 if (!*++argv) {
2654 zwarnnam(nam, "-n: argument expected");
2655 return 1;
2656 }
2657 sig = zstrtol(*argv, &endp, 10);
2658 if (*endp) {
2659 zwarnnam(nam, "invalid signal number: %s", *argv);
2660 return 1;
2661 }
2662 } else {
2663 if (!((*argv)[1] == 's' && (*argv)[2] == '\0'))
2664 signame = *argv + 1;
2665 else if (!(*++argv)) {
2666 zwarnnam(nam, "-s: argument expected");
2667 return 1;
2668 } else
2669 signame = *argv;
2670 if (!*signame) {
2671 zwarnnam(nam, "-: signal name expected");
2672 return 1;
2673 }
2674 signame = casemodify(signame, CASMOD_UPPER);
2675 if (!strncmp(signame, "SIG", 3))
2676 signame+=3;
2677
2678 /* check for signal matching specified name */
2679 for (sig = 1; sig <= SIGCOUNT; sig++)
2680 if (!strcmp(*(sigs + sig), signame))
2681 break;
2682 if (*signame == '0' && !signame[1])
2683 sig = 0;
2684 if (sig > SIGCOUNT) {
2685 int i;
2686
2687 for (i = 0; alt_sigs[i].name; i++)
2688 if (!strcmp(alt_sigs[i].name, signame))
2689 {
2690 sig = alt_sigs[i].num;
2691 break;
2692 }
2693 }
2694 if (sig > SIGCOUNT) {
2695 zwarnnam(nam, "unknown signal: SIG%s", signame);
2696 zwarnnam(nam, "type kill -l for a list of signals");
2697 return 1;
2698 }
2699 }
2700 }
2701 argv++;
2702 }
2703
2704 /* Discard the standard "-" and "--" option breaks */
2705 if (*argv && (*argv)[0] == '-' && (!(*argv)[1] || (*argv)[1] == '-'))
2706 argv++;
2707
2708 if (!*argv) {
2709 zwarnnam(nam, "not enough arguments");
2710 return 1;
2711 }
2712
2713 queue_signals();
2714 setcurjob();
2715
2716 /* Remaining arguments specify processes. Loop over them, and send the
2717 signal (number sig) to each process. */
2718 for (; *argv; argv++) {
2719 if (**argv == '%') {
2720 /* job specifier introduced by '%' */
2721 int p;
2722
2723 if ((p = getjob(*argv, nam)) == -1) {
2724 returnval++;
2725 continue;
2726 }
2727 if (killjb(jobtab + p, sig) == -1) {
2728 zwarnnam("kill", "kill %s failed: %e", *argv, errno);
2729 returnval++;
2730 continue;
2731 }
2732 /* automatically update the job table if sending a SIGCONT to a
2733 job, and send the job a SIGCONT if sending it a non-stopping
2734 signal. */
2735 if (jobtab[p].stat & STAT_STOPPED) {
2736 #ifndef WIFCONTINUED
2737 /* With WIFCONTINUED we find this out properly */
2738 if (sig == SIGCONT)
2739 makerunning(jobtab + p);
2740 #endif
2741 if (sig != SIGKILL && sig != SIGCONT && sig != SIGTSTP
2742 && sig != SIGTTOU && sig != SIGTTIN && sig != SIGSTOP)
2743 killjb(jobtab + p, SIGCONT);
2744 }
2745 } else if (!isanum(*argv)) {
2746 zwarnnam("kill", "illegal pid: %s", *argv);
2747 returnval++;
2748 } else {
2749 int pid = atoi(*argv);
2750 if (kill(pid, sig) == -1) {
2751 zwarnnam("kill", "kill %s failed: %e", *argv, errno);
2752 returnval++;
2753 }
2754 #ifndef WIFCONTINUED
2755 else if (sig == SIGCONT) {
2756 Job jn;
2757 Process pn;
2758 /* With WIFCONTINUED we find this out properly */
2759 if (findproc(pid, &jn, &pn, 0)) {
2760 if (WIFSTOPPED(pn->status))
2761 pn->status = SP_RUNNING;
2762 }
2763 }
2764 #endif
2765 }
2766 }
2767 unqueue_signals();
2768
2769 return returnval < 126 ? returnval : 1;
2770 }
2771 /* Get a signal number from a string */
2772
2773 /**/
2774 mod_export int
getsignum(const char * s)2775 getsignum(const char *s)
2776 {
2777 int x, i;
2778
2779 /* check for a signal specified by number */
2780 x = atoi(s);
2781 if (idigit(*s) && x >= 0 && x < VSIGCOUNT)
2782 return x;
2783
2784 /* search for signal by name */
2785 if (!strncmp(s, "SIG", 3))
2786 s += 3;
2787
2788 for (i = 0; i < VSIGCOUNT; i++)
2789 if (!strcmp(s, sigs[i]))
2790 return i;
2791
2792 for (i = 0; alt_sigs[i].name; i++)
2793 {
2794 if (!strcmp(s, alt_sigs[i].name))
2795 return alt_sigs[i].num;
2796 }
2797
2798 /* no matching signal */
2799 return -1;
2800 }
2801
2802 /* Get the name for a signal. */
2803
2804 /**/
2805 mod_export const char *
getsigname(int sig)2806 getsigname(int sig)
2807 {
2808 if (sigtrapped[sig] & ZSIG_ALIAS)
2809 {
2810 int i;
2811 for (i = 0; alt_sigs[i].name; i++)
2812 if (sig == alt_sigs[i].num)
2813 return alt_sigs[i].name;
2814 }
2815 else
2816 return sigs[sig];
2817
2818 /* shouldn't reach here */
2819 #ifdef DEBUG
2820 dputs("Bad alias flag for signal");
2821 #endif
2822 return "";
2823 }
2824
2825
2826 /* Get the function node for a trap, taking care about alternative names */
2827 /**/
2828 HashNode
gettrapnode(int sig,int ignoredisable)2829 gettrapnode(int sig, int ignoredisable)
2830 {
2831 char fname[20];
2832 HashNode hn;
2833 HashNode (*getptr)(HashTable ht, const char *name);
2834 int i;
2835 if (ignoredisable)
2836 getptr = shfunctab->getnode2;
2837 else
2838 getptr = shfunctab->getnode;
2839
2840 sprintf(fname, "TRAP%s", sigs[sig]);
2841 if ((hn = getptr(shfunctab, fname)))
2842 return hn;
2843
2844 for (i = 0; alt_sigs[i].name; i++) {
2845 if (alt_sigs[i].num == sig) {
2846 sprintf(fname, "TRAP%s", alt_sigs[i].name);
2847 if ((hn = getptr(shfunctab, fname)))
2848 return hn;
2849 }
2850 }
2851
2852 return NULL;
2853 }
2854
2855 /* Remove a TRAP function under any name for the signal */
2856
2857 /**/
2858 void
removetrapnode(int sig)2859 removetrapnode(int sig)
2860 {
2861 HashNode hn = gettrapnode(sig, 1);
2862 if (hn) {
2863 shfunctab->removenode(shfunctab, hn->nam);
2864 shfunctab->freenode(hn);
2865 }
2866 }
2867
2868 /* Suspend this shell */
2869
2870 /**/
2871 int
bin_suspend(char * name,UNUSED (char ** argv),Options ops,UNUSED (int func))2872 bin_suspend(char *name, UNUSED(char **argv), Options ops, UNUSED(int func))
2873 {
2874 /* won't suspend a login shell, unless forced */
2875 if (islogin && !OPT_ISSET(ops,'f')) {
2876 zwarnnam(name, "can't suspend login shell");
2877 return 1;
2878 }
2879 if (jobbing) {
2880 /* stop ignoring signals */
2881 signal_default(SIGTTIN);
2882 signal_default(SIGTSTP);
2883 signal_default(SIGTTOU);
2884
2885 /* Move ourselves back to the process group we came from */
2886 release_pgrp();
2887 }
2888
2889 /* suspend ourselves with a SIGTSTP */
2890 killpg(origpgrp, SIGTSTP);
2891
2892 if (jobbing) {
2893 acquire_pgrp();
2894 /* restore signal handling */
2895 signal_ignore(SIGTTOU);
2896 signal_ignore(SIGTSTP);
2897 signal_ignore(SIGTTIN);
2898 }
2899 return 0;
2900 }
2901
2902 /* find a job named s */
2903
2904 /**/
2905 int
findjobnam(const char * s)2906 findjobnam(const char *s)
2907 {
2908 int jobnum;
2909
2910 for (jobnum = maxjob; jobnum >= 0; jobnum--)
2911 if (!(jobtab[jobnum].stat & (STAT_SUBJOB | STAT_NOPRINT)) &&
2912 jobtab[jobnum].stat && jobtab[jobnum].procs && jobnum != thisjob &&
2913 jobtab[jobnum].procs->text[0] && strpfx(s, jobtab[jobnum].procs->text))
2914 return jobnum;
2915 return -1;
2916 }
2917
2918
2919 /* make sure we are a process group leader by creating a new process
2920 group if necessary */
2921
2922 /**/
2923 void
acquire_pgrp(void)2924 acquire_pgrp(void)
2925 {
2926 long ttpgrp;
2927 sigset_t blockset, oldset;
2928
2929 if ((mypgrp = GETPGRP()) >= 0) {
2930 long lastpgrp = mypgrp;
2931 sigemptyset(&blockset);
2932 sigaddset(&blockset, SIGTTIN);
2933 sigaddset(&blockset, SIGTTOU);
2934 sigaddset(&blockset, SIGTSTP);
2935 oldset = signal_block(blockset);
2936 int loop_count = 0;
2937 while ((ttpgrp = gettygrp()) != -1 && ttpgrp != mypgrp) {
2938 mypgrp = GETPGRP();
2939 if (mypgrp == mypid) {
2940 if (!interact)
2941 break; /* attachtty() will be a no-op, give up */
2942 signal_setmask(oldset);
2943 attachtty(mypgrp); /* Might generate SIGT* */
2944 signal_block(blockset);
2945 }
2946 if (mypgrp == gettygrp())
2947 break;
2948 signal_setmask(oldset);
2949 if (read(0, NULL, 0) != 0) {} /* Might generate SIGT* */
2950 signal_block(blockset);
2951 mypgrp = GETPGRP();
2952 if (mypgrp == lastpgrp) {
2953 if (!interact)
2954 break; /* Unlikely that pgrp will ever change */
2955 if (++loop_count == 100)
2956 {
2957 /*
2958 * It's time to give up. The count is arbitrary;
2959 * this is just to fix up unusual cases, so it's
2960 * left large in an attempt not to break normal
2961 * cases where there's some delay in the system
2962 * setting up the terminal.
2963 */
2964 break;
2965 }
2966 }
2967 lastpgrp = mypgrp;
2968 }
2969 if (mypgrp != mypid) {
2970 if (setpgrp(0, 0) == 0) {
2971 mypgrp = mypid;
2972 attachtty(mypgrp);
2973 } else
2974 opts[MONITOR] = 0;
2975 }
2976 signal_setmask(oldset);
2977 } else
2978 opts[MONITOR] = 0;
2979 }
2980
2981 /* revert back to the process group we came from (before acquire_pgrp) */
2982
2983 /**/
2984 void
release_pgrp(void)2985 release_pgrp(void)
2986 {
2987 if (origpgrp != mypgrp) {
2988 /* in linux pid namespaces, origpgrp may never have been set */
2989 if (origpgrp) {
2990 attachtty(origpgrp);
2991 setpgrp(0, origpgrp);
2992 }
2993 mypgrp = origpgrp;
2994 }
2995 }
2996