Skip site navigation (1)Skip section navigation (2)
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>