]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
Use sigaction over signal and check iface and state before freeing
authorRoy Marples <roy@marples.name>
Sun, 27 Jan 2008 18:39:31 +0000 (18:39 +0000)
committerRoy Marples <roy@marples.name>
Sun, 27 Jan 2008 18:39:31 +0000 (18:39 +0000)
client.c
interface.c
signal.c
signal.h

index c87da559a2f64a34d5fa4444a3bd7c964279a75c..f447d9a140af6a8cd5417bfb998194b93dc7ece4 100644 (file)
--- 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);
 }
index 8d222205c6302b4c4b5ca6fe3950078237632101..3cb4952ca99b729a91ef3dd8e036b1f08b411b75 100644 (file)
@@ -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;
index a1f8bff44c2cb9be992f476c1dbe1cda4bb397a4..11e0865e9a801811db3a8860b8ff6677c57c73ce 100644 (file)
--- a/signal.c
+++ b/signal.c
 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);
 }
index cbd8477b17cb80cfe679f3b4726ff3ca8de3037f..eccec5181cf99a32299b26344dfdd5568e6b0beb 100644 (file)
--- 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);