don't rfork(RFNOTEG) because then you lose

the ability to read from the console.  damn.

also, handle case where child exits before
fork returns in parent.  have to record that
sigchld was seen and then run the handler later.
This commit is contained in:
rsc 2005-01-11 21:06:55 +00:00
parent 2b85f70db0
commit e9dbe11dbf

View file

@ -9,6 +9,7 @@
static int sigpid; static int sigpid;
static int threadpassfd; static int threadpassfd;
static int gotsigchld;
static void static void
child(void) child(void)
@ -44,12 +45,28 @@ child(void)
static void static void
sigpass(int sig) sigpass(int sig)
{ {
if(sigpid == 1){
gotsigchld = 1;
return;
}
if(sig == SIGCHLD) if(sig == SIGCHLD)
child(); child();
else else
kill(sigpid, sig); kill(sigpid, sig);
} }
static int sigs[] =
{
SIGHUP, SIGINT, SIGQUIT, SIGILL,
SIGTRAP, SIGABRT, SIGBUS, SIGFPE,
SIGUSR1, SIGSEGV, SIGUSR2, SIGPIPE,
SIGALRM, SIGTERM, SIGCHLD, SIGSTOP,
SIGTSTP, SIGTTIN, SIGTTOU, SIGURG,
SIGXCPU, SIGXFSZ, SIGVTALRM, SIGPROF,
SIGWINCH, SIGIO, SIGPWR, SIGSYS
};
void void
_threadsetupdaemonize(void) _threadsetupdaemonize(void)
{ {
@ -88,20 +105,23 @@ _threadsetupdaemonize(void)
for(i=0; i<100; i++) sched_yield(); for(i=0; i<100; i++) sched_yield();
notedisable("sys: child"); notedisable("sys: child");
signal(SIGCHLD, SIG_DFL); signal(SIGCHLD, SIG_DFL);
rfork(RFNOTEG); /* rfork(RFNOTEG); */
close(p[0]); close(p[0]);
threadpassfd = p[1]; threadpassfd = p[1];
return; return;
} }
sigpid = pid; sigpid = pid;
for(i=0; i<NSIG; i++){ if(gotsigchld)
sigpass(SIGCHLD);
for(i=0; i<nelem(sigs); i++){
struct sigaction sa; struct sigaction sa;
memset(&sa, 0, sizeof sa); memset(&sa, 0, sizeof sa);
sa.sa_handler = sigpass; sa.sa_handler = sigpass;
sa.sa_flags |= SA_RESTART; sa.sa_flags |= SA_RESTART;
sigaction(i, &sa, nil); sigaction(sigs[i], &sa, nil);
} }
for(;;){ for(;;){