summaryrefslogtreecommitdiff
path: root/bin/ksh/jobs.c
diff options
context:
space:
mode:
authorJason Downs <downsj@cvs.openbsd.org>1996-08-19 20:09:10 +0000
committerJason Downs <downsj@cvs.openbsd.org>1996-08-19 20:09:10 +0000
commite7e852656e3beb5f62f8c146ba24004cfda2cf88 (patch)
treeb312bc3e985b3f1cf19691c779e7870219573b6e /bin/ksh/jobs.c
parent1e9e82f84b5de8bcd110c41c780f476397c385d9 (diff)
update to pdksh-5.2.8
Diffstat (limited to 'bin/ksh/jobs.c')
-rw-r--r--bin/ksh/jobs.c77
1 files changed, 46 insertions, 31 deletions
diff --git a/bin/ksh/jobs.c b/bin/ksh/jobs.c
index d40a092ac4b..e1c11fcd04a 100644
--- a/bin/ksh/jobs.c
+++ b/bin/ksh/jobs.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: jobs.c,v 1.1 1996/08/14 06:19:11 downsj Exp $ */
+/* $OpenBSD: jobs.c,v 1.2 1996/08/19 20:08:52 downsj Exp $ */
/*
* Process and job control
@@ -140,6 +140,7 @@ struct job {
clock_t usrtime; /* user time used by job */
Proc *proc_list; /* process list */
Proc *last_proc; /* last process in list */
+ Coproc_id coproc_id; /* 0 or id of coprocess output pipe */
#ifdef TTY_PGRP
TTY_state ttystate; /* saved tty state for stopped jobs */
#endif /* TTY_PGRP */
@@ -177,7 +178,6 @@ static int child_max; /* CHILD_MAX */
#ifdef JOB_SIGS
-static sigset_t sm_default, sm_sigchld;
/* held_sigchld is set if sigchld occurs before a job is completely started */
static int held_sigchld;
#endif /* JOB_SIGS */
@@ -234,7 +234,8 @@ j_init(mflagset)
sigemptyset(&sm_sigchld);
sigaddset(&sm_sigchld, SIGCHLD);
- setsig(&sigtraps[SIGCHLD], j_sigchld, SS_RESTORE_ORIG|SS_FORCE);
+ setsig(&sigtraps[SIGCHLD], j_sigchld,
+ SS_RESTORE_ORIG|SS_FORCE|SS_SHTRAP);
#else /* JOB_SIGS */
/* Make sure SIGCHLD isn't ignored - can do odd things under SYSV */
setsig(&sigtraps[SIGCHLD], SIG_DFL, SS_RESTORE_ORIG|SS_FORCE);
@@ -253,9 +254,12 @@ j_init(mflagset)
if (Flag(FMONITOR) || Flag(FTALKING)) {
int i;
- /* j_change() sets these to SS_RESTORE_DFL if FMONITOR */
+ /* the TF_SHELL_USES test is a kludge that lets us know if
+ * if the signals have been changed by the shell.
+ */
for (i = NELEM(tt_sigs); --i >= 0; ) {
sigtraps[tt_sigs[i]].flags |= TF_SHELL_USES;
+ /* j_change() sets this to SS_RESTORE_DFL if FMONITOR */
setsig(&sigtraps[tt_sigs[i]], SIG_IGN,
SS_RESTORE_IGN|SS_FORCE);
}
@@ -397,9 +401,6 @@ j_change()
} else {
# ifdef TTY_PGRP
ttypgrp_ok = 0;
- /* the TF_SHELL_USES test is a kludge that lets us know if
- * if the signals have been changed by the shell.
- */
if (Flag(FTALKING))
for (i = NELEM(tt_sigs); --i >= 0; )
setsig(&sigtraps[tt_sigs[i]], SIG_IGN,
@@ -410,7 +411,7 @@ j_change()
|TF_ORIG_DFL))
setsig(&sigtraps[tt_sigs[i]],
(sigtraps[tt_sigs[i]].flags & TF_ORIG_IGN) ? SIG_IGN : SIG_DFL,
- SS_RESTORE_CURR|SS_FORCE);
+ SS_RESTORE_ORIG|SS_FORCE);
}
# endif /* TTY_PGRP */
if (!Flag(FTALKING))
@@ -483,12 +484,9 @@ exchild(t, flags, close_fd)
j->ppid = procpid;
j->age = ++njobs;
j->proc_list = p;
+ j->coproc_id = 0;
last_job = j;
last_proc = p;
- if (flags & XXCOM)
- j->flags |= JF_XXCOM;
- else if (!(flags & XBGND))
- j->flags |= JF_FG;
put_job(j, PJ_PAST_STOPPED);
}
@@ -535,8 +533,8 @@ exchild(t, flags, close_fd)
dotty = 1;
# ifdef NEED_PGRP_SYNC
if (j_sync_open) {
- close(j_sync_pipe[ischild ? 1 : 0]);
- j_sync_pipe[ischild ? 1 : 0] = -1;
+ close(j_sync_pipe[ischild]);
+ j_sync_pipe[ischild] = -1;
dosync = ischild;
}
# endif /* NEED_PGRP_SYNC */
@@ -571,18 +569,19 @@ exchild(t, flags, close_fd)
#endif /* JOBS */
/* used to close pipe input fd */
- if (close_fd >= 0 && (((orig_flags & XPCLOSE) && i != 0)
- || ((orig_flags & XCCLOSE) && i == 0)))
+ if (close_fd >= 0 && (((orig_flags & XPCLOSE) && !ischild)
+ || ((orig_flags & XCCLOSE) && ischild)))
close(close_fd);
- if (i == 0) { /* child */
+ if (ischild) { /* child */
+#ifdef KSH
+ /* Do this before restoring signal */
+ if (orig_flags & XCOPROC)
+ coproc_cleanup(FALSE);
+#endif /* KSH */
#ifdef JOB_SIGS
sigprocmask(SIG_SETMASK, &omask, (sigset_t *) 0);
#endif /* JOB_SIGS */
cleanup_parents_env();
-#ifdef KSH
- if (orig_flags & XCOPROC)
- cleanup_coproc(FALSE);
-#endif /* KSH */
#ifdef TTY_PGRP
/* If FMONITOR or FTALKING is set, these signals are ignored,
* if neither FMONITOR nor FTALKING are set, the signals have
@@ -604,9 +603,9 @@ exchild(t, flags, close_fd)
setsig(&sigtraps[SIGQUIT], SIG_IGN,
SS_RESTORE_IGN|SS_FORCE);
if (!(orig_flags & (XPIPEI | XCOPROC))) {
- i = open("/dev/null", 0);
- (void) ksh_dup2(i, 0, TRUE);
- close(i);
+ int fd = open("/dev/null", 0);
+ (void) ksh_dup2(fd, 0, TRUE);
+ close(fd);
}
}
remove_job(j, "child"); /* in case of `jobs` command */
@@ -634,8 +633,11 @@ exchild(t, flags, close_fd)
#endif /* TTY_PGRP */
j_startjob(j);
#ifdef KSH
- if (flags & XCOPROC)
- coproc.job = (void *) j;
+ if (orig_flags & XCOPROC) {
+ j->coproc_id = coproc.id;
+ coproc.njobs++; /* n jobs using co-process output */
+ coproc.job = (void *) j; /* j using co-process input */
+ }
#endif /* KSH */
if (flags & XBGND) {
j_set_async(j);
@@ -1268,8 +1270,6 @@ j_sigchld(sig)
WAIT_T status;
struct tms t0, t1;
- trapsig(sig);
-
#ifdef JOB_SIGS
/* Don't wait for any processes if a job is partially started.
* This is so we don't do away with the process group leader
@@ -1386,9 +1386,24 @@ check_job(j)
* remove_job() since neither may be called for non-interactive
* shells.
*/
- if ((j->state == PEXITED || j->state == PSIGNALLED)
- && coproc.job == (void *) j)
- coproc.job = (void *) 0;
+ if (j->state == PEXITED || j->state == PSIGNALLED) {
+ /* No need to keep co-process input any more
+ * (at leasst, this is what ksh93d thinks)
+ */
+ if (coproc.job == j) {
+ coproc.job = (void *) 0;
+ /* XXX would be nice to get the closes out of here
+ * so they aren't done in the signal handler.
+ * Would mean a check in coproc_getfd() to
+ * do "if job == 0 && write >= 0, close write".
+ */
+ coproc_write_close(coproc.write);
+ }
+ /* Do we need to keep the output? */
+ if (j->coproc_id && j->coproc_id == coproc.id
+ && --coproc.njobs == 0)
+ coproc_readw_close(coproc.read);
+ }
#endif /* KSH */
j->flags |= JF_CHANGED;