From owner-freebsd-questions Fri Mar 29 7:14:28 2002 Delivered-To: freebsd-questions@freebsd.org Received: from raven.ravenbrook.com (raven.ravenbrook.com [193.82.131.18]) by hub.freebsd.org (Postfix) with ESMTP id 75CFF37B405 for ; Fri, 29 Mar 2002 07:14:19 -0800 (PST) Received: from thrush.ravenbrook.com (thrush.ravenbrook.com [193.112.141.249]) by raven.ravenbrook.com (8.11.6/8.11.6) with ESMTP id g2TFEFO79739; Fri, 29 Mar 2002 15:14:15 GMT (envelope-from nb@ravenbrook.com) Received: from thrush.ravenbrook.com (localhost [127.0.0.1]) by thrush.ravenbrook.com (8.11.6/8.11.6) with ESMTP id g2TFEkK33455; Fri, 29 Mar 2002 15:14:46 GMT (envelope-from nb@thrush.ravenbrook.com) From: Nick Barnes To: =?koi8-r?Q?=E2=C5=D2=A3=DA=CB=CF_=E9=D7=C1=CE?= Cc: "'freebsd-questions@freebsd.org'" Subject: Re: execl() after fork() in signal handler - strange things happen :) In-Reply-To: Message from =?koi8-r?Q?=E2=C5=D2=A3=DA=CB=CF_=E9=D7=C1=CE?= of "Fri, 29 Mar 2002 14:22:31 +0300." <3649F9FBD2621F4498A022E513C5CA2101528B@falcon.win.infodom.ru> Date: Fri, 29 Mar 2002 15:14:46 +0000 Message-ID: <33453.1017414886@thrush.ravenbrook.com> Sender: owner-freebsd-questions@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG [brought over to -questions from -stable] At 2002-03-29 11:22:31+0000, =?koi8-r?Q?=E2=C5=D2=A3=DA=CB=CF_=E9=D7=C1=CE?= wr ites: > Hello, people. > > The problem is - when doing execl() after fork() inside a signal handler, > the signal is not delivered to executed child anymore. Is this correct? (I > understand, that doing such things is a bad idea, but... :) It's because the signal is blocked in the signal handler (see signal(3)). The signal mask is inherited by the execl child (see sigprocmask(2)), so the signal is still masked in the child. Here's a small modification of your program which shows this. Nick Barnes Ravenbrook Limited #include #include #include #include static char * self; static int running; static void sig_handler(int); static void showmask(void); int main(int argc, char** argv) { int i; self = argv[0]; openlog("signaltest", LOG_PID | LOG_NDELAY, LOG_LOCAL0); showmask(); syslog(LOG_NOTICE, "setting signal handlers"); signal(SIGHUP, sig_handler); signal(SIGTERM, sig_handler); syslog(LOG_NOTICE, "entering waiting loop"); running = 1; i = 0; while(running) { sleep(2); syslog(LOG_NOTICE, "sleeping: %d", i++); } syslog(LOG_NOTICE, "terminated"); return 0; } static void showmask(void) { sigset_t set; int i, mask = sigprocmask(0, NULL, &set); for (i = 1; i < _SIG_MAXSIG; ++i) { if (sigismember(&set, i)) { syslog(LOG_NOTICE, "signal %d (%s) masked\n", i, strsignal(i)); } } } static void sig_handler(int sig) { int rc; syslog(LOG_NOTICE, "got a signal: %d", sig); switch(sig) { case SIGHUP: rc = fork(); if (-1 == rc) { syslog(LOG_ERR, "fork() failed: %m"); break; } if (0 == rc) { rc = execl(self, NULL); syslog(LOG_ERR, "execl() failed: %m"); } case SIGTERM: running = 0; break; } } /* shell log: $ cc -g foo.c $ ./a.out & Mar 29 15:09:16 thrush signaltest[33442]: setting signal handlers Mar 29 15:09:16 thrush signaltest[33442]: entering waiting loop Mar 29 15:09:18 thrush signaltest[33442]: sleeping: 0 Mar 29 15:09:20 thrush signaltest[33442]: sleeping: 1 $ kill -HUP 33442 Mar 29 15:09:22 thrush signaltest[33442]: got a signal: 1 Mar 29 15:09:22 thrush signaltest[33442]: sleeping: 2 Mar 29 15:09:22 thrush signaltest[33442]: terminated Mar 29 15:09:22 thrush signaltest[33444]: signal 1 (Hangup) masked Mar 29 15:09:22 thrush signaltest[33444]: setting signal handlers Mar 29 15:09:22 thrush signaltest[33444]: entering waiting loop Mar 29 15:09:24 thrush signaltest[33444]: sleeping: 0 Mar 29 15:09:26 thrush signaltest[33444]: sleeping: 1 Mar 29 15:09:28 thrush signaltest[33444]: sleeping: 2 $ kill -HUP 33444 Mar 29 15:09:30 thrush signaltest[33444]: sleeping: 3 Mar 29 15:09:32 thrush signaltest[33444]: sleeping: 4 Mar 29 15:09:34 thrush signaltest[33444]: sleeping: 5 $ kill -TERM 33444 Mar 29 15:09:36 thrush signaltest[33444]: got a signal: 15 Mar 29 15:09:36 thrush signaltest[33444]: sleeping: 6 Mar 29 15:09:36 thrush signaltest[33444]: terminated $ */ To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-questions" in the body of the message