Diff for /embedaddon/sudo/src/exec.c between versions 1.1.1.4 and 1.1.1.5

version 1.1.1.4, 2013/07/22 10:46:13 version 1.1.1.5, 2013/10/14 07:56:35
Line 515  dispatch_signals(int sv[2], pid_t child, int log_io, s Line 515  dispatch_signals(int sv[2], pid_t child, int log_io, s
                      * select() notification.                       * select() notification.
                      */                       */
                     (void) shutdown(sv[0], SHUT_WR);                      (void) shutdown(sv[0], SHUT_WR);
                } else {                } else if (WIFSTOPPED(status)) {
                    if (WIFSTOPPED(status)) {                    /*
                      * Save the controlling terminal's process group
                      * so we can restore it after we resume, if needed.
                      * Most well-behaved shells change the pgrp back to
                      * its original value before suspending so we must
                      * not try to restore in that case, lest we race with
                      * the child upon resume, potentially stopping sudo
                      * with SIGTTOU while the command continues to run.
                      */
                     sigaction_t sa, osa;
                     pid_t saved_pgrp = (pid_t)-1;
                     int signo = WSTOPSIG(status);
                     int fd = open(_PATH_TTY, O_RDWR|O_NOCTTY, 0);
                     if (fd != -1) {
                         saved_pgrp = tcgetpgrp(fd);
                         /*                          /*
                         * Save the controlling terminal's process group                         * Child was stopped trying to access controlling
                         * so we can restore it after we resume, if needed.                         * terminal.  If the child has a different pgrp
                         * Most well-behaved shells change the pgrp back to                         * and we own the controlling terminal, give it
                         * its original value before suspending so we must                         * to the child's pgrp and let it continue.
                         * not try to restore in that case, lest we race with 
                         * the child upon resume, potentially stopping sudo 
                         * with SIGTTOU while the command continues to run. 
                          */                           */
                        sigaction_t sa, osa;                        if (signo == SIGTTOU || signo == SIGTTIN) {
                        pid_t saved_pgrp = (pid_t)-1;                            if (saved_pgrp == ppgrp) {
                        int signo = WSTOPSIG(status);                                pid_t child_pgrp = getpgid(child);
                        int fd = open(_PATH_TTY, O_RDWR|O_NOCTTY, 0);                                if (child_pgrp != ppgrp) {
                        if (fd != -1) {                                    if (tcsetpgrp(fd, child_pgrp) == 0) {
                            if ((saved_pgrp = tcgetpgrp(fd)) == ppgrp)                                        if (killpg(child_pgrp, SIGCONT) != 0) {
                                saved_pgrp = -1;                                            warning("kill(%d, SIGCONT)",
                                                 (int)child_pgrp);
                                         }
                                         close(fd);
                                         debug_return_int(1);
                                     }
                                 }
                             }
                         }                          }
                         if (signo == SIGTSTP) {  
                             memset(&sa, 0, sizeof(sa));  
                             sigemptyset(&sa.sa_mask);  
                             sa.sa_flags = SA_RESTART;  
                             sa.sa_handler = SIG_DFL;  
                             sudo_sigaction(SIGTSTP, &sa, &osa);  
                         }  
                         if (kill(getpid(), signo) != 0)  
                             warning("kill(%d, SIG%s)", (int)getpid(), signame);  
                         if (signo == SIGTSTP)  
                             sudo_sigaction(SIGTSTP, &osa, NULL);  
                         if (fd != -1) {  
                             /*  
                              * Restore command's process group if different.  
                              * Otherwise, we cannot resume some shells.  
                              */  
                             if (saved_pgrp != (pid_t)-1)  
                                 (void)tcsetpgrp(fd, saved_pgrp);  
                             close(fd);  
                         }  
                     } else {  
                         /* Child has exited, we are done. */  
                         cstat->type = CMD_WSTATUS;  
                         cstat->val = status;  
                         debug_return_int(0);  
                     }                      }
                       if (signo == SIGTSTP) {
                           memset(&sa, 0, sizeof(sa));
                           sigemptyset(&sa.sa_mask);
                           sa.sa_flags = SA_RESTART;
                           sa.sa_handler = SIG_DFL;
                           sudo_sigaction(SIGTSTP, &sa, &osa);
                       }
                       if (kill(getpid(), signo) != 0)
                           warning("kill(%d, SIG%s)", (int)getpid(), signame);
                       if (signo == SIGTSTP)
                           sudo_sigaction(SIGTSTP, &osa, NULL);
                       if (fd != -1) {
                           /*
                            * Restore command's process group if different.
                            * Otherwise, we cannot resume some shells.
                            */
                           if (saved_pgrp != ppgrp)
                               (void)tcsetpgrp(fd, saved_pgrp);
                           close(fd);
                       }
                   } else {
                       /* Child has exited or been killed, we are done. */
                       cstat->type = CMD_WSTATUS;
                       cstat->val = status;
                       debug_return_int(0);
                 }                  }
             }              }
         } else {          } else {

Removed from v.1.1.1.4  
changed lines
  Added in v.1.1.1.5


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>