diff options
Diffstat (limited to 'contrib/tcsh/sh.proc.c')
-rw-r--r-- | contrib/tcsh/sh.proc.c | 667 |
1 files changed, 233 insertions, 434 deletions
diff --git a/contrib/tcsh/sh.proc.c b/contrib/tcsh/sh.proc.c index 62b75af..bf6fb3a 100644 --- a/contrib/tcsh/sh.proc.c +++ b/contrib/tcsh/sh.proc.c @@ -1,4 +1,4 @@ -/* $Header: /src/pub/tcsh/sh.proc.c,v 3.90 2005/03/03 19:57:07 kim Exp $ */ +/* $Header: /p/tcsh/cvsroot/tcsh/sh.proc.c,v 3.104 2006/09/27 16:59:04 mitr Exp $ */ /* * sh.proc.c: Job manipulations */ @@ -32,7 +32,7 @@ */ #include "sh.h" -RCSID("$Id: sh.proc.c,v 3.90 2005/03/03 19:57:07 kim Exp $") +RCSID("$tcsh: sh.proc.c,v 3.104 2006/09/27 16:59:04 mitr Exp $") #include "ed.h" #include "tc.h" @@ -77,6 +77,14 @@ RCSID("$Id: sh.proc.c,v 3.90 2005/03/03 19:57:07 kim Exp $") # endif /* !BSDWAIT */ #endif /* !WCOREDUMP */ +#ifndef JOBDEBUG +# define jobdebug_xprintf(x) (void)0 +# define jobdebug_flush() (void)0 +#else +# define jobdebug_xprintf(s) xprintf s +# define jobdebug_flush() flush() +#endif + /* * C Shell - functions that manage processes, handling hanging, termination */ @@ -106,38 +114,40 @@ static struct tms zru = {0L, 0L, 0L, 0L}, lru = {0L, 0L, 0L, 0L}; # endif /* !_SEQUENT_ */ #endif /* !BSDTIMES */ +#ifndef BSDTIMES +static int timesdone; /* shtimes buffer full ? */ +#endif /* BSDTIMES */ + #ifndef RUSAGE_CHILDREN # define RUSAGE_CHILDREN -1 #endif /* RUSAGE_CHILDREN */ -static void pflushall __P((void)); -static void pflush __P((struct process *)); -static void pfree __P((struct process *)); -static void pclrcurr __P((struct process *)); -static void padd __P((struct command *)); -static int pprint __P((struct process *, int)); -static void ptprint __P((struct process *)); -static void pads __P((Char *)); -static void pkill __P((Char **, int)); -static struct process *pgetcurr __P((struct process *)); -static void okpcntl __P((void)); -static void setttypgrp __P((int)); +static void pflushall (void); +static void pflush (struct process *); +static void pfree (struct process *); +static void pclrcurr (struct process *); +static void padd (struct command *); +static int pprint (struct process *, int); +static void ptprint (struct process *); +static void pads (Char *); +static void pkill (Char **, int); +static struct process *pgetcurr (struct process *); +static void okpcntl (void); +static void setttypgrp (int); /* - * pchild - called at interrupt level by the SIGCHLD signal + * pchild - call queued by the SIGCHLD signal * indicating that at least one child has terminated or stopped * thus at least one wait system call will definitely return a * childs status. Top level routines (like pwait) must be sure * to mask interrupts when playing with the proclist data structures! */ -RETSIGTYPE -/*ARGSUSED*/ -pchild(snum) -int snum; +void +pchild(void) { struct process *pp; struct process *fp; - int pid; + pid_t pid; #ifdef BSDWAIT union wait w; #else /* !BSDWAIT */ @@ -161,33 +171,13 @@ int snum; # endif /* !_SEQUENT_ */ #endif /* !BSDTIMES */ - USE(snum); -#ifdef JOBDEBUG - xprintf("pchild()\n"); -#endif /* JOBDEBUG */ - -/* Christos on where the signal(SIGCHLD, pchild) shoud be: - * - * I think that it should go *after* the wait, unlike most signal handlers. - * - * In release two (for which I have manuals), it says that wait will remove - * the first child from the queue of dead children. - * All the rest of the children that die while in the signal handler of the - * SIGC(H)LD, will be placed in the queue. If signal is called to re-establish - * the signal handler, and there are items in the queue, the process will - * receive another SIGC(H)LD before signal returns. BTW this is from the - * manual page on comp-sim... Maybe it is not applicable to the hp's, but - * I read on the news in comp.unix.wizards or comp.unix.questions yesterday - * that another person was claiming the the signal() call should be after - * the wait(). - */ + jobdebug_xprintf(("pchild()\n")); loop: + jobdebug_xprintf(("Waiting...\n")); + jobdebug_flush(); errno = 0; /* reset, just in case */ -#ifdef JOBDEBUG - xprintf("Waiting...\n"); - flush(); -#endif /* JOBDEBUG */ + #ifndef WINNT_NATIVE # ifdef BSDJOBS # ifdef BSDTIMES @@ -197,7 +187,7 @@ loop: (setintr && (intty || insource) ? WNOHANG | WUNTRACED : WNOHANG), &ru); # else /* both a wait3 and rusage */ -# if !defined(BSDWAIT) || defined(NeXT) || defined(MACH) || defined(linux) || defined(__GNU__) || defined(__GLIBC__) || (defined(IRIS4D) && (__STDC__ || defined(PROTOTYPES)) && SYSVREL <= 3) || defined(__lucid) || defined(__osf__) +# if !defined(BSDWAIT) || defined(NeXT) || defined(MACH) || defined(linux) || defined(__GNU__) || defined(__GLIBC__) || (defined(IRIS4D) && SYSVREL <= 3) || defined(__lucid) || defined(__osf__) pid = wait3(&w, (setintr && (intty || insource) ? WNOHANG | WUNTRACED : WNOHANG), &ru); # else /* BSDWAIT */ @@ -235,7 +225,7 @@ loop: # else /* !BSDTIMES */ # ifdef ODT /* For Sco Unix 3.2.0 or ODT 1.0 */ # define HAVEwait3 - pid = waitpid(-1, &w, + pid = waitpid(-1, &w, (setintr && (intty || insource) ? WNOHANG | WUNTRACED : WNOHANG)); # endif /* ODT */ # if defined(aiws) || defined(uts) @@ -244,50 +234,35 @@ loop: (setintr && (intty || insource) ? WNOHANG | WUNTRACED : WNOHANG), 0); # endif /* aiws || uts */ # ifndef HAVEwait3 -# ifdef UNRELSIGS +# ifndef BSDWAIT /* no wait3, therefore no rusage */ /* on Sys V, this may hang. I hope it's not going to be a problem */ -# ifdef _MINIX - pid = wait(&w); -# else /* !_MINIX */ - pid = ourwait(&w.w_status); -# endif /* _MINIX */ -# else /* !UNRELSIGS */ + pid = wait(&w); +# else /* BSDWAIT */ /* * XXX: for greater than 3 we should use waitpid(). * but then again, SVR4 falls into the POSIX/BSDJOBS category. */ - pid = wait(&w.w_status); -# endif /* !UNRELSIGS */ + pid = wait(&w.w_status); +# endif /* BSDWAIT */ # endif /* !HAVEwait3 */ # endif /* !BSDTIMES */ -# ifndef BSDSIGS - (void) sigset(SIGCHLD, pchild); -# endif /* !BSDSIGS */ # endif /* !BSDJOBS */ #else /* WINNT_NATIVE */ - { - extern int insource; - pid = waitpid(-1, &w, + pid = waitpid(-1, &w, (setintr && (intty || insource) ? WNOHANG | WUNTRACED : WNOHANG)); - } #endif /* WINNT_NATIVE */ -#ifdef JOBDEBUG - xprintf("parent %d pid %d, retval %x termsig %x retcode %x\n", - getpid(), pid, w, WTERMSIG(w), WEXITSTATUS(w)); - flush(); -#endif /* JOBDEBUG */ + jobdebug_xprintf(("parent %d pid %d, retval %x termsig %x retcode %x\n", + (int)getpid(), (int)pid, w, WTERMSIG(w), + WEXITSTATUS(w))); + jobdebug_flush(); if ((pid == 0) || (pid == -1)) { -#ifdef JOBDEBUG - xprintf("errno == %d\n", errno); -#endif /* JOBDEBUG */ - if (errno == EINTR) { - errno = 0; + handle_pending_signals(); + jobdebug_xprintf(("errno == %d\n", errno)); + if (errno == EINTR) goto loop; - } - pnoprocesses = pid == -1; goto end; } for (pp = proclist.p_next; pp != NULL; pp = pp->p_next) @@ -312,12 +287,7 @@ found: # ifdef _SEQUENT_ (void) get_process_stats(&pp->p_etime, PS_SELF, NULL, NULL); # else /* !_SEQUENT_ */ -# ifndef COHERENT pp->p_etime = times(&proctimes); -# else /* COHERENT */ - pp->p_etime = HZ * time(NULL); - times(&proctimes); -# endif /* COHERENT */ # endif /* !_SEQUENT_ */ #else /* BSDTIMES */ (void) gettimeofday(&pp->p_etime, NULL); @@ -399,11 +369,8 @@ found: !eq(dcwd->di_name, fp->p_cwd->di_name))) { /* PWP: print a newline after ^C */ if (jobflags & PINTERRUPTED) { -#ifdef SHORT_STRINGS - xputchar('\r' | QUOTE), xputchar('\n'); -#else /* !SHORT_STRINGS */ - xprintf("\215\n"); /* \215 is a quoted ^M */ -#endif /* !SHORT_STRINGS */ + xputchar('\r' | QUOTE); + xputchar('\n'); } #ifdef notdef else if ((jobflags & (PTIME|PSTOPPED)) == PTIME) @@ -413,38 +380,33 @@ found: } else { if (jobflags & PNOTIFY || adrof(STRnotify)) { -#ifdef SHORT_STRINGS - xputchar('\r' | QUOTE), xputchar('\n'); -#else /* !SHORT_STRINGS */ - xprintf("\215\n"); /* \215 is a quoted ^M */ -#endif /* !SHORT_STRINGS */ + xputchar('\r' | QUOTE); + xputchar('\n'); (void) pprint(pp, NUMBER | NAME | REASON); if ((jobflags & PSTOPPED) == 0) pflush(pp); - { - if (GettingInput) { - errno = 0; - (void) Rawmode(); + if (GettingInput) { + errno = 0; + (void) Rawmode(); #ifdef notdef - /* - * don't really want to do that, because it - * will erase our message in case of multi-line - * input - */ - ClearLines(); + /* + * don't really want to do that, because it + * will erase our message in case of multi-line + * input + */ + ClearLines(); #endif /* notdef */ - ClearDisp(); - Refresh(); - } + ClearDisp(); + Refresh(); } } else { fp->p_flags |= PNEEDNOTE; - neednote++; + neednote = 1; } } } -#if defined(BSDJOBS) || defined(HAVEwait3) +#if defined(BSDJOBS) || defined(HAVEwait3) ||defined(WINNT_NATIVE) goto loop; #endif /* BSDJOBS || HAVEwait3 */ end: @@ -452,45 +414,34 @@ found: } void -pnote() +pnote(void) { struct process *pp; int flags; -#ifdef BSDSIGS - sigmask_t omask; -#endif /* BSDSIGS */ neednote = 0; for (pp = proclist.p_next; pp != NULL; pp = pp->p_next) { if (pp->p_flags & PNEEDNOTE) { -#ifdef BSDSIGS - omask = sigblock(sigmask(SIGCHLD)); -#else /* !BSDSIGS */ - (void) sighold(SIGCHLD); -#endif /* !BSDSIGS */ + pchild_disabled++; + cleanup_push(&pchild_disabled, disabled_cleanup); pp->p_flags &= ~PNEEDNOTE; flags = pprint(pp, NUMBER | NAME | REASON); if ((flags & (PRUNNING | PSTOPPED)) == 0) pflush(pp); -#ifdef BSDSIGS - (void) sigsetmask(omask); -#else /* !BSDSIGS */ - (void) sigrelse(SIGCHLD); -#endif /* !BSDSIGS */ + cleanup_until(&pchild_disabled); } } } static void -pfree(pp) - struct process *pp; +pfree(struct process *pp) { - xfree((ptr_t) pp->p_command); + xfree(pp->p_command); if (pp->p_cwd && --pp->p_cwd->di_count == 0) if (pp->p_cwd->di_next == 0) dfree(pp->p_cwd); - xfree((ptr_t) pp); + xfree(pp); } @@ -499,36 +450,19 @@ pfree(pp) * of current and previous job indicators. */ void -pwait() +pwait(void) { struct process *fp, *pp; -#ifdef BSDSIGS - sigmask_t omask; -#endif /* BSDSIGS */ /* * Here's where dead procs get flushed. */ -#ifdef BSDSIGS - omask = sigblock(sigmask(SIGCHLD)); -#else /* !BSDSIGS */ - (void) sighold(SIGCHLD); -#endif /* !BSDSIGS */ for (pp = (fp = &proclist)->p_next; pp != NULL; pp = (fp = pp)->p_next) if (pp->p_procid == 0) { fp->p_next = pp->p_next; pfree(pp); pp = fp; } -#ifdef BSDSIGS - (void) sigsetmask(omask); -#else /* !BSDSIGS */ - (void) sigrelse(SIGCHLD); -# ifdef notdef - if (setintr) - sigignore(SIGINT); -# endif /* notdef */ -#endif /* !BSDSIGS */ pjwait(pcurrjob); } @@ -538,70 +472,47 @@ pwait() * It is assumed to be in the foreground state (PFOREGND) */ void -pjwait(pp) - struct process *pp; +pjwait(struct process *pp) { struct process *fp; int jobflags, reason; -#ifdef BSDSIGS - sigmask_t omask; -#endif /* BSDSIGS */ -#ifdef UNRELSIGS - signalfun_t inthandler; -#endif /* UNRELSIGS */ + sigset_t oset, set, pause_mask; + Char *reason_str; + while (pp->p_procid != pp->p_jobid) pp = pp->p_friends; fp = pp; do { if ((fp->p_flags & (PFOREGND | PRUNNING)) == PRUNNING) - xprintf(CGETS(17, 1, "BUG: waiting for background job!\n")); + xprintf(CGETS(17, 1, "BUG: waiting for background job!\n")); } while ((fp = fp->p_friends) != pp); /* * Now keep pausing as long as we are not interrupted (SIGINT), and the * target process, or any of its friends, are running */ fp = pp; -#ifdef BSDSIGS - omask = sigblock(sigmask(SIGCHLD)); -#endif /* BSDSIGS */ -#ifdef UNRELSIGS - if (setintr) - inthandler = signal(SIGINT, SIG_IGN); -#endif /* UNRELSIGS */ + sigemptyset(&set); + sigaddset(&set, SIGINT); + sigaddset(&set, SIGCHLD); + (void)sigprocmask(SIG_BLOCK, &set, &oset); + cleanup_push(&oset, sigprocmask_cleanup); + pause_mask = oset; + sigdelset(&pause_mask, SIGCHLD); for (;;) { -#ifndef BSDSIGS - (void) sighold(SIGCHLD); -#endif /* !BSDSIGS */ + handle_pending_signals(); jobflags = 0; do jobflags |= fp->p_flags; while ((fp = (fp->p_friends)) != pp); if ((jobflags & PRUNNING) == 0) break; -#ifdef JOBDEBUG - xprintf("%d starting to sigpause for SIGCHLD on %d\n", - getpid(), fp->p_procid); -#endif /* JOBDEBUG */ -#ifdef BSDSIGS - /* (void) sigpause(sigblock((sigmask_t) 0) &~ sigmask(SIGCHLD)); */ - (void) sigpause(omask & ~sigmask(SIGCHLD)); -#else /* !BSDSIGS */ - (void) sigpause(SIGCHLD); -#endif /* !BSDSIGS */ + jobdebug_xprintf(("%d starting to sigsuspend for SIGCHLD on %d\n", + getpid(), fp->p_procid)); + sigsuspend(&pause_mask); } -#ifdef JOBDEBUG - xprintf("%d returned from sigpause loop\n", getpid()); -#endif /* JOBDEBUG */ -#ifdef BSDSIGS - (void) sigsetmask(omask); -#else /* !BSDSIGS */ - (void) sigrelse(SIGCHLD); -#endif /* !BSDSIGS */ -#ifdef UNRELSIGS - if (setintr) - (void) signal(SIGINT, inthandler); -#endif /* UNRELSIGS */ + cleanup_until(&oset); + jobdebug_xprintf(("%d returned from sigsuspend loop\n", getpid())); #ifdef BSDJOBS if (tpgrp > 0) /* get tty back */ (void) tcsetpgrp(FSHTTY, tpgrp); @@ -650,7 +561,11 @@ pjwait(pp) if ((reason != 0) && (adrof(STRprintexitvalue)) && (pp->p_flags & PBACKQ) == 0) xprintf(CGETS(17, 2, "Exit %d\n"), reason); - set(STRstatus, putn(reason), VAR_READWRITE); + reason_str = putn(reason); + cleanup_push(reason_str, xfree); + setv(STRstatus, reason_str, VAR_READWRITE); + cleanup_ignore(reason_str); + cleanup_until(reason_str); if (reason && exiterr) exitstat(); pflush(pp); @@ -662,42 +577,27 @@ pjwait(pp) /*ARGSUSED*/ void -dowait(v, c) - Char **v; - struct command *c; +dowait(Char **v, struct command *c) { struct process *pp; -#ifdef BSDSIGS - sigmask_t omask; -#endif /* BSDSIGS */ + sigset_t pause_mask; USE(c); USE(v); pjobs++; -#ifdef BSDSIGS - omask = sigblock(sigmask(SIGCHLD)); -loop: -#else /* !BSDSIGS */ + sigprocmask(SIG_BLOCK, NULL, &pause_mask); + sigdelset(&pause_mask, SIGCHLD); if (setintr) - (void) sigrelse(SIGINT); + sigdelset(&pause_mask, SIGINT); loop: - (void) sighold(SIGCHLD); -#endif /* !BSDSIGS */ for (pp = proclist.p_next; pp; pp = pp->p_next) if (pp->p_procid && /* pp->p_procid == pp->p_jobid && */ pp->p_flags & PRUNNING) { -#ifdef BSDSIGS - (void) sigpause((sigmask_t) 0); -#else /* !BSDSIGS */ - (void) sigpause(SIGCHLD); -#endif /* !BSDSIGS */ + handle_pending_signals(); + sigsuspend(&pause_mask); + handle_pending_signals(); goto loop; } -#ifdef BSDSIGS - (void) sigsetmask(omask); -#else /* !BSDSIGS */ - (void) sigrelse(SIGCHLD); -#endif /* !BSDSIGS */ pjobs = 0; } @@ -705,7 +605,7 @@ loop: * pflushall - flush all jobs from list (e.g. at fork()) */ static void -pflushall() +pflushall(void) { struct process *pp; @@ -720,8 +620,7 @@ pflushall() * space is not done here since pflush is called at interrupt level. */ static void -pflush(pp) - struct process *pp; +pflush(struct process *pp) { struct process *np; int idx; @@ -754,8 +653,7 @@ pflush(pp) * pp MUST be the job leader */ static void -pclrcurr(pp) - struct process *pp; +pclrcurr(struct process *pp) { if (pp == pcurrent) { if (pprevious != NULL) { @@ -773,15 +671,14 @@ pclrcurr(pp) /* +4 here is 1 for '\0', 1 ea for << >& >> */ static Char command[PMAXLEN + 4]; -static int cmdlen; +static size_t cmdlen; static Char *cmdp; /* GrP * unparse - Export padd() functionality */ Char * -unparse(t) - struct command *t; +unparse(struct command *t) { cmdp = command; cmdlen = 0; @@ -796,14 +693,12 @@ unparse(t) * an important assumption is made that the process is running. */ void -palloc(pid, t) - int pid; - struct command *t; +palloc(pid_t pid, struct command *t) { struct process *pp; int i; - pp = (struct process *) xcalloc(1, (size_t) sizeof(struct process)); + pp = xcalloc(1, sizeof(struct process)); pp->p_procid = pid; pp->p_flags = ((t->t_dflg & F_AMPERSAND) ? 0 : PFOREGND) | PRUNNING; if (t->t_dflg & F_TIME) @@ -872,20 +767,14 @@ palloc(pid, t) { struct tms tmptimes; -# ifndef COHERENT pp->p_btime = times(&tmptimes); -# else /* !COHERENT */ - pp->p_btime = HZ * time(NULL); - times(&tmptimes); -# endif /* !COHERENT */ } # endif /* !_SEQUENT_ */ #endif /* !BSDTIMES */ } static void -padd(t) - struct command *t; +padd(struct command *t) { Char **argp; @@ -948,10 +837,9 @@ padd(t) } static void -pads(cp) - Char *cp; +pads(Char *cp) { - int i; + size_t i; /* * Avoid the Quoted Space alias hack! Reported by: @@ -960,7 +848,7 @@ pads(cp) if (cp[0] == STRQNULL[0]) cp++; - i = (int) Strlen(cp); + i = Strlen(cp); if (cmdlen >= PMAXLEN) return; @@ -981,19 +869,16 @@ pads(cp) * and `` in globbing. */ void -psavejob() +psavejob(void) { pholdjob = pcurrjob; pcurrjob = NULL; } -/* - * prestjob - opposite of psavejob. This may be missed if we are interrupted - * somewhere, but pendjob cleans up anyway. - */ void -prestjob() +psavejob_cleanup(void *dummy) { + USE(dummy); pcurrjob = pholdjob; pholdjob = NULL; } @@ -1003,7 +888,7 @@ prestjob() * or is about to begin. */ void -pendjob() +pendjob(void) { struct process *pp, *tp; @@ -1034,9 +919,7 @@ pendjob() */ static int -pprint(pp, flag) - struct process *pp; - int flag; +pprint(struct process *pp, int flag) { int status, reason; struct process *tp; @@ -1076,9 +959,9 @@ pprint(pp, flag) * we can search for the next one downstream later. */ } - pcond = (int) (tp != pp || (inpipe && tp == pp)); + pcond = (tp != pp || (inpipe && tp == pp)); #else /* !BACKPIPE */ - pcond = (int) (tp != pp); + pcond = (tp != pp); #endif /* BACKPIPE */ jobflags |= pp->p_flags; @@ -1106,10 +989,6 @@ pprint(pp, flag) xprintf(" "); } if (flag & FANCY) { -#ifdef TCF - extern char *sitename(); - -#endif /* TCF */ xprintf("%5d ", pp->p_procid); #ifdef TCF xprintf("%11s ", sitename(pp->p_procid)); @@ -1143,7 +1022,7 @@ pprint(pp, flag) case PSIGNALED: /* * tell what happened to the background job - * From: Michael Schroeder + * From: Michael Schroeder * <mlschroe@immd4.informatik.uni-erlangen.de> */ if ((flag & REASON) @@ -1151,15 +1030,20 @@ pprint(pp, flag) && reason != SIGINT && (reason != SIGPIPE || (pp->p_flags & PPOU) == 0))) { - const char *ptr; - char buf[1024]; - - if ((ptr = mesg[pp->p_reason & ASCII].pname) == NULL) { - xsnprintf(buf, sizeof(buf), "%s %d", - CGETS(17, 5, "Signal"), pp->p_reason & ASCII); - ptr = buf; + char *ptr; + int free_ptr; + + free_ptr = 0; + ptr = (char *)(intptr_t)mesg[pp->p_reason & 0177].pname; + if (ptr == NULL) { + ptr = xasprintf("%s %d", CGETS(17, 5, "Signal"), + pp->p_reason & 0177); + cleanup_push(ptr, xfree); + free_ptr = 1; } xprintf(format, ptr); + if (free_ptr != 0) + cleanup_until(ptr); } else reason = -1; @@ -1279,8 +1163,7 @@ prcomd: ((tvp)->tv_sec cmp (uvp)->tv_sec)) static void -ptprint(tp) - struct process *tp; +ptprint(struct process *tp) { #ifdef BSDTIMES struct timeval tetime, diff; @@ -1360,9 +1243,7 @@ ptprint(tp) */ /*ARGSUSED*/ void -dojobs(v, c) - Char **v; - struct command *c; +dojobs(Char **v, struct command *c) { struct process *pp; int flag = NUMBER | NAME | REASON; @@ -1391,9 +1272,7 @@ dojobs(v, c) */ /*ARGSUSED*/ void -dofg(v, c) - Char **v; - struct command *c; +dofg(Char **v, struct command *c) { struct process *pp; @@ -1407,12 +1286,6 @@ dofg(v, c) stderror(ERR_NAME|ERR_BADJOB, pp->p_command, strerror(errno)); continue; } -#ifndef BSDSIGS -# ifdef notdef - if (setintr) - sigignore(SIGINT); -# endif -#endif /* !BSDSIGS */ pjwait(pp); } while (*v && *++v); } @@ -1422,9 +1295,7 @@ dofg(v, c) */ /*ARGSUSED*/ void -dofg1(v, c) - Char **v; - struct command *c; +dofg1(Char **v, struct command *c) { struct process *pp; @@ -1436,12 +1307,6 @@ dofg1(v, c) stderror(ERR_NAME|ERR_BADJOB, pp->p_command, strerror(errno)); return; } -#ifndef BSDSIGS -# ifdef notdef - if (setintr) - sigignore(SIGINT); -# endif -#endif /* !BSDSIGS */ pjwait(pp); } @@ -1450,9 +1315,7 @@ dofg1(v, c) */ /*ARGSUSED*/ void -dobg(v, c) - Char **v; - struct command *c; +dobg(Char **v, struct command *c) { struct process *pp; @@ -1473,9 +1336,7 @@ dobg(v, c) */ /*ARGSUSED*/ void -dobg1(v, c) - Char **v; - struct command *c; +dobg1(Char **v, struct command *c) { struct process *pp; @@ -1492,9 +1353,7 @@ dobg1(v, c) */ /*ARGSUSED*/ void -dostop(v, c) - Char **v; - struct command *c; +dostop(Char **v, struct command *c) { USE(c); #ifdef BSDJOBS @@ -1507,9 +1366,7 @@ dostop(v, c) */ /*ARGSUSED*/ void -dokill(v, c) - Char **v; - struct command *c; +dokill(Char **v, struct command *c) { int signum, len = 0; const char *name; @@ -1522,7 +1379,7 @@ dokill(v, c) for (signum = 0; signum <= nsig; signum++) { if ((name = mesg[signum].iname) != NULL) { len += strlen(name) + 1; - if (len >= T_Cols - 1) { + if (len >= TermH - 1) { xputchar('\n'); len = strlen(name) + 1; } @@ -1564,44 +1421,28 @@ gotsig: } static void -pkill(v, signum) - Char **v; - int signum; +pkill(Char **v, int signum) { struct process *pp, *np; int jobflags = 0, err1 = 0; pid_t pid; -#ifdef BSDSIGS - sigmask_t omask; -#endif /* BSDSIGS */ - Char *cp, **vp; + Char *cp, **vp, **globbed; -#ifdef BSDSIGS - omask = sigmask(SIGCHLD); - if (setintr) - omask |= sigmask(SIGINT); - omask = sigblock(omask) & ~omask; -#else /* !BSDSIGS */ - if (setintr) - (void) sighold(SIGINT); - (void) sighold(SIGCHLD); -#endif /* !BSDSIGS */ + pchild_disabled++; + cleanup_push(&pchild_disabled, disabled_cleanup); + if (setintr) { + pintr_disabled++; + cleanup_push(&pintr_disabled, disabled_cleanup); + } /* Avoid globbing %?x patterns */ for (vp = v; vp && *vp; vp++) if (**vp == '%') (void) quote(*vp); - gflag = 0, tglob(v); - if (gflag) { - v = globall(v); - if (v == 0) - stderror(ERR_NAME | ERR_NOMATCH); - } - else { - v = gargv = saveblk(v); - trim(v); - } + v = glob_all_or_error(v); + globbed = v; + cleanup_push(globbed, blk_cleanup); while (v && (cp = *v)) { @@ -1675,15 +1516,7 @@ pkill(v, signum) cont: v++; } - if (gargv) - blkfree(gargv), gargv = 0; -#ifdef BSDSIGS - (void) sigsetmask(omask); -#else /* !BSDSIGS */ - (void) sigrelse(SIGCHLD); - if (setintr) - (void) sigrelse(SIGINT); -#endif /* !BSDSIGS */ + cleanup_until(&pchild_disabled); if (err1) stderror(ERR_SILENT); } @@ -1692,23 +1525,15 @@ cont: * pstart - start the job in foreground/background */ int -pstart(pp, foregnd) - struct process *pp; - int foregnd; +pstart(struct process *pp, int foregnd) { int rv = 0; struct process *np; -#ifdef BSDSIGS - sigmask_t omask; -#endif /* BSDSIGS */ /* We don't use jobflags in this function right now (see below) */ /* long jobflags = 0; */ -#ifdef BSDSIGS - omask = sigblock(sigmask(SIGCHLD)); -#else /* !BSDSIGS */ - (void) sighold(SIGCHLD); -#endif + pchild_disabled++; + cleanup_push(&pchild_disabled, disabled_cleanup); np = pp; do { /* We don't use jobflags in this function right now (see below) */ @@ -1743,7 +1568,7 @@ pstart(pp, foregnd) * 4. pchild() calls wait3(WNOHANG) which returns 0. * The child process is NOT ready to be waited for at this time. * pchild() returns without picking-up the correct status - * for the child process which generated the SIGCHILD. + * for the child process which generated the SIGCHLD. * 5. CONSEQUENCE : csh is UNaware that the process is stopped * 6. THIS LINE HAS BEEN COMMENTED OUT : if (jobflags&PSTOPPED) * (beto@aixwiz.austin.ibm.com - aug/03/91) @@ -1758,17 +1583,12 @@ pstart(pp, foregnd) if (rv != -1) rv = killpg(pp->p_jobid, SIGCONT); #endif /* BSDJOBS */ -#ifdef BSDSIGS - (void) sigsetmask(omask); -#else /* !BSDSIGS */ - (void) sigrelse(SIGCHLD); -#endif /* !BSDSIGS */ + cleanup_until(&pchild_disabled); return rv != -1; } void -panystop(neednl) - int neednl; +panystop(int neednl) { struct process *pp; @@ -1779,8 +1599,7 @@ panystop(neednl) } struct process * -pfind(cp) - Char *cp; +pfind(Char *cp) { struct process *pp, *np; @@ -1834,8 +1653,7 @@ pfind(cp) * pgetcurr - find most recent job that is not pp, preferably stopped */ static struct process * -pgetcurr(pp) - struct process *pp; +pgetcurr(struct process *pp) { struct process *np; struct process *xp = NULL; @@ -1856,9 +1674,7 @@ pgetcurr(pp) */ /*ARGSUSED*/ void -donotify(v, c) - Char **v; - struct command *c; +donotify(Char **v, struct command *c) { struct process *pp; @@ -1867,6 +1683,14 @@ donotify(v, c) pp->p_flags |= PNOTIFY; } +#ifdef SIGSYNCH +static void +synch_handler(int sno) +{ + USE(sno); +} +#endif /* SIGSYNCH */ + /* * Do the fork and whatever should be done in the child side that * should not be done if we are not forking at all (like for simple builtin's) @@ -1879,20 +1703,14 @@ donotify(v, c) * It is usually just the value of tpgrp. */ -int -pfork(t, wanttty) - struct command *t; /* command we are forking for */ - int wanttty; +pid_t +pfork(struct command *t, int wanttty) { - int pid; + pid_t pid; int ignint = 0; - int pgrp; -#ifdef BSDSIGS - sigmask_t omask = 0; -#endif /* BSDSIGS */ + pid_t pgrp; #ifdef SIGSYNCH - sigvec_t osv; - static sigvec_t nsv = {synch_handler, (sigset_t) ~0, 0}; + struct sigaction osa, nsa; #endif /* SIGSYNCH */ /* @@ -1907,43 +1725,33 @@ pfork(t, wanttty) ignint = (tpgrp == -1 && (t->t_dflg & F_NOINTERRUPT)) || (gointr && eq(gointr, STRminus)); -#ifdef COHERENT - ignint |= gointr && eq(gointr, STRminus); -#endif /* COHERENT */ - /* * Check for maximum nesting of 16 processes to avoid Forking loops */ if (child == 16) stderror(ERR_NESTING, 16); #ifdef SIGSYNCH - if (mysigvec(SIGSYNCH, &nsv, &osv)) - stderror(ERR_SYSTEM, "pfork: sigvec set", strerror(errno)); + nsa.sa_handler = synch_handler; + sigfillset(&nsa.sa_mask); + nsa.sa_flags = SA_RESTART; + if (sigaction(SIGSYNCH, &nsa, &osa)) + stderror(ERR_SYSTEM, "pfork: sigaction set", strerror(errno)); #endif /* SIGSYNCH */ /* - * Hold SIGCHLD until we have the process installed in our table. + * Hold pchild() until we have the process installed in our table. */ if (wanttty < 0) { -#ifdef BSDSIGS - omask = sigblock(sigmask(SIGCHLD)); -#else /* !BSDSIGS */ - (void) sighold(SIGCHLD); -#endif /* !BSDSIGS */ + pchild_disabled++; + cleanup_push(&pchild_disabled, disabled_cleanup); } while ((pid = fork()) == -1) if (setintr == 0) (void) sleep(FORKSLEEP); - else { - if (wanttty < 0) -#ifdef BSDSIGS - (void) sigsetmask(omask); -#else /* !BSDSIGS */ - (void) sigrelse(SIGCHLD); - (void) sigrelse(SIGINT); -#endif /* !BSDSIGS */ + else stderror(ERR_NOPROC); - } if (pid == 0) { + (void)cleanup_push_mark(); /* Never to be popped */ + pchild_disabled = 0; settimes(); pgrp = pcurrjob ? pcurrjob->p_jobid : getpid(); pflushall(); @@ -1954,10 +1762,6 @@ pfork(t, wanttty) child++; if (setintr) { setintr = 0; /* until I think otherwise */ -#ifndef BSDSIGS - if (wanttty < 0) - (void) sigrelse(SIGCHLD); -#endif /* !BSDSIGS */ /* * Children just get blown away on SIGINT, SIGQUIT unless "onintr * -" seen. @@ -1972,14 +1776,14 @@ pfork(t, wanttty) (void) signal(SIGTTOU, SIG_DFL); } #endif /* BSDJOBS */ - (void) signal(SIGTERM, parterm); + sigaction(SIGTERM, &parterm, NULL); } else if (tpgrp == -1 && (t->t_dflg & F_NOINTERRUPT)) { (void) signal(SIGINT, SIG_IGN); (void) signal(SIGQUIT, SIG_IGN); } #ifdef OREO - sigignore(SIGIO); /* ignore SIGIO in child too */ + signal(SIGIO, SIG_IGN); /* ignore SIGIO in child too */ #endif /* OREO */ pgetty(wanttty, pgrp); @@ -1994,7 +1798,7 @@ pfork(t, wanttty) int nval = SIGN_EXTEND_CHAR(t->t_nice); #ifdef HAVE_SETPRIORITY if (setpriority(PRIO_PROCESS, 0, nval) == -1 && errno) - stderror(ERR_SYSTEM, "setpriority", strerror(errno)); + stderror(ERR_SYSTEM, "setpriority", strerror(errno)); #else /* !HAVE_SETPRIORITY */ (void) nice(nval); #endif /* !HAVE_SETPRIORITY */ @@ -2036,6 +1840,9 @@ pfork(t, wanttty) #endif /* POSIXJOBS */ palloc(pid, t); #ifdef SIGSYNCH + { + sigset_t pause_mask; + /* * rfw 8/89 Wait for child to own terminal. Solves half of ugly * synchronization problem. With this change, we know that the only @@ -2044,25 +1851,25 @@ pfork(t, wanttty) * either have exited or not yet started to run. Two uglies become * one. */ - (void) sigpause(omask & ~SYNCHMASK); - if (mysigvec(SIGSYNCH, &osv, NULL)) - stderror(ERR_SYSTEM, "pfork parent: sigvec restore", - strerror(errno)); + sigprocmask(SIG_BLOCK, NULL, &pause); + sigdelset(&pause_mask, SIGCHLD); + sigdelset(&pause_mask, SIGSYNCH); + sigsuspend(&pause_mask); + handle_pending_signals(); + if (sigaction(SIGSYNCH, &osa, NULL)) + stderror(ERR_SYSTEM, "pfork parent: sigaction restore", + strerror(errno)); + } #endif /* SIGSYNCH */ - if (wanttty < 0) { -#ifdef BSDSIGS - (void) sigsetmask(omask); -#else /* !BSDSIGS */ - (void) sigrelse(SIGCHLD); -#endif /* !BSDSIGS */ - } + if (wanttty < 0) + cleanup_until(&pchild_disabled); } return (pid); } static void -okpcntl() +okpcntl(void) { if (tpgrp == -1) stderror(ERR_JOBCONTROL); @@ -2072,8 +1879,7 @@ okpcntl() static void -setttypgrp(pgrp) - int pgrp; +setttypgrp(int pgrp) { /* * If we are piping out a builtin, eg. 'echo | more' things can go @@ -2090,15 +1896,18 @@ setttypgrp(pgrp) */ if (tcgetpgrp(FSHTTY) != pgrp) { #ifdef POSIXJOBS + struct sigaction old; + /* * tcsetpgrp will set SIGTTOU to all the the processes in * the background according to POSIX... We ignore this here. */ - signalfun_t old = sigset(SIGTTOU, SIG_IGN); + sigaction(SIGTTOU, NULL, &old); + signal(SIGTTOU, SIG_IGN); #endif (void) tcsetpgrp(FSHTTY, pgrp); # ifdef POSIXJOBS - (void) sigset(SIGTTOU, old); + sigaction(SIGTTOU, &old, NULL); # endif } @@ -2114,32 +1923,28 @@ setttypgrp(pgrp) * I am open to suggestions how to fix that. */ void -pgetty(wanttty, pgrp) - int wanttty, pgrp; +pgetty(int wanttty, pid_t pgrp) { #ifdef BSDJOBS -# if defined(BSDSIGS) && defined(POSIXJOBS) - sigmask_t omask = 0; -# endif /* BSDSIGS && POSIXJOBS */ - -# ifdef JOBDEBUG - xprintf("wanttty %d pid %d opgrp%d pgrp %d tpgrp %d\n", - wanttty, getpid(), pgrp, mygetpgrp(), tcgetpgrp(FSHTTY)); -# endif /* JOBDEBUG */ +# ifdef POSIXJOBS + sigset_t oset, set; +# endif /* POSIXJOBS */ + + jobdebug_xprintf(("wanttty %d pid %d opgrp%d pgrp %d tpgrp %d\n", + wanttty, (int)getpid(), (int)pgrp, (int)mygetpgrp(), + (int)tcgetpgrp(FSHTTY))); # ifdef POSIXJOBS /* * christos: I am blocking the tty signals till I've set things * correctly.... */ - if (wanttty > 0) -# ifdef BSDSIGS - omask = sigblock(sigmask(SIGTSTP)|sigmask(SIGTTIN)); -# else /* !BSDSIGS */ - { - (void) sighold(SIGTSTP); - (void) sighold(SIGTTIN); + if (wanttty > 0) { + sigemptyset(&set); + sigaddset(&set, SIGTSTP); + sigaddset(&set, SIGTTIN); + (void)sigprocmask(SIG_BLOCK, &set, &oset); + cleanup_push(&oset, sigprocmask_cleanup); } -# endif /* !BSDSIGS */ # endif /* POSIXJOBS */ # ifndef POSIXJOBS @@ -2171,20 +1976,14 @@ pgetty(wanttty, pgrp) } # ifdef POSIXJOBS - if (wanttty > 0) + if (wanttty > 0) { setttypgrp(pgrp); -# ifdef BSDSIGS - (void) sigsetmask(omask); -# else /* BSDSIGS */ - (void) sigrelse(SIGTSTP); - (void) sigrelse(SIGTTIN); -# endif /* !BSDSIGS */ + cleanup_until(&oset); + } # endif /* POSIXJOBS */ -# ifdef JOBDEBUG - xprintf("wanttty %d pid %d pgrp %d tpgrp %d\n", - wanttty, getpid(), mygetpgrp(), tcgetpgrp(FSHTTY)); -# endif /* JOBDEBUG */ + jobdebug_xprintf(("wanttty %d pid %d pgrp %d tpgrp %d\n", + wanttty, getpid(), mygetpgrp(), tcgetpgrp(FSHTTY))); if (tpgrp > 0) tpgrp = 0; /* gave tty away */ |