summaryrefslogtreecommitdiff
path: root/usr.bin/make/job.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.bin/make/job.c')
-rw-r--r--usr.bin/make/job.c122
1 files changed, 60 insertions, 62 deletions
diff --git a/usr.bin/make/job.c b/usr.bin/make/job.c
index 647ae6a7aa9..d53fe717825 100644
--- a/usr.bin/make/job.c
+++ b/usr.bin/make/job.c
@@ -1,5 +1,5 @@
/* $OpenPackages$ */
-/* $OpenBSD: job.c,v 1.92 2007/10/06 19:34:32 cnst Exp $ */
+/* $OpenBSD: job.c,v 1.93 2007/10/09 09:32:03 espie Exp $ */
/* $NetBSD: job.c,v 1.16 1996/11/06 17:59:08 christos Exp $ */
/*
@@ -123,19 +123,14 @@
* Each job has several things associated with it:
* 1) The process id of the child shell
* 2) The graph node describing the target being made by this job
- * 3) A LstNode for the first command to be saved after the job
- * completes. This is NULL if there was no "..." in the job's
- * commands.
- * 4) An FILE* for writing out the commands. This is only
+ * 3) An FILE* for writing out the commands. This is only
* used before the job is actually started.
- * 5) Things used for handling the shell's output.
+ * 4) Things used for handling the shell's output.
* the output is being caught via a pipe and
* the descriptors of our pipe, an array in which output is line
* buffered and the current position in that buffer are all
* maintained for each job.
- * 6) An identifier provided by and for the exclusive use of the
- * Rmt module.
- * 7) A word of flags which determine how the module handles errors,
+ * 5) A word of flags which determine how the module handles errors,
* echoing, etc. for the job
*
* The job "table" is kept as a linked Lst in 'jobs', with the number of
@@ -268,10 +263,10 @@ static LIST stoppedJobs; /* Lst of Job structures describing
#define W_SETEXITSTATUS(st, val) W_SETMASKED(st, val, WEXITSTATUS)
-static void JobCondPassSig(void *, void *);
+static void pass_signal_to_job(void *, void *);
static void SigHandler(int);
-static void HandleSigs(void);
-static void JobPassSig(int);
+static void handle_all_signals(void);
+static void handle_signal(int);
static int JobCmpPid(void *, void *);
static int JobPrintCommand(LstNode, void *);
static void JobSaveCommand(void *, void *);
@@ -288,13 +283,13 @@ static void JobRestartJobs(void);
static void DBPRINTF(Job *, const char *, ...);
static void debug_printf(const char *, ...);
static FILE *new_command_file(void);
+static void setup_signal(int);
+
+static volatile sig_atomic_t got_signal;
static volatile sig_atomic_t got_SIGINT, got_SIGHUP, got_SIGQUIT,
- got_SIGTERM;
-#if defined(USE_PGRP)
-static volatile sig_atomic_t got_SIGTSTP, got_SIGTTOU, got_SIGTTIN,
- got_SIGWINCH;
-#endif
+ got_SIGTERM, got_SIGTSTP, got_SIGTTOU, got_SIGTTIN, got_SIGWINCH;
+
#define TMPPAT "/tmp/makeXXXXXXXXXX"
@@ -321,70 +316,81 @@ SigHandler(int sig)
switch(sig) {
case SIGINT:
got_SIGINT++;
+ got_signal = 1;
break;
case SIGHUP:
got_SIGHUP++;
+ got_signal = 1;
break;
case SIGQUIT:
got_SIGQUIT++;
+ got_signal = 1;
break;
case SIGTERM:
got_SIGTERM++;
+ got_signal = 1;
break;
-#if defined(USE_PGRGP)
+#ifdef USE_PGRP
case SIGTSTP:
got_SIGTSTP++;
+ got_signal = 1;
break;
case SIGTTOU:
got_SIGTTOU++;
+ got_signal = 1;
break;
case SIGTTIN:
got_SIGTTIN++;
+ got_signal = 1;
break;
case SIGWINCH:
got_SIGWINCH++;
+ got_signal = 1;
break;
#endif
}
}
static void
-HandleSigs()
+handle_all_signals()
{
+ if (got_signal)
+ got_signal = 0;
+ else
+ return;
+
if (got_SIGINT) {
got_SIGINT=0;
- JobPassSig(SIGINT);
+ handle_signal(SIGINT);
}
if (got_SIGHUP) {
got_SIGHUP=0;
- JobPassSig(SIGHUP);
+ handle_signal(SIGHUP);
}
if (got_SIGQUIT) {
got_SIGQUIT=0;
- JobPassSig(SIGQUIT);
+ handle_signal(SIGQUIT);
}
if (got_SIGTERM) {
got_SIGTERM=0;
- JobPassSig(SIGTERM);
+ handle_signal(SIGTERM);
}
-#if defined(USE_PGRP)
if (got_SIGTSTP) {
got_SIGTSTP=0;
- JobPassSig(SIGTSTP);
+ handle_signal(SIGTSTP);
}
if (got_SIGTTOU) {
got_SIGTTOU=0;
- JobPassSig(SIGTTOU);
+ handle_signal(SIGTTOU);
}
if (got_SIGTTIN) {
got_SIGTTIN=0;
- JobPassSig(SIGTTIN);
+ handle_signal(SIGTTIN);
}
if (got_SIGWINCH) {
got_SIGWINCH=0;
- JobPassSig(SIGWINCH);
+ handle_signal(SIGWINCH);
}
-#endif
}
/*-
@@ -398,14 +404,14 @@ HandleSigs()
*-----------------------------------------------------------------------
*/
static void
-JobCondPassSig(void *jobp, /* Job to biff */
+pass_signal_to_job(void *jobp, /* Job to biff */
void *signop) /* Signal to send it */
{
Job *job = (Job *)jobp;
int signo = *(int *)signop;
if (DEBUG(JOB)) {
(void)fprintf(stdout,
- "JobCondPassSig passing signal %d to child %ld.\n",
+ "pass_signal_to_job passing signal %d to child %ld.\n",
signo, (long)job->pid);
(void)fflush(stdout);
}
@@ -423,16 +429,16 @@ JobCondPassSig(void *jobp, /* Job to biff */
*-----------------------------------------------------------------------
*/
static void
-JobPassSig(int signo) /* The signal number we've received */
+handle_signal(int signo) /* The signal number we've received */
{
sigset_t nmask, omask;
struct sigaction act;
if (DEBUG(JOB)) {
- (void)fprintf(stdout, "JobPassSig(%d) called.\n", signo);
+ (void)fprintf(stdout, "handle_signal(%d) called.\n", signo);
(void)fflush(stdout);
}
- Lst_ForEach(&jobs, JobCondPassSig, &signo);
+ Lst_ForEach(&jobs, pass_signal_to_job, &signo);
/*
* Deal with proper cleanup based on the signal received. We only run
@@ -470,7 +476,7 @@ JobPassSig(int signo) /* The signal number we've received */
if (DEBUG(JOB)) {
(void)fprintf(stdout,
- "JobPassSig passing signal to self, mask = %x.\n",
+ "handle_signal passing signal to self, mask = %x.\n",
~0 & ~(1 << (signo-1)));
(void)fflush(stdout);
}
@@ -479,7 +485,7 @@ JobPassSig(int signo) /* The signal number we've received */
(void)KILL(getpid(), signo);
signo = SIGCONT;
- Lst_ForEach(&jobs, JobCondPassSig, &signo);
+ Lst_ForEach(&jobs, pass_signal_to_job, &signo);
(void)sigprocmask(SIG_SETMASK, &omask, NULL);
sigprocmask(SIG_SETMASK, &omask, NULL);
@@ -1594,7 +1600,7 @@ Job_CatchChildren()
}
while ((pid = waitpid((pid_t) -1, &status, WNOHANG|WUNTRACED)) > 0) {
- HandleSigs();
+ handle_all_signals();
debug_printf("Process %ld exited or stopped.\n", (long)pid);
jnode = Lst_Find(&jobs, JobCmpPid, &pid);
@@ -1659,7 +1665,7 @@ Job_CatchOutput(void)
timeout.tv_usec = SEL_USEC;
nfds = select(outputsn+1, readfdsp, NULL, NULL, &timeout);
- HandleSigs();
+ handle_all_signals();
if (nfds > 0) {
for (ln = Lst_First(&jobs); nfds && ln != NULL;
ln = Lst_Adv(ln)) {
@@ -1689,6 +1695,14 @@ Job_Make(GNode *gn)
(void)JobStart(gn, 0);
}
+static void
+setup_signal(int sig)
+{
+ if (signal(sig, SIG_IGN) != SIG_IGN) {
+ (void)signal(sig, SigHandler);
+ }
+}
+
/*-
*-----------------------------------------------------------------------
* Job_Init --
@@ -1726,18 +1740,10 @@ Job_Init(int maxproc)
* Catch the four signals that POSIX specifies if they aren't ignored.
* JobPassSig will take care of calling JobInterrupt if appropriate.
*/
- if (signal(SIGINT, SIG_IGN) != SIG_IGN) {
- (void)signal(SIGINT, SigHandler);
- }
- if (signal(SIGHUP, SIG_IGN) != SIG_IGN) {
- (void)signal(SIGHUP, SigHandler);
- }
- if (signal(SIGQUIT, SIG_IGN) != SIG_IGN) {
- (void)signal(SIGQUIT, SigHandler);
- }
- if (signal(SIGTERM, SIG_IGN) != SIG_IGN) {
- (void)signal(SIGTERM, SigHandler);
- }
+ setup_signal(SIGINT);
+ setup_signal(SIGHUP);
+ setup_signal(SIGQUIT);
+ setup_signal(SIGTERM);
/*
* There are additional signals that need to be caught and passed if
* either the export system wants to be told directly of signals or if
@@ -1745,18 +1751,10 @@ Job_Init(int maxproc)
* signals from the terminal driver as we own the terminal)
*/
#if defined(USE_PGRP)
- if (signal(SIGTSTP, SIG_IGN) != SIG_IGN) {
- (void)signal(SIGTSTP, SigHandler);
- }
- if (signal(SIGTTOU, SIG_IGN) != SIG_IGN) {
- (void)signal(SIGTTOU, SigHandler);
- }
- if (signal(SIGTTIN, SIG_IGN) != SIG_IGN) {
- (void)signal(SIGTTIN, SigHandler);
- }
- if (signal(SIGWINCH, SIG_IGN) != SIG_IGN) {
- (void)signal(SIGWINCH, SigHandler);
- }
+ setup_signal(SIGTSTP);
+ setup_signal(SIGTTOU);
+ setup_signal(SIGTTIN);
+ setup_signal(SIGWINCH);
#endif
if ((begin_node->type & OP_DUMMY) == 0) {