Date: Fri, 29 Mar 2002 14:22:31 +0300 From: =?koi8-r?Q?=E2=C5=D2=A3=DA=CB=CF_=E9=D7=C1=CE?= <iberiozko@infodom.ru> To: "'freebsd-stable@freebsd.org'" <freebsd-stable@freebsd.org> Subject: execl() after fork() in signal handler - strange things happen :) Message-ID: <3649F9FBD2621F4498A022E513C5CA2101528B@falcon.win.infodom.ru>
next in thread | raw e-mail | index | archive | help
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... :)
This is a test program, built using "gcc -o test test.c". Tested under
4.2-RELEASE and 4.3 RELEASE.
The program, as you can see, does the following:
1. Sets handlers for SIGTERM and SIGHUP.
2. Enters loop, writes "sleeping" message every 2 seconds.
3. SIGTERM - leaves loop and terminates.
4. SIGHUP - forks, executes itself, and terminates parent in the same
manner, as with SIGTERM.
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <syslog.h>
static char * self;
static int running;
static void sig_handler(int);
int main(int argc, char** argv)
{
int i;
self = argv[0];
openlog("signaltest", LOG_PID | LOG_NDELAY, LOG_LOCAL0);
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 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;
}
}
This is a cut of execution log.
% gcc -o test test.c
% ./test &
Mar 29 13:39:28 jb-note signaltest[4483]: setting signal handlers
Mar 29 13:39:28 jb-note signaltest[4483]: entering waiting loop
Mar 29 13:39:30 jb-note signaltest[4483]: sleeping: 0
Mar 29 13:39:32 jb-note signaltest[4483]: sleeping: 1
Mar 29 13:39:34 jb-note signaltest[4483]: sleeping: 2
Mar 29 13:39:36 jb-note signaltest[4483]: sleeping: 3
Mar 29 13:39:38 jb-note signaltest[4483]: sleeping: 4
% kill -HUP 4483
# Successfully caught signal, forked and restarted itself
Mar 29 13:39:40 jb-note signaltest[4483]: got a signal: 1
Mar 29 13:39:40 jb-note signaltest[4483]: sleeping: 5
Mar 29 13:39:40 jb-note signaltest[4483]: terminated
Mar 29 13:39:40 jb-note signaltest[4484]: setting signal handlers
Mar 29 13:39:40 jb-note signaltest[4484]: entering waiting loop
Mar 29 13:39:42 jb-note signaltest[4484]: sleeping: 0
Mar 29 13:39:44 jb-note signaltest[4484]: sleeping: 1
Mar 29 13:39:46 jb-note signaltest[4484]: sleeping: 2
% kill -HUP 4484
# No action, does not see signal
Mar 29 13:39:48 jb-note signaltest[4484]: sleeping: 3
Mar 29 13:39:50 jb-note signaltest[4484]: sleeping: 4
Mar 29 13:39:52 jb-note signaltest[4484]: sleeping: 5
% kill -HUP 4484
# No action, does not see signal
Mar 29 13:39:54 jb-note signaltest[4484]: sleeping: 6
Mar 29 13:39:56 jb-note signaltest[4484]: sleeping: 7
Mar 29 13:39:58 jb-note signaltest[4484]: sleeping: 8
% kill -HUP 4484
# No action, does not see signal
Mar 29 13:40:00 jb-note signaltest[4484]: sleeping: 9
Mar 29 13:40:02 jb-note signaltest[4484]: sleeping: 10
% kill -HUP 4484
# No action, does not see signal
Mar 29 13:40:04 jb-note signaltest[4484]: sleeping: 11
Mar 29 13:40:06 jb-note signaltest[4484]: sleeping: 12
% kill -TERM 4484
# Successfully caught TERM and terminated
Mar 29 13:40:07 jb-note signaltest[4484]: got a signal: 15
Mar 29 13:40:07 jb-note signaltest[4484]: sleeping: 13
Mar 29 13:40:07 jb-note signaltest[4484]: terminated
Good luck.
Ivan Beriozko
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-stable" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?3649F9FBD2621F4498A022E513C5CA2101528B>
