sigwaitinfo() may fail with EINTR if interrupted by an unblocked signal not in the set
[strongswan.git] / src / charon / charon.c
index a82aa42..4c2a9a4 100644 (file)
  */
 
 #include <stdio.h>
-#define _POSIX_PTHREAD_SEMANTICS /* for two param sigwait on OpenSolaris */
 #include <signal.h>
-#undef _POSIX_PTHREAD_SEMANTICS
 #include <pthread.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <sys/utsname.h>
 #include <unistd.h>
 #include <getopt.h>
+#include <fcntl.h>
+#include <errno.h>
 
 #include <hydra.h>
 #include <daemon.h>
@@ -98,7 +98,7 @@ static void run()
 {
        sigset_t set;
 
-       /* handle SIGINT, SIGHUP ans SIGTERM in this handler */
+       /* handle SIGINT, SIGHUP and SIGTERM in this handler */
        sigemptyset(&set);
        sigaddset(&set, SIGINT);
        sigaddset(&set, SIGHUP);
@@ -108,12 +108,15 @@ static void run()
        while (TRUE)
        {
                int sig;
-               int error;
 
-               error = sigwait(&set, &sig);
-               if (error)
+               sig = sigwaitinfo(&set, NULL);
+               if (sig == -1)
                {
-                       DBG1(DBG_DMN, "error %d while waiting for a signal", error);
+                       if (errno == EINTR)
+                       {       /* ignore signals we didn't wait for */
+                               continue;
+                       }
+                       DBG1(DBG_DMN, "waiting for signal failed: %s", strerror(errno));
                        return;
                }
                switch (sig)
@@ -122,15 +125,12 @@ static void run()
                        {
                                DBG1(DBG_DMN, "signal of type SIGHUP received. Reloading "
                                         "configuration");
-#ifdef STRONGSWAN_CONF
-                               if (lib->settings->load_files(lib->settings, STRONGSWAN_CONF,
-                                                                                         FALSE))
+                               if (lib->settings->load_files(lib->settings, lib->conf, FALSE))
                                {
                                        charon->load_loggers(charon, levels, !use_syslog);
                                        lib->plugins->reload(lib->plugins, NULL);
                                }
                                else
-#endif
                                {
                                        DBG1(DBG_DMN, "reloading config failed, keeping old");
                                }
@@ -148,11 +148,6 @@ static void run()
                                charon->bus->alert(charon->bus, ALERT_SHUTDOWN_SIGNAL, sig);
                                return;
                        }
-                       default:
-                       {
-                               DBG1(DBG_DMN, "unknown signal %d received. Ignored", sig);
-                               break;
-                       }
                }
        }
 }
@@ -232,6 +227,14 @@ static bool check_pidfile()
        pidfile = fopen(PID_FILE, "w");
        if (pidfile)
        {
+               int fd;
+
+               fd = fileno(pidfile);
+               if (fd == -1 || fcntl(fd, F_SETFD, FD_CLOEXEC) == -1)
+               {
+                       DBG1(DBG_LIB, "setting FD_CLOEXEC for '"PID_FILE"' failed: %s",
+                                strerror(errno));
+               }
                ignore_result(fchown(fileno(pidfile),
                                                         lib->caps->get_uid(lib->caps),
                                                         lib->caps->get_gid(lib->caps)));
@@ -427,7 +430,7 @@ int main(int argc, char *argv[])
        }
 
        /* add handler for SEGV and ILL,
-        * INT, TERM and HUP are handled by sigwait() in run() */
+        * INT, TERM and HUP are handled by sigwaitinfo() in run() */
        action.sa_handler = segv_handler;
        action.sa_flags = 0;
        sigemptyset(&action.sa_mask);
@@ -458,4 +461,3 @@ deinit:
        library_deinit();
        return status;
 }
-