#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
+#ifdef HAVE_PATHS_H
#include <paths.h>
+#endif
#include <sys/types.h>
#include <sys/param.h>
#ifdef BSD
/* mode flags for dowait */
#define DOWAIT_NORMAL 0
#define DOWAIT_BLOCK 1
+#define DOWAIT_WAITCMD 2
/* array of jobs */
static struct job *jobtab;
if (on == jobctl || rootshell == 0)
return;
if (on) {
- fd = open(_PATH_TTY, O_RDWR);
+ int ofd;
+ ofd = fd = open(_PATH_TTY, O_RDWR);
if (fd < 0) {
fd += 3;
while (!isatty(fd))
if (--fd < 0)
goto out;
}
- fd = savefd(fd);
+ fd = savefd(fd, ofd);
do { /* while we are in the background */
if ((pgrp = tcgetpgrp(fd)) < 0) {
out:
#endif
}
col = fmtstr(s, 32, strsignal(st));
+#ifdef WCOREDUMP
if (WCOREDUMP(status)) {
col += fmtstr(s + col, 16, " (core dumped)");
}
+#endif
} else if (!sigonly) {
if (st)
col = fmtstr(s, 16, "Done(%d)", st);
int retval;
struct job *jp;
- EXSIGON();
-
nextopt(nullstr);
retval = 0;
jp->waited = 1;
jp = jp->prev_job;
}
- dowait(DOWAIT_BLOCK, 0);
+ if (dowait(DOWAIT_WAITCMD, 0) <= 0)
+ goto sigout;
}
}
job = getjob(*argv, 0);
/* loop until process terminated or stopped */
while (job->state == JOBRUNNING)
- dowait(DOWAIT_BLOCK, 0);
+ if (dowait(DOWAIT_WAITCMD, 0) <= 0)
+ goto sigout;
job->waited = 1;
retval = getstatus(job);
repeat:
out:
return retval;
+
+sigout:
+ retval = 128 + pendingsigs;
+ goto out;
}
if (is_number(p)) {
num = atoi(p);
- if (num < njobs) {
+ if (num <= njobs) {
jp = jobtab + num - 1;
if (jp->used)
goto gotit;
int pid;
int status;
struct job *jp;
- struct job *thisjob;
+ struct job *thisjob = NULL;
int state;
+ INTOFF;
TRACE(("dowait(%d) called\n", block));
pid = waitproc(block, &status);
TRACE(("wait returns pid %d, status=%d\n", pid, status));
if (pid <= 0)
- return pid;
- INTOFF;
- thisjob = NULL;
+ goto out;
+
for (jp = curjob; jp; jp = jp->prev_job) {
struct procstat *sp;
struct procstat *spend;
STATIC int
waitproc(int block, int *status)
{
-#ifdef BSD
- int flags = 0;
+ sigset_t mask, oldmask;
+ int flags = block == DOWAIT_BLOCK ? 0 : WNOHANG;
+ int err;
#if JOBS
if (jobctl)
flags |= WUNTRACED;
#endif
- if (block == 0)
- flags |= WNOHANG;
- return wait3(status, flags, (struct rusage *)NULL);
-#else
-#ifdef SYSV
- int (*save)();
- if (block == 0) {
- gotsigchild = 0;
- save = signal(SIGCLD, onsigchild);
- signal(SIGCLD, save);
- if (gotsigchild == 0)
- return 0;
- }
- return wait(status);
-#else
- if (block == 0)
- return 0;
- return wait(status);
-#endif
-#endif
+ do {
+ gotsigchld = 0;
+ err = wait3(status, flags, NULL);
+ if (err || !block)
+ break;
+
+ block = 0;
+
+ sigfillset(&mask);
+ sigprocmask(SIG_SETMASK, &mask, &oldmask);
+
+ while (!gotsigchld && !pendingsigs)
+ sigsuspend(&oldmask);
+
+ sigclearmask();
+ } while (gotsigchld);
+
+ return err;
}
/*
STARTSTACKSTR(cmdnextc);
cmdtxt(n);
name = stackblock();
- TRACE(("commandtext: name %p, end %p\n\t\"%s\"\n",
- name, cmdnextc, ps->cmd));
+ TRACE(("commandtext: name %p, end %p\n", name, cmdnextc));
return savestr(name);
}
p = "; done";
goto dodo;
case NDEFUN:
- cmdputs(n->narg.text);
+ cmdputs(n->ndefun.text);
p = "() { ... }";
goto dotail2;
case NCMD: