Imported Upstream version 1.7.4p4
[debian/sudo] / exec.c
diff --git a/exec.c b/exec.c
index 93316a0012b11f71e2f0bc7502ead5b4faad9c7e..784f90ab40ff80020dc18f2ea12105076042b5c9 100644 (file)
--- a/exec.c
+++ b/exec.c
@@ -101,8 +101,15 @@ static int fork_cmnd(path, argv, envp, sv, rbac_enabled)
     int rbac_enabled;
 {
     struct command_status cstat;
+    sigaction_t sa;
     int pid;
 
+    zero_bytes(&sa, sizeof(sa));
+    sigemptyset(&sa.sa_mask);
+    sa.sa_flags = SA_INTERRUPT; /* do not restart syscalls */
+    sa.sa_handler = handler;
+    sigaction(SIGCONT, &sa, NULL);
+
     pid = fork();
     switch (pid) {
     case -1:
@@ -260,21 +267,22 @@ sudo_execve(path, argv, envp, uid, cstat, dowait, bgmode)
 #else
                pid = wait(&status);
 #endif
-               if (pid == child) {
-                   if (!log_io) {
-                       if (WIFSTOPPED(status)) {
-                           /* Child may not have privs to suspend us itself. */
-                           kill(getpid(), WSTOPSIG(status));
-                       } else {
-                           /* Child has exited, we are done. */
-                           cstat->type = CMD_WSTATUS;
-                           cstat->val = status;
-                           return 0;
-                       }
+           } while (pid == -1 && errno == EINTR);
+           if (pid == child) {
+               /* If not logging I/O and child has exited we are done. */
+               if (!log_io) {
+                   if (WIFSTOPPED(status)) {
+                       /* Child may not have privs to suspend us itself. */
+                       kill(getpid(), WSTOPSIG(status));
+                   } else {
+                       /* Child has exited, we are done. */
+                       cstat->type = CMD_WSTATUS;
+                       cstat->val = status;
+                       return 0;
                    }
-                   /* Else we get ECONNRESET on sv[0] if child dies. */
                }
-           } while (pid != -1 || errno == EINTR);
+               /* Else we get ECONNRESET on sv[0] if child dies. */
+           }
        }
 
        zero_bytes(fdsw, howmany(maxfd + 1, NFDBITS) * sizeof(fd_mask));