diff options
Diffstat (limited to 'shells/pdksh/files/jobs.c')
-rw-r--r-- | shells/pdksh/files/jobs.c | 136 |
1 files changed, 60 insertions, 76 deletions
diff --git a/shells/pdksh/files/jobs.c b/shells/pdksh/files/jobs.c index 2b3a63b9e72..fd17dc153f0 100644 --- a/shells/pdksh/files/jobs.c +++ b/shells/pdksh/files/jobs.c @@ -1,3 +1,5 @@ +/* $NetBSD: jobs.c,v 1.2 2008/05/31 16:47:36 tnn Exp $ */ + /* * Process and job control */ @@ -13,7 +15,7 @@ * * Notes regarding the copious ifdefs: * - JOB_SIGS is independent of JOBS - it is defined if there are modern - * signal and wait routines available. This is prefered, even when + * signal and wait routines available. This is preferred, even when * JOBS is not defined, since the shell will not otherwise notice when * background jobs die until the shell waits for a foreground process * to die. @@ -21,6 +23,12 @@ * process groups * - NEED_PGRP_SYNC defined iff JOBS is defined - see comment below */ +#include <sys/cdefs.h> + +#ifndef lint +__RCSID("$NetBSD: jobs.c,v 1.2 2008/05/31 16:47:36 tnn Exp $"); +#endif + #include "sh.h" #include "ksh_stat.h" @@ -121,7 +129,7 @@ struct proc { #define JF_CHANGED 0x040 /* process has changed state */ #define JF_KNOWN 0x080 /* $! referenced */ #define JF_ZOMBIE 0x100 /* known, unwaited process */ -#define JF_REMOVE 0x200 /* flaged for removal (j_jobs()/j_noityf()) */ +#define JF_REMOVE 0x200 /* flagged for removal (j_jobs()/j_noityf()) */ #define JF_USETTYMODE 0x400 /* tty mode saved if process exits normally */ #define JF_SAVEDTTYPGRP 0x800 /* j->saved_ttypgrp is valid */ @@ -219,8 +227,7 @@ static Proc *new_proc ARGS((void)); static void check_job ARGS((Job *j)); static void put_job ARGS((Job *j, int where)); static void remove_job ARGS((Job *j, const char *where)); -static void kill_job ARGS((Job *j)); -static void fill_command ARGS((char *c, int len, struct op *t)); +static int kill_job ARGS((Job *j, int sig)); /* initialize job control */ void @@ -294,10 +301,17 @@ j_exit() && procpid == kshpid))))) { killed = 1; - killpg(j->pgrp, SIGHUP); + if (j->pgrp == 0) + kill_job(j, SIGHUP); + else + killpg(j->pgrp, SIGHUP); #ifdef JOBS - if (j->state == PSTOPPED) - killpg(j->pgrp, SIGCONT); + if (j->state == PSTOPPED) { + if (j->pgrp == 0) + kill_job(j, SIGCONT); + else + killpg(j->pgrp, SIGCONT); + } #endif /* JOBS */ } } @@ -497,7 +511,7 @@ exchild(t, flags, close_fd) put_job(j, PJ_PAST_STOPPED); } - fill_command(p->command, sizeof(p->command), t); + snptreef(p->command, sizeof(p->command), "%T", t); /* create child process */ forksleep = 1; @@ -508,7 +522,7 @@ exchild(t, flags, close_fd) forksleep <<= 1; } if (i < 0) { - kill_job(j); + kill_job(j, SIGKILL); remove_job(j, "fork failed"); #ifdef NEED_PGRP_SYNC if (j_sync_open) { @@ -621,8 +635,10 @@ exchild(t, flags, close_fd) SS_RESTORE_IGN|SS_FORCE); if (!(flags & (XPIPEI | XCOPROC))) { int fd = open("/dev/null", 0); - (void) ksh_dup2(fd, 0, TRUE); - close(fd); + if (fd != 0) { + (void) ksh_dup2(fd, 0, TRUE); + close(fd); + } } } remove_job(j, "child"); /* in case of `jobs` command */ @@ -805,7 +821,6 @@ j_kill(cp, sig) int sig; { Job *j; - Proc *p; int rv = 0; int ecode; #ifdef JOB_SIGS @@ -823,11 +838,10 @@ j_kill(cp, sig) } if (j->pgrp == 0) { /* started when !Flag(FMONITOR) */ - for (p=j->proc_list; p != (Proc *) 0; p = p->next) - if (kill(p->pid, sig) < 0) { - bi_errorf("%s: %s", cp, strerror(errno)); - rv = 1; - } + if (kill_job(j, sig) < 0) { + bi_errorf("%s: %s", cp, strerror(errno)); + rv = 1; + } } else { #ifdef JOBS if (j->state == PSTOPPED && (sig == SIGTERM || sig == SIGHUP)) @@ -1070,7 +1084,7 @@ j_notify() #endif /* JOB_SIGS */ } -/* Return pid of last process in last asynchornous job */ +/* Return pid of last process in last asynchronous job */ pid_t j_async() { @@ -1214,7 +1228,7 @@ j_waitj(j, flags, where) * a fork/exec instead of an exec (the fork means * the execed shell gets a different pid from its * pgrp, so naturally it sets its pgrp and gets hosed - * when it gets forgrounded by the parent shell, which + * when it gets foregrounded by the parent shell, which * has restored the tty's pgrp to that of the su * process). */ @@ -1282,7 +1296,7 @@ j_waitj(j, flags, where) j_systime = j->systime; rv = j->status; - if (!(flags & JW_ASYNCNOTIFY) + if (!(flags & JW_ASYNCNOTIFY) && (!Flag(FMONITOR) || j->state != PSTOPPED)) { j_print(j, JP_SHORT, shl_out); @@ -1423,12 +1437,12 @@ check_job(j) #ifdef KSH /* Note when co-process dies: can't be done in j_wait() nor - * remove_job() since neither may be called for non-interactive + * remove_job() since neither may be called for non-interactive * shells. */ if (j->state == PEXITED || j->state == PSIGNALLED) { /* No need to keep co-process input any more - * (at leasst, this is what ksh93d thinks) + * (at least, this is what ksh93d thinks) */ if (coproc.job == j) { coproc.job = (void *) 0; @@ -1530,16 +1544,17 @@ j_print(j, how, shf) coredumped = 0; switch (p->state) { case PRUNNING: - strcpy(buf, "Running"); + strlcpy(buf, "Running", sizeof buf); break; case PSTOPPED: - strcpy(buf, sigtraps[WSTOPSIG(p->status)].mess); + strlcpy(buf, sigtraps[WSTOPSIG(p->status)].mess, + sizeof buf); break; case PEXITED: if (how == JP_SHORT) buf[0] = '\0'; else if (WEXITSTATUS(p->status) == 0) - strcpy(buf, "Done"); + strlcpy(buf, "Done", sizeof buf); else shf_snprintf(buf, sizeof(buf), "Done (%d)", WEXITSTATUS(p->status)); @@ -1555,15 +1570,17 @@ j_print(j, how, shf) || WTERMSIG(p->status) == SIGPIPE)) { buf[0] = '\0'; } else - strcpy(buf, sigtraps[WTERMSIG(p->status)].mess); + strlcpy(buf, sigtraps[WTERMSIG(p->status)].mess, + sizeof buf); break; } - if (how != JP_SHORT) + if (how != JP_SHORT) { if (p == j->proc_list) shf_fprintf(shf, "[%d] %c ", j->job, jobchar); else shf_fprintf(shf, "%s", filler); + } if (how == JP_LONG) shf_fprintf(shf, "%5d ", p->pid); @@ -1635,27 +1652,27 @@ j_lookup(cp, ecodep) return (Job *) 0; } switch (*++cp) { - case '\0': /* non-standard */ - case '+': - case '%': + case '\0': /* non-standard */ + case '+': + case '%': if (job_list != (Job *) 0) return job_list; break; - case '-': + case '-': if (job_list != (Job *) 0 && job_list->next) return job_list->next; break; - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': job = atoi(cp); for (j = job_list; j != (Job *) 0; j = j->next) if (j->job == job) return j; break; - case '?': /* %?string */ + case '?': /* %?string */ last_match = (Job *) 0; for (j = job_list; j != (Job *) 0; j = j->next) for (p = j->proc_list; p != (Proc *) 0; p = p->next) @@ -1671,7 +1688,7 @@ j_lookup(cp, ecodep) return last_match; break; - default: /* %string */ + default: /* %string */ len = strlen(cp); last_match = (Job *) 0; for (j = job_list; j != (Job *) 0; j = j->next) @@ -1723,7 +1740,7 @@ new_job() return newj; } -/* Allocate new process strut +/* Allocate new process struct * * If jobs are compiled in then this routine expects sigchld to be blocked. */ @@ -1825,50 +1842,17 @@ put_job(j, where) * * If jobs are compiled in then this routine expects sigchld to be blocked. */ -static void -kill_job(j) +static int +kill_job(j, sig) Job *j; + int sig; { Proc *p; + int rval = 0; for (p = j->proc_list; p != (Proc *) 0; p = p->next) if (p->pid != 0) - (void) kill(p->pid, SIGKILL); -} - -/* put a more useful name on a process than snptreef does (in certain cases) */ -static void -fill_command(c, len, t) - char *c; - int len; - struct op *t; -{ - int alen; - char **ap; - - if (t->type == TEXEC || t->type == TCOM) { - /* Causes problems when set -u is in effect, can also - cause problems when array indices evaluated (may have - side effects, eg, assignment, incr, etc.) - if (t->type == TCOM) - ap = eval(t->args, DOBLANK|DONTRUNCOMMAND); - else - */ - ap = t->args; - --len; /* save room for the null */ - while (len > 0 && *ap != (char *) 0) { - alen = strlen(*ap); - if (alen > len) - alen = len; - memcpy(c, *ap, alen); - c += alen; - len -= alen; - if (len > 0) { - *c++ = ' '; len--; - } - ap++; - } - *c = '\0'; - } else - snptreef(c, len, "%T", t); + if (kill(p->pid, sig) < 0) + rval = -1; + return rval; } |