]> rtime.felk.cvut.cz Git - l4.git/blobdiff - l4/pkg/dash/contrib/src/jobs.c
Update
[l4.git] / l4 / pkg / dash / contrib / src / jobs.c
index 2b6a752a71069bdf22b7a35d1378a6348a4f7667..c2c2332a25fa509a32ddc1b2603528d7f123e95b 100644 (file)
@@ -36,7 +36,9 @@
 #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
@@ -75,6 +77,7 @@
 /* mode flags for dowait */
 #define DOWAIT_NORMAL 0
 #define DOWAIT_BLOCK 1
+#define DOWAIT_WAITCMD 2
 
 /* array of jobs */
 static struct job *jobtab;
@@ -188,14 +191,15 @@ setjobctl(int on)
        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:
@@ -424,9 +428,11 @@ sprint_status(char *s, int status, int sigonly)
 #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);
@@ -589,8 +595,6 @@ waitcmd(int argc, char **argv)
        int retval;
        struct job *jp;
 
-       EXSIGON();
-
        nextopt(nullstr);
        retval = 0;
 
@@ -609,7 +613,8 @@ waitcmd(int argc, char **argv)
                                jp->waited = 1;
                                jp = jp->prev_job;
                        }
-                       dowait(DOWAIT_BLOCK, 0);
+                       if (dowait(DOWAIT_WAITCMD, 0) <= 0)
+                               goto sigout;
                }
        }
 
@@ -631,7 +636,8 @@ start:
                        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:
@@ -640,6 +646,10 @@ repeat:
 
 out:
        return retval;
+
+sigout:
+       retval = 128 + pendingsigs;
+       goto out;
 }
 
 
@@ -689,7 +699,7 @@ check:
 
        if (is_number(p)) {
                num = atoi(p);
-               if (num < njobs) {
+               if (num <= njobs) {
                        jp = jobtab + num - 1;
                        if (jp->used)
                                goto gotit;
@@ -998,16 +1008,16 @@ dowait(int block, struct job *job)
        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;
@@ -1115,34 +1125,33 @@ STATIC int onsigchild() {
 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;
 }
 
 /*
@@ -1184,8 +1193,7 @@ commandtext(union node *n)
        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);
 }
 
@@ -1280,7 +1288,7 @@ dotail:
                p = "; done";
                goto dodo;
        case NDEFUN:
-               cmdputs(n->narg.text);
+               cmdputs(n->ndefun.text);
                p = "() { ... }";
                goto dotail2;
        case NCMD: