summaryrefslogtreecommitdiff
path: root/shells/pdksh/files/jobs.c
diff options
context:
space:
mode:
Diffstat (limited to 'shells/pdksh/files/jobs.c')
-rw-r--r--shells/pdksh/files/jobs.c136
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;
}