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