Date: Thu, 22 May 1997 22:55:26 -0700 (PDT) From: dholland@eecs.harvard.edu To: freebsd-gnats-submit@FreeBSD.ORG Subject: bin/3668: /bin/sh knows too much about wait() Message-ID: <199705230555.WAA02625@hub.freebsd.org> Resent-Message-ID: <199705230600.XAA02744@hub.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 3668 >Category: bin >Synopsis: /bin/sh knows too much about wait() >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-bugs >State: open >Class: change-request >Submitter-Id: current-users >Arrival-Date: Thu May 22 23:00:01 PDT 1997 >Last-Modified: >Originator: David A. Holland >Organization: VINO, Harvard University >Release: see below >Environment: N/A >Description: sh knows too much about the bit fields returned by wait(), instead of using the WIF... macros in <sys/wait.h>. This means if you change the bit fields (eg to support >256 signals), sh breaks in strange ways. This problem was found in netbsd's sh but apparently applies to freebsd too, so I'm sending the patch along. >How-To-Repeat: n/a >Fix: If this patch has been garbaged by netscape or other web stuff please mail me for a fixed copy. :-/ also please note that the patch is in fact against netbsd and I haven't tried applying it to freebsd's sh. Index: jobs.c =================================================================== RCS file: /home/vino/repo/src/utils/bsd/bin/sh/jobs.c,v retrieving revision 1.1.1.1 diff -u -3 -r1.1.1.1 jobs.c --- jobs.c 1997/04/10 18:32:45 1.1.1.1 +++ jobs.c 1997/05/22 22:07:22 @@ -241,7 +241,7 @@ INTOFF; killpg(jp->ps[0].pid, SIGCONT); for (ps = jp->ps, i = jp->nprocs ; --i >= 0 ; ps++) { - if ((ps->status & 0377) == 0177) { + if (WIFSTOPPED(ps->status)) { ps->status = -1; jp->state = 0; } @@ -304,19 +304,21 @@ if (ps->status == -1) { /* don't print anything */ - } else if ((ps->status & 0xFF) == 0) { - fmtstr(s, 64, "Exit %d", ps->status >> 8); + } else if (WIFEXITED(ps->status)) { + fmtstr(s, 64, "Exit %d", + WEXITSTATUS(ps->status)); } else { - i = ps->status; #if JOBS - if ((i & 0xFF) == 0177) - i >>= 8; + if (WIFSTOPPED(ps->status)) + i = WSTOPSIG(ps->status); + else /* WIFSIGNALED(ps->status) */ #endif + i = WTERMSIG(ps->status); if ((i & 0x7F) < NSIG && sys_siglist[i & 0x7F]) scopy(sys_siglist[i & 0x7F], s); else fmtstr(s, 64, "Signal %d", i & 0x7F); - if (i & 0x80) + if (WCOREDUMP(ps->status)) strcat(s, " (core dumped)"); } out1str(s); @@ -372,7 +374,7 @@ char **argv; { struct job *job; - int status; + int status, retval; struct job *jp; if (argc > 1) { @@ -384,17 +386,19 @@ if (job != NULL) { if (job->state) { status = job->ps[job->nprocs - 1].status; - if ((status & 0xFF) == 0) - status = status >> 8 & 0xFF; + if (WIFEXITED(status)) + retval = WEXITSTATUS(status); #if JOBS - else if ((status & 0xFF) == 0177) - status = (status >> 8 & 0x7F) + 128; + else if (WIFSTOPPED(status)) + retval = WSTOPSIG(status) + 128; #endif - else - status = (status & 0x7F) + 128; + else { + /* XXX */ + retval = WTERMSIG(status) + 128; + } if (! iflag) freejob(job); - return status; + return retval; } } else { for (jp = jobtab ; ; jp++) { @@ -713,18 +717,18 @@ #endif status = jp->ps[jp->nprocs - 1].status; /* convert to 8 bits */ - if ((status & 0xFF) == 0) - st = status >> 8 & 0xFF; + if (WIFEXITED(status)) + st = WEXITSTATUS(status); #if JOBS - else if ((status & 0xFF) == 0177) - st = (status >> 8 & 0x7F) + 128; + else if (WIFSTOPPED(status)) + st = WSTOPSIG(status) + 128; #endif else - st = (status & 0x7F) + 128; + st = WTERMSIG(status) + 128; if (! JOBS || jp->state == JOBDONE) freejob(jp); CLEAR_PENDING_INT; - if ((status & 0x7F) == SIGINT) + if (WIFSIGNALED(status) && WTERMSIG(status) == SIGINT) kill(getpid(), SIGINT); INTON; return st; @@ -749,6 +753,7 @@ int done; int stopped; int core; + int sig; TRACE(("dowait(%d) called\n", block)); do { @@ -767,13 +772,13 @@ if (sp->pid == -1) continue; if (sp->pid == pid) { - TRACE(("Changin status of proc %d from 0x%x to 0x%x\n", pid, sp->status, status)); + TRACE(("Changing status of proc %d from 0x%x to 0x%x\n", pid, sp->status, status)); sp->status = status; thisjob = jp; } if (sp->status == -1) stopped = 0; - else if ((sp->status & 0377) == 0177) + else if (WIFSTOPPED(sp->status)) done = 0; } if (stopped) { /* stopped or done */ @@ -791,29 +796,32 @@ } INTON; if (! rootshell || ! iflag || (job && thisjob == job)) { + core = WCOREDUMP(status); #if JOBS - if ((status & 0xFF) == 0177) - status >>= 8; + if (WIFSTOPPED(status)) sig = WSTOPSIG(status); + else #endif - core = status & 0x80; - status &= 0x7F; - if (status != 0 && status != SIGINT && status != SIGPIPE) { + if (WIFEXITED(status)) sig = 0; + else sig = WTERMSIG(status); + + if (sig != 0 && sig != SIGINT && sig != SIGPIPE) { if (thisjob != job) outfmt(out2, "%d: ", pid); #if JOBS - if (status == SIGTSTP && rootshell && iflag) + if (sig == SIGTSTP && rootshell && iflag) outfmt(out2, "%%%d ", job - jobtab + 1); #endif - if (status < NSIG && sys_siglist[status]) - out2str(sys_siglist[status]); + if (sig < NSIG && sys_siglist[sig]) + out2str(sys_siglist[sig]); else - outfmt(out2, "Signal %d", status); + outfmt(out2, "Signal %d", sig); if (core) out2str(" - core dumped"); out2c('\n'); flushout(&errout); } else { - TRACE(("Not printing status: status=%d\n", status)); + TRACE(("Not printing status: status=%d, sig=%d\n", + status, sig)); } } else { TRACE(("Not printing status, rootshell=%d, job=0x%x\n", rootshell, job)); >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199705230555.WAA02625>