aboutsummaryrefslogtreecommitdiff
path: root/sh.proc.c
diff options
context:
space:
mode:
Diffstat (limited to 'sh.proc.c')
-rw-r--r--sh.proc.c57
1 files changed, 45 insertions, 12 deletions
diff --git a/sh.proc.c b/sh.proc.c
index f2356d1b98e9..0af5e03ab68e 100644
--- a/sh.proc.c
+++ b/sh.proc.c
@@ -1,4 +1,4 @@
-/* $Header: /p/tcsh/cvsroot/tcsh/sh.proc.c,v 3.121 2012/01/25 15:34:41 christos Exp $ */
+/* $Header: /p/tcsh/cvsroot/tcsh/sh.proc.c,v 3.134 2016/09/23 19:17:28 christos Exp $ */
/*
* sh.proc.c: Job manipulations
*/
@@ -32,7 +32,7 @@
*/
#include "sh.h"
-RCSID("$tcsh: sh.proc.c,v 3.121 2012/01/25 15:34:41 christos Exp $")
+RCSID("$tcsh: sh.proc.c,v 3.134 2016/09/23 19:17:28 christos Exp $")
#include "ed.h"
#include "tc.h"
@@ -47,11 +47,9 @@ RCSID("$tcsh: sh.proc.c,v 3.121 2012/01/25 15:34:41 christos Exp $")
# define HZ 16
#endif /* aiws */
-#if defined(_BSD) || (defined(IRIS4D) && __STDC__) || defined(__lucid) || defined(__linux__) || defined(__GNU__) || defined(__GLIBC__)
-# if !defined(__ANDROID__)
-# define BSDWAIT
-# endif
-#endif /* _BSD || (IRIS4D && __STDC__) || __lucid || glibc */
+#if defined(_BSD) || (defined(IRIS4D) && __STDC__) || defined(__lucid)
+# define BSDWAIT
+#endif /* _BSD || (IRIS4D && __STDC__) || __lucid */
#ifndef WTERMSIG
# define WTERMSIG(w) (((union wait *) &(w))->w_termsig)
# ifndef BSDWAIT
@@ -191,8 +189,13 @@ loop:
# else
/* both a wait3 and rusage */
# if !defined(BSDWAIT) || defined(NeXT) || defined(MACH) || defined(__linux__) || defined(__GNU__) || defined(__GLIBC__) || (defined(IRIS4D) && SYSVREL <= 3) || defined(__lucid) || defined(__osf__)
+#ifdef __ANDROID__ /* no wait3, only wait4 */
+ pid = wait4(-1, &w,
+ (setintr && (intty || insource) ? WNOHANG | WUNTRACED : WNOHANG), &ru);
+#else
pid = wait3(&w,
(setintr && (intty || insource) ? WNOHANG | WUNTRACED : WNOHANG), &ru);
+#endif /* __ANDROID__ */
# else /* BSDWAIT */
pid = wait3(&w.w_status,
(setintr && (intty || insource) ? WNOHANG | WUNTRACED : WNOHANG), &ru);
@@ -507,6 +510,7 @@ pjwait(struct process *pp)
cleanup_push(&oset, sigprocmask_cleanup);
pause_mask = oset;
sigdelset(&pause_mask, SIGCHLD);
+ sigaddset(&pause_mask, SIGINT);
for (;;) {
(void)handle_pending_signals();
jobflags = 0;
@@ -593,22 +597,44 @@ void
dowait(Char **v, struct command *c)
{
struct process *pp;
+
+ /* the current block mask to be able to restore */
+ sigset_t old_mask;
+
+ /* block mask for critical section: OLD_MASK U {SIGCHLD} */
+ sigset_t block_mask;
+
+ /* ignore those during blocking sigsuspend:
+ OLD_MASK / {SIGCHLD, possibly(SIGINT)} */
sigset_t pause_mask;
+
int opintr_disabled, gotsig;
USE(c);
USE(v);
pjobs++;
+
sigprocmask(SIG_BLOCK, NULL, &pause_mask);
sigdelset(&pause_mask, SIGCHLD);
if (setintr)
sigdelset(&pause_mask, SIGINT);
+
+ /* critical section, block also SIGCHLD */
+ sigprocmask(SIG_BLOCK, NULL, &block_mask);
+ sigaddset(&block_mask, SIGCHLD);
+ sigprocmask(SIG_BLOCK, &block_mask, &old_mask);
+
+ /* detect older SIGCHLDs and remove PRUNNING flag from proclist */
+ (void)handle_pending_signals();
+
loop:
for (pp = proclist.p_next; pp; pp = pp->p_next)
if (pp->p_procid && /* pp->p_procid == pp->p_jobid && */
pp->p_flags & PRUNNING) {
- (void)handle_pending_signals();
+ /* wait for (or pick up alredy blocked) SIGCHLD */
sigsuspend(&pause_mask);
+
+ /* make the 'wait' interuptable by CTRL-C */
opintr_disabled = pintr_disabled;
pintr_disabled = 0;
gotsig = handle_pending_signals();
@@ -618,6 +644,8 @@ loop:
goto loop;
}
pjobs = 0;
+
+ sigprocmask(SIG_SETMASK, &old_mask, NULL);
}
/*
@@ -963,6 +991,7 @@ pprint(struct process *pp, int flag)
struct process *tp;
int jobflags, pstatus, pcond;
const char *format;
+ int ohaderr;
#ifdef BACKPIPE
struct process *pipehead = NULL, *pipetail = NULL, *pmarker = NULL;
@@ -978,6 +1007,9 @@ pprint(struct process *pp, int flag)
tp = pp;
status = reason = -1;
jobflags = 0;
+ ohaderr = haderr;
+ /* Print status to stderr, except for jobs built-in */
+ haderr = !(flag & JOBLIST);
do {
#ifdef BACKPIPE
/*
@@ -1186,6 +1218,7 @@ prcomd:
xprintf(" ");
ptprint(tp);
}
+ haderr = ohaderr;
return (jobflags);
}
@@ -1284,7 +1317,7 @@ void
dojobs(Char **v, struct command *c)
{
struct process *pp;
- int flag = NUMBER | NAME | REASON;
+ int flag = NUMBER | NAME | REASON | JOBLIST;
int i;
USE(c);
@@ -1833,12 +1866,12 @@ pfork(struct command *t, int wanttty)
(void) signal(SIGHUP, SIG_IGN);
if (t->t_dflg & F_NICE) {
int nval = SIGN_EXTEND_CHAR(t->t_nice);
-#ifdef HAVE_SETPRIORITY
+#if defined(HAVE_SETPRIORITY) && defined(PRIO_PROCESS)
if (setpriority(PRIO_PROCESS, 0, nval) == -1 && errno)
stderror(ERR_SYSTEM, "setpriority", strerror(errno));
-#else /* !HAVE_SETPRIORITY */
+#else /* !HAVE_SETPRIORITY || !PRIO_PROCESS */
(void) nice(nval);
-#endif /* !HAVE_SETPRIORITY */
+#endif /* HAVE_SETPRIORITY && PRIO_PROCESS */
}
#ifdef F_VER
if (t->t_dflg & F_VER) {