summaryrefslogtreecommitdiffstats
path: root/contrib/tcsh/sh.proc.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/tcsh/sh.proc.c')
-rw-r--r--contrib/tcsh/sh.proc.c667
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 */
OpenPOWER on IntegriCloud