Rework set_default_signals into afterfork, which does the sigprocmask
too. This is necessary for processes we fork after
setup_signal_handling(), which otherwise inherit our blocking mask and
non-default handlers.
Call it after each fork() (except the ones we use for daemonising).
As a consequence:
- hackypar children will die if they get a terminating signal
- our subprocesses such as `route' and `ifconfig' will inherit
reasonable signal setups
- it will be correct to call udp_make_socket during phase RUN
(previously any authbind would get a strange signal setup)
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
}
if (!child) { /* we are the child */
}
if (!child) { /* we are the child */
static int spw,spr; /* file descriptors for signal notification pipe */
static int spw,spr; /* file descriptors for signal notification pipe */
-static void set_default_signals(void);
-
/* Long-lived subprocesses can only be started once we've started
signal processing so that we can catch SIGCHLD for them and report
their exit status using the callback function. We block SIGCHLD
/* Long-lived subprocesses can only be started once we've started
signal processing so that we can catch SIGCHLD for them and report
their exit status using the callback function. We block SIGCHLD
p=fork();
if (p==0) {
/* Child process */
p=fork();
if (p==0) {
/* Child process */
- set_default_signals();
- sigprocmask(SIG_SETMASK,&emptyset,NULL);
entry(est);
abort();
} else if (p==-1) {
entry(est);
abort();
} else if (p==-1) {
if the execvp() fails this seems somewhat pointless, and
increases the chance of the child process failing before it
gets to exec(). */
if the execvp() fails this seems somewhat pointless, and
increases the chance of the child process failing before it
gets to exec(). */
va_start(ap,arg);
args[0]=(char *)arg; /* program name */
i=1;
va_start(ap,arg);
args[0]=(char *)arg; /* program name */
i=1;
-static void set_default_signals(void)
{
struct signotify *n;
sigset_t done;
{
struct signotify *n;
sigset_t done;
sa.sa_flags=0;
sigaction(n->signum,&sa,NULL);
}
sa.sa_flags=0;
sigaction(n->signum,&sa,NULL);
}
+
+ sigemptyset(&emptyset);
+ sigprocmask(SIG_SETMASK,&emptyset,NULL);
}
static void signal_handler(int signum)
}
static void signal_handler(int signum)
/* from process.c */
extern void start_signal_handling(void);
/* from process.c */
extern void start_signal_handling(void);
+void afterfork(void);
+/* Must be called before exec in every child made after
+ start_signal_handling. Safe to call in earlier children too. */
+
/***** CONFIGURATION support *****/
extern bool_t just_check_config; /* If True then we're going to exit after
/***** CONFIGURATION support *****/
extern bool_t just_check_config; /* If True then we're going to exit after
char *argv[5], addrstr[33], portstr[5];
const char *addrfam;
int port;
char *argv[5], addrstr[33], portstr[5];
const char *addrfam;
int port;
switch (addr->sa.sa_family) {
case AF_INET:
sprintf(addrstr,"%08lX",(long)addr->sin.sin_addr.s_addr);
switch (addr->sa.sa_family) {
case AF_INET:
sprintf(addrstr,"%08lX",(long)addr->sin.sin_addr.s_addr);