version 1.23, 2009/04/26 09:25:49 |
version 1.24, 2009/05/10 11:07:37 |
|
|
#include "str.h" |
#include "str.h" |
#include "memory.h" |
#include "memory.h" |
#include "buf.h" |
#include "buf.h" |
|
#include "job.h" |
|
|
|
void setup_all_signals(psighandler, psighandler); |
static void MakeTimeStamp(void *, void *); |
static void MakeTimeStamp(void *, void *); |
static int rewrite_time(const char *); |
static int rewrite_time(const char *); |
static void setup_signal(int); |
static void setup_signal(int, psighandler); |
static void setup_all_signals(void); |
|
static void setup_meta(void); |
static void setup_meta(void); |
static char **recheck_command_for_shell(char **); |
static char **recheck_command_for_shell(char **); |
|
|
|
|
|
|
volatile sig_atomic_t got_signal; |
volatile sig_atomic_t got_signal; |
|
|
volatile sig_atomic_t got_SIGINT, got_SIGHUP, got_SIGQUIT, |
volatile sig_atomic_t got_SIGINT, got_SIGHUP, got_SIGQUIT, got_SIGTERM; |
got_SIGTERM, got_SIGTSTP, got_SIGTTOU, got_SIGTTIN, got_SIGWINCH; |
|
|
|
static void |
static void |
setup_signal(int sig) |
setup_signal(int sig, psighandler h) |
{ |
{ |
if (signal(sig, SIG_IGN) != SIG_IGN) { |
if (signal(sig, SIG_IGN) != SIG_IGN) |
(void)signal(sig, SigHandler); |
(void)signal(sig, h); |
} |
|
} |
} |
|
|
static void |
void |
setup_all_signals() |
setup_all_signals(psighandler interrupt, psighandler jc) |
{ |
{ |
/* |
/* |
* Catch the four signals that POSIX specifies if they aren't ignored. |
* Catch the four signals that POSIX specifies if they aren't ignored. |
* handle_signal will take care of calling JobInterrupt if appropriate. |
* handle_signal will take care of calling JobInterrupt if appropriate. |
*/ |
*/ |
setup_signal(SIGINT); |
setup_signal(SIGINT, interrupt); |
setup_signal(SIGHUP); |
setup_signal(SIGHUP, interrupt); |
setup_signal(SIGQUIT); |
setup_signal(SIGQUIT, interrupt); |
setup_signal(SIGTERM); |
setup_signal(SIGTERM, interrupt); |
/* |
setup_signal(SIGTSTP, jc); |
* There are additional signals that need to be caught and passed if |
setup_signal(SIGTTOU, jc); |
* either the export system wants to be told directly of signals or if |
setup_signal(SIGTTIN, jc); |
* we're giving each job its own process group (since then it won't get |
setup_signal(SIGWINCH, jc); |
* signals from the terminal driver as we own the terminal) |
setup_signal(SIGCONT, jc); |
*/ |
got_signal = 0; |
#if defined(USE_PGRP) |
|
setup_signal(SIGTSTP); |
|
setup_signal(SIGTTOU); |
|
setup_signal(SIGTTIN); |
|
setup_signal(SIGWINCH); |
|
#endif |
|
} |
} |
|
|
void |
void |
|
|
got_SIGTERM++; |
got_SIGTERM++; |
got_signal = 1; |
got_signal = 1; |
break; |
break; |
#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 |
|
} |
} |
} |
} |
|
|
|
|
/* The child is off and running. Now all we can do is wait... */ |
/* The child is off and running. Now all we can do is wait... */ |
while (1) { |
while (1) { |
|
|
while ((stat = wait(&reason)) != cpid) { |
while ((stat = waitpid(cpid, &reason, 0)) != cpid) { |
if (stat == -1 && errno != EINTR) |
if (stat == -1 && errno != EINTR) |
break; |
break; |
} |
} |
|
|
break; |
break; |
|
|
if (stat != -1) { |
if (stat != -1) { |
if (WIFSTOPPED(reason)) |
if (WIFEXITED(reason)) { |
status = WSTOPSIG(reason); /* stopped */ |
|
else if (WIFEXITED(reason)) { |
|
status = WEXITSTATUS(reason); /* exited */ |
status = WEXITSTATUS(reason); /* exited */ |
if (status != 0) |
if (status != 0) |
printf("*** Error code %d", status); |
printf("*** Error code %d", status); |
} else { |
} else { |
status = WTERMSIG(reason); /* signaled */ |
status = WTERMSIG(reason); /* signaled */ |
printf("*** Signal %d", status); |
printf("*** Signal %d", status); |
|
|
} |
} |
|
|
void |
void |
setup_engine() |
setup_engine(int parallel) |
{ |
{ |
static int already_setup = 0; |
static int already_setup = 0; |
|
|
if (!already_setup) { |
if (!already_setup) { |
setup_meta(); |
setup_meta(); |
setup_all_signals(); |
if (parallel) |
|
setup_all_signals(parallel_handler, parallel_handler); |
|
else |
|
setup_all_signals(SigHandler, SIG_DFL); |
already_setup = 1; |
already_setup = 1; |
} |
} |
} |
} |