diff --git a/config.h.in b/config.h.in
index 9a13927..56d956d 100644
--- a/config.h.in
+++ b/config.h.in
@@ -309,6 +309,9 @@
 /* Define if you have the setresuid function.  */
 #undef HAVE_SETRESUID
 
+/* Define if you have the sigaction function.  */
+#undef HAVE_SIGACTION
+
 /* Define if you have the signal function.  */
 #undef HAVE_SIGNAL
 
diff --git a/configure.in b/configure.in
index 5fef169..99936a4 100644
--- a/configure.in
+++ b/configure.in
@@ -113,6 +113,7 @@ AC_CHECK_FUNCS(getopt_long)
 AC_CHECK_FUNCS(mkstemp)
 AC_CHECK_FUNCS(flock lockf)
 AC_CHECK_FUNCS(setlinebuf)
+AC_CHECK_FUNCS(sigaction)
 AC_CHECK_FUNCS(signal)
 AC_CHECK_FUNCS(sigset)
 
diff --git a/fcron.c b/fcron.c
index d7f8366..7abc6ca 100644
--- a/fcron.c
+++ b/fcron.c
@@ -48,6 +48,9 @@ void sigchild_handler(int x);
 void sigusr1_handler(int x);
 void sigusr2_handler(int x);
 void sigcont_handler(int x);
+void set_signal_handler(int signal, void (*handler)(int), bool first_install);
+void install_signal_handler(int signal, void (*handler)(int));
+void reinstall_signal_handler(int signal, void (*handler)(int));
 int parseopt(int argc, char *argv[]);
 void get_lock(void);
 int is_system_reboot(void);
@@ -533,6 +536,56 @@ sigcont_handler(int x)
     sig_cont = 1;
 }
 
+void
+set_signal_handler(int signal, void (*handler)(int), bool first_install)
+    /* (re)install a signal handler, with restartable syscalls retried. */
+{
+#ifdef HAVE_SIGACTION
+    /* The signal handler stays set after the handler is called when set
+       with sigaction(): we only need to install it once. */
+    if (first_install) {
+        struct sigaction act = {0};
+        act.sa_flags = SA_RESTART;
+        act.sa_handler = handler;
+        if (sigaction(signal, &act, NULL) < 0) {
+            die_e("sigaction() failed on signal %d", signal);
+        }
+    }
+#elif defined(HAVE_SIGNAL)
+    /* Some systems reset the handler to SIG_DFL when the handler
+       is called when the handler was set with signal(). So we have to install
+       it (again) every time. */
+    if (signal(signal, handler) == SIG_ERR) {
+        die_e("signal() failed on signal %d", signal);
+    }
+    if (siginterrupt(signal, 0) < 0) {
+        die_e("siginterrupt() failed on signal %d", signal);
+    }
+#elif defined(HAVE_SIGSET)
+    /* The signal handler stays set after the handler is called when set
+       with sigset(): we only need to install it once. */
+    if (first_install) {
+        if (sigset(signal, handler) == -1) {
+            die_e("sigset() failed on signal %d", signal);
+        }
+    }
+#else
+#error "No signal installation function found"
+#endif
+}
+
+void
+install_signal_handler(int signal, void (*handler)(int)) {
+    set_signal_handler(signal, handler, true);
+}
+
+void
+reinstall_signal_handler(int signal, void (*handler)(int))
+    /* reinstall the signal handler, after execution, if needed. */
+{
+    set_signal_handler(signal, handler, false);
+}
+
 int
 main(int argc, char **argv)
 {
@@ -652,32 +705,15 @@ main(int argc, char **argv)
 
     explain("%s[%d] " VERSION_QUOTED " started", prog_name, daemon_pid);
 
-#ifdef HAVE_SIGNAL
-    /* FIXME: check for errors */
-    signal(SIGTERM, sigterm_handler);
-    signal(SIGHUP, sighup_handler);
-    siginterrupt(SIGHUP, 0);
-    signal(SIGCHLD, sigchild_handler);
-    siginterrupt(SIGCHLD, 0);
-    signal(SIGUSR1, sigusr1_handler);
-    siginterrupt(SIGUSR1, 0);
-    signal(SIGUSR2, sigusr2_handler);
-    siginterrupt(SIGUSR2, 0);
-    signal(SIGCONT, sigcont_handler);
-    siginterrupt(SIGCONT, 0);
+    install_signal_handler(SIGTERM, sigterm_handler);
+    install_signal_handler(SIGHUP, sighup_handler);
+    install_signal_handler(SIGCHLD, sigchild_handler);
+    install_signal_handler(SIGUSR1, sigusr1_handler);
+    install_signal_handler(SIGUSR2, sigusr2_handler);
+    install_signal_handler(SIGCONT, sigcont_handler);
     /* we don't want SIGPIPE to kill fcron, and don't need to handle it as when ignored
      * write() on a pipe closed at the other end will return EPIPE */
-    signal(SIGPIPE, SIG_IGN);
-#elif HAVE_SIGSET
-    /* FIXME: check for errors */
-    sigset(SIGTERM, sigterm_handler);
-    sigset(SIGHUP, sighup_handler);
-    sigset(SIGCHLD, sigchild_handler);
-    sigset(SIGUSR1, sigusr1_handler);
-    sigset(SIGUSR2, sigusr2_handler);
-    sigset(SIGCONT, sigcont_handler);
-    sigset(SIGPIPE, SIG_IGN);
-#endif
+    install_signal_handler(SIGPIPE, SIG_IGN);
 
     /* initialize job database */
     next_id = 0;
@@ -739,10 +775,7 @@ check_signal()
     if (sig_chld > 0) {
         wait_chld();
         sig_chld = 0;
-#ifdef HAVE_SIGNAL
-        (void)signal(SIGCHLD, sigchild_handler);
-        siginterrupt(SIGCHLD, 0);
-#endif
+        reinstall_signal_handler(SIGCHLD, sigchild_handler);
     }
 
     if (sig_conf > 0) {
@@ -751,19 +784,13 @@ check_signal()
             /* update configuration */
             synchronize_dir(".", 0);
             sig_conf = 0;
-#ifdef HAVE_SIGNAL
-            signal(SIGHUP, sighup_handler);
-            siginterrupt(SIGHUP, 0);
-#endif
+            reinstall_signal_handler(SIGHUP, sighup_handler);
         }
         else {
             /* reload all configuration */
             reload_all(".");
             sig_conf = 0;
-#ifdef HAVE_SIGNAL
-            signal(SIGUSR1, sigusr1_handler);
-            siginterrupt(SIGUSR1, 0);
-#endif
+            reinstall_signal_handler(SIGUSR1, sigusr1_handler);
         }
 
     }
@@ -773,10 +800,7 @@ check_signal()
         debug_opt = (debug_opt > 0) ? 0 : 1;
         explain("debug_opt = %d", debug_opt);
         sig_debug = 0;
-#ifdef HAVE_SIGNAL
-        signal(SIGUSR2, sigusr2_handler);
-        siginterrupt(SIGUSR2, 0);
-#endif
+        reinstall_signal_handler(SIGUSR2, sigusr2_handler);
     }
 
 }
@@ -788,10 +812,7 @@ reset_sig_cont(void)
     if (sig_cont > 0) {
 
         sig_cont = 0;
-#ifdef HAVE_SIGNAL
-        signal(SIGCONT, sigcont_handler);
-        siginterrupt(SIGCONT, 0);
-#endif
+        reinstall_signal_handler(SIGCONT, sigcont_handler);
     }
 }
 
diff --git a/fcrondyn.c b/fcrondyn.c
index e04e0ae..d76224c 100644
--- a/fcrondyn.c
+++ b/fcrondyn.c
@@ -253,9 +253,10 @@ parse_cmd(char *cmd_str, long int **cmd, int *cmd_len)
                     fprintf(stderr, "  uid = ALL\n");
             }
             else {
-                Write_cmd(user_uid);
+                int_buf = (long int)user_uid;
+                Write_cmd(int_buf);
                 if (debug_opt)
-                    fprintf(stderr, "  uid = %d\n", (int)user_uid);
+                    fprintf(stderr, "  uid = %ld\n", int_buf);
             }
 
         }
diff --git a/fcronsighup.c b/fcronsighup.c
index 89eabb0..7621cec 100644
--- a/fcronsighup.c
+++ b/fcronsighup.c
@@ -98,7 +98,7 @@ sig_daemon(void)
     if (max_delay_s > 0) {
         time_t now_epoch = 0;
         int delay_s = 0;
-        time_t *target_time_epoch = NULL;
+        time_t target_time_epoch = 0;
         struct tm *target_time_tm = NULL;
         FILE *fp = NULL;
         int fd = 0;
diff --git a/fcrontab.c b/fcrontab.c
index 9a544f2..6a45476 100644
--- a/fcrontab.c
+++ b/fcrontab.c
@@ -80,7 +80,6 @@ char need_sig = 0;              /* do we need to signal fcron daemon */
 char orig_dir[PATH_LEN];
 cf_t *file_base = NULL;
 char buf[PATH_LEN];
-char file[PATH_LEN];
 
 /* needed by log part : */
 char *prog_name = NULL;
@@ -888,7 +887,7 @@ parseopt(int argc, char *argv[])
                 Set(fcronconf, optarg);
             }
             else {
-                char buf[PATH_LEN];
+                char buf[sizeof(orig_dir)+1+strlen(optarg)+1];
                 snprintf(buf, sizeof(buf), "%s/%s", orig_dir, optarg);
                 Set(fcronconf, buf);
             }
@@ -995,12 +994,12 @@ main(int argc, char **argv)
     const char *const *env;
 #endif
     struct passwd *pass;
+    char *fcrontab_file_path = NULL;
 
     rootuid = get_user_uid_safe(ROOTNAME);
     rootgid = get_group_gid_safe(ROOTGROUP);
 
     memset(buf, 0, sizeof(buf));
-    memset(file, 0, sizeof(file));
 
     if (strrchr(argv[0], '/') == NULL)
         prog_name = argv[0];
@@ -1112,18 +1111,20 @@ main(int argc, char **argv)
         else {
             int fd = -1;
 
-            if (*argv[file_opt] != '/')
+            if (*argv[file_opt] != '/') {
                 /* this is just the file name, not the path : complete it */
-                snprintf(file, sizeof(file), "%s/%s", orig_dir, argv[file_opt]);
+                size_t path_len = strlen(orig_dir) + 1 + strlen(argv[file_opt]) + 1;
+                alloc_safe(path_len, fcrontab_file_path);
+                snprintf(fcrontab_file_path, path_len, "%s/%s", orig_dir, argv[file_opt]);
+            }
             else {
-                strncpy(file, argv[file_opt], sizeof(file) - 1);
-                file[sizeof(file) - 1] = '\0';
+                fcrontab_file_path = strdup(argv[file_opt]);
             }
 
-            fd = open_as_user(file, useruid, usergid, O_RDONLY);
+            fd = open_as_user(fcrontab_file_path, useruid, usergid, O_RDONLY);
             if (fd < 0)
-                die_e("Could not open file %s", file);
-            if (make_file(file, fd) == OK)
+                die_e("Could not open file %s", fcrontab_file_path);
+            if (make_file(fcrontab_file_path, fd) == OK)
                 xexit(EXIT_OK);
             else
                 xexit(EXIT_ERR);
diff --git a/global.h b/global.h
index 1e328fd..0b1feef 100644
--- a/global.h
+++ b/global.h
@@ -198,8 +198,8 @@ typedef struct cf_t {
     int cf_running;             /* number of jobs running                    */
     signed char cf_tzdiff;      /* time diff between system and local hour   */
 #ifdef WITH_SELINUX
-    security_context_t cf_user_context;
-    security_context_t cf_file_context;
+    char *cf_user_context;
+    char *cf_file_context;
 #endif
 } cf_t;
 
