From: Roy Marples Date: Sun, 27 Jan 2008 18:39:31 +0000 (+0000) Subject: Use sigaction over signal and check iface and state before freeing X-Git-Tag: v3.2.3~60 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0376353cfc371c545c97716c09891ccd5e55c94c;p=thirdparty%2Fdhcpcd.git Use sigaction over signal and check iface and state before freeing --- diff --git a/client.c b/client.c index c87da559..f447d9a1 100644 --- a/client.c +++ b/client.c @@ -1001,7 +1001,8 @@ int dhcp_run (const options_t *options, int *pidfd) if (! client_setup (state, options)) goto eexit; - signal_setup (); + if (signal_setup () == -1) + goto eexit; for (;;) { retval = wait_for_packet (&rset, state, options); @@ -1032,24 +1033,25 @@ int dhcp_run (const options_t *options, int *pidfd) } eexit: - do_socket (state, SOCKET_CLOSED); - drop_config (state, options); - if (iface) { + do_socket (state, SOCKET_CLOSED); + drop_config (state, options); free_route (iface->previous_routes); free (iface); } - if (state->forked) - retval = 0; + if (state) { + if (state->forked) + retval = 0; - if (state->daemonised) - unlink (options->pidfile); + if (state->daemonised) + unlink (options->pidfile); - free_dhcp (state->dhcp); - free (state->dhcp); - free (state->buffer); - free (state); + free_dhcp (state->dhcp); + free (state->dhcp); + free (state->buffer); + free (state); + } return (retval); } diff --git a/interface.c b/interface.c index 8d222205..3cb4952c 100644 --- a/interface.c +++ b/interface.c @@ -399,7 +399,7 @@ interface_t *read_interface (const char *ifname, _unused int metric) if (! (ifr.ifr_flags & IFF_UP) || ! (ifr.ifr_flags & IFF_RUNNING)) { ifr.ifr_flags |= IFF_UP | IFF_RUNNING; - if (ioctl (s, SIOCSIFFLAGS, &ifr) == -1) { + if (ioctl (s, SIOCSIFFLAGS, &ifr) != 0) { logger (LOG_ERR, "ioctl SIOCSIFFLAGS: %s", strerror (errno)); goto exit; diff --git a/signal.c b/signal.c index a1f8bff4..11e0865e 100644 --- a/signal.c +++ b/signal.c @@ -40,9 +40,17 @@ static int signal_pipe[2]; static int signals[5]; +static const int handle_sigs[] = { + SIGHUP, + SIGALRM, + SIGTERM, + SIGINT +}; + static void signal_handler (int sig) { unsigned int i = 0; + int serrno = errno; /* Add a signal to our stack */ while (signals[i]) @@ -52,8 +60,11 @@ static void signal_handler (int sig) else signals[i] = sig; - if (send (signal_pipe[1], &sig, sizeof (sig), MSG_DONTWAIT) == -1) + if (write (signal_pipe[1], &sig, sizeof (sig)) == -1) logger (LOG_ERR, "Could not send signal: %s", strerror (errno)); + + /* Restore errno */ + errno = serrno; } /* Add the signal pipe to an fd set */ @@ -114,12 +125,16 @@ int signal_read (fd_set *rset) /* Call this before doing anything else. Sets up the socket pair * and installs the signal handler */ -void signal_setup (void) +int signal_setup (void) { unsigned int i; int flags; + struct sigaction sa; - socketpair (AF_UNIX, SOCK_STREAM, 0, signal_pipe); + if (pipe (signal_pipe) == -1) { + logger (LOG_ERR, "pipe: %s", strerror (errno)); + return (-1); + } /* Stop any scripts from inheriting us */ for (i = 0; i < 2; i++) @@ -127,13 +142,23 @@ void signal_setup (void) fcntl (signal_pipe[i], F_SETFD, flags | FD_CLOEXEC) == -1) logger (LOG_ERR ,"fcntl: %s", strerror (errno)); - signal (SIGHUP, signal_handler); - signal (SIGALRM, signal_handler); - signal (SIGTERM, signal_handler); - signal (SIGINT, signal_handler); + sa.sa_handler = signal_handler; + sigemptyset (&sa.sa_mask); + for (i = 0; i < sizeof (handle_sigs) / sizeof (handle_sigs[0]); i++) + if (sigaction (handle_sigs[i], &sa, NULL) == -1) { + logger (LOG_ERR, "sigaction: %s", strerror (errno)); + return (-1); + } - /* We don't care about our childs exit codes right now */ - signal (SIGCHLD, SIG_IGN); + /* Ignore child signals and don't make zombies */ + sa.sa_handler = SIG_DFL; + sa.sa_flags = SA_NOCLDSTOP | SA_NOCLDWAIT; + if (sigaction (SIGCHLD, &sa, NULL) == -1) { + logger (LOG_ERR, "sigaction: %s", strerror (errno)); + return (-1); + } memset (signals, 0, sizeof (signals)); + + return (0); } diff --git a/signal.h b/signal.h index cbd8477b..eccec518 100644 --- a/signal.h +++ b/signal.h @@ -28,7 +28,7 @@ #ifndef SIGNAL_H #define SIGNAL_H -void signal_setup (void); +int signal_setup (void); int signal_fd_set (fd_set *rset, int fd); int signal_exists (const fd_set *rset); int signal_read (fd_set *rset);