aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bitlbee.c3
-rw-r--r--bitlbee.h2
-rw-r--r--unix.c35
3 files changed, 31 insertions, 9 deletions
diff --git a/bitlbee.c b/bitlbee.c
index 98f2d9c9..fa8c6795 100644
--- a/bitlbee.c
+++ b/bitlbee.c
@@ -310,6 +310,9 @@ static gboolean bitlbee_io_new_client(gpointer data, gint fd, b_input_condition
close(global.listen_socket);
b_event_remove(global.listen_watch_source_id);
+ /* Make a new pipe for the shutdown signal handler */
+ sighandler_shutdown_setup();
+
/* Make the connection. */
irc = irc_new(new_socket);
diff --git a/bitlbee.h b/bitlbee.h
index 49a5496a..447e2e64 100644
--- a/bitlbee.h
+++ b/bitlbee.h
@@ -157,6 +157,8 @@ typedef struct global {
int restart;
} global_t;
+void sighandler_shutdown_setup(void);
+
int bitlbee_daemon_init(void);
int bitlbee_inetd_init(void);
diff --git a/unix.c b/unix.c
index 30451241..298c8427 100644
--- a/unix.c
+++ b/unix.c
@@ -47,7 +47,11 @@
global_t global; /* Against global namespace pollution */
-static int signal_shutdown_pipe[2] = { -1, -1 };
+static struct {
+ int fd[2];
+ int tag;
+} shutdown_pipe = {{-1 , -1}, 0};
+
static void sighandler_shutdown(int signal);
static void sighandler_crash(int signal);
@@ -155,13 +159,11 @@ int main(int argc, char *argv[])
sig.sa_handler = sighandler_crash;
sigaction(SIGSEGV, &sig, &old);
- /* Use a pipe for SIGTERM/SIGINT so the actual signal handler doesn't do anything unsafe */
- if (pipe(signal_shutdown_pipe) == 0) {
- b_input_add(signal_shutdown_pipe[0], B_EV_IO_READ, bitlbee_shutdown, NULL);
- sig.sa_handler = sighandler_shutdown;
- sigaction(SIGINT, &sig, &old);
- sigaction(SIGTERM, &sig, &old);
- }
+ sighandler_shutdown_setup();
+
+ sig.sa_handler = sighandler_shutdown;
+ sigaction(SIGINT, &sig, &old);
+ sigaction(SIGTERM, &sig, &old);
if (!getuid() || !geteuid()) {
log_message(LOGLVL_WARNING, "BitlBee is running with root privileges. Why?");
@@ -255,12 +257,27 @@ static int crypt_main(int argc, char *argv[])
return 0;
}
+/* Set up a pipe for SIGTERM/SIGINT so the actual signal handler doesn't do anything unsafe */
+void sighandler_shutdown_setup()
+{
+ if (shutdown_pipe.fd[0] != -1) {
+ /* called again from a forked process, clean up to avoid propagating the signal */
+ b_event_remove(shutdown_pipe.tag);
+ close(shutdown_pipe.fd[0]);
+ close(shutdown_pipe.fd[1]);
+ }
+
+ if (pipe(shutdown_pipe.fd) == 0) {
+ shutdown_pipe.tag = b_input_add(shutdown_pipe.fd[0], B_EV_IO_READ, bitlbee_shutdown, NULL);
+ }
+}
+
/* Signal handler for SIGTERM and SIGINT */
static void sighandler_shutdown(int signal)
{
/* Write a single null byte to the pipe, just to send a message to the main loop.
* This gets handled by bitlbee_shutdown (the b_input_add callback for this pipe) */
- write(signal_shutdown_pipe[1], "", 1);
+ write(shutdown_pipe.fd[1], "", 1);
}
/* Signal handler for SIGSEGV