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