=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/make/job.c,v retrieving revision 1.92 retrieving revision 1.93 diff -c -r1.92 -r1.93 *** src/usr.bin/make/job.c 2007/10/06 19:34:32 1.92 --- src/usr.bin/make/job.c 2007/10/09 09:32:03 1.93 *************** *** 1,5 **** /* $OpenPackages$ */ ! /* $OpenBSD: job.c,v 1.92 2007/10/06 19:34:32 cnst Exp $ */ /* $NetBSD: job.c,v 1.16 1996/11/06 17:59:08 christos Exp $ */ /* --- 1,5 ---- /* $OpenPackages$ */ ! /* $OpenBSD: job.c,v 1.93 2007/10/09 09:32:03 espie Exp $ */ /* $NetBSD: job.c,v 1.16 1996/11/06 17:59:08 christos Exp $ */ /* *************** *** 123,141 **** * Each job has several things associated with it: * 1) The process id of the child shell * 2) The graph node describing the target being made by this job ! * 3) A LstNode for the first command to be saved after the job ! * completes. This is NULL if there was no "..." in the job's ! * commands. ! * 4) An FILE* for writing out the commands. This is only * used before the job is actually started. ! * 5) Things used for handling the shell's output. * the output is being caught via a pipe and * the descriptors of our pipe, an array in which output is line * buffered and the current position in that buffer are all * maintained for each job. ! * 6) An identifier provided by and for the exclusive use of the ! * Rmt module. ! * 7) A word of flags which determine how the module handles errors, * echoing, etc. for the job * * The job "table" is kept as a linked Lst in 'jobs', with the number of --- 123,136 ---- * Each job has several things associated with it: * 1) The process id of the child shell * 2) The graph node describing the target being made by this job ! * 3) An FILE* for writing out the commands. This is only * used before the job is actually started. ! * 4) Things used for handling the shell's output. * the output is being caught via a pipe and * the descriptors of our pipe, an array in which output is line * buffered and the current position in that buffer are all * maintained for each job. ! * 5) A word of flags which determine how the module handles errors, * echoing, etc. for the job * * The job "table" is kept as a linked Lst in 'jobs', with the number of *************** *** 268,277 **** #define W_SETEXITSTATUS(st, val) W_SETMASKED(st, val, WEXITSTATUS) ! static void JobCondPassSig(void *, void *); static void SigHandler(int); ! static void HandleSigs(void); ! static void JobPassSig(int); static int JobCmpPid(void *, void *); static int JobPrintCommand(LstNode, void *); static void JobSaveCommand(void *, void *); --- 263,272 ---- #define W_SETEXITSTATUS(st, val) W_SETMASKED(st, val, WEXITSTATUS) ! static void pass_signal_to_job(void *, void *); static void SigHandler(int); ! static void handle_all_signals(void); ! static void handle_signal(int); static int JobCmpPid(void *, void *); static int JobPrintCommand(LstNode, void *); static void JobSaveCommand(void *, void *); *************** *** 288,301 **** static void DBPRINTF(Job *, const char *, ...); static void debug_printf(const char *, ...); static FILE *new_command_file(void); static volatile sig_atomic_t got_SIGINT, got_SIGHUP, got_SIGQUIT, ! got_SIGTERM; ! #if defined(USE_PGRP) ! static volatile sig_atomic_t got_SIGTSTP, got_SIGTTOU, got_SIGTTIN, ! got_SIGWINCH; ! #endif #define TMPPAT "/tmp/makeXXXXXXXXXX" static FILE * --- 283,296 ---- static void DBPRINTF(Job *, const char *, ...); static void debug_printf(const char *, ...); static FILE *new_command_file(void); + static void setup_signal(int); + static volatile sig_atomic_t got_signal; + static volatile sig_atomic_t got_SIGINT, got_SIGHUP, got_SIGQUIT, ! got_SIGTERM, got_SIGTSTP, got_SIGTTOU, got_SIGTTIN, got_SIGWINCH; + #define TMPPAT "/tmp/makeXXXXXXXXXX" static FILE * *************** *** 321,390 **** switch(sig) { case SIGINT: got_SIGINT++; break; case SIGHUP: got_SIGHUP++; break; case SIGQUIT: got_SIGQUIT++; break; case SIGTERM: got_SIGTERM++; break; ! #if defined(USE_PGRGP) case SIGTSTP: got_SIGTSTP++; break; case SIGTTOU: got_SIGTTOU++; break; case SIGTTIN: got_SIGTTIN++; break; case SIGWINCH: got_SIGWINCH++; break; #endif } } static void ! HandleSigs() { if (got_SIGINT) { got_SIGINT=0; ! JobPassSig(SIGINT); } if (got_SIGHUP) { got_SIGHUP=0; ! JobPassSig(SIGHUP); } if (got_SIGQUIT) { got_SIGQUIT=0; ! JobPassSig(SIGQUIT); } if (got_SIGTERM) { got_SIGTERM=0; ! JobPassSig(SIGTERM); } - #if defined(USE_PGRP) if (got_SIGTSTP) { got_SIGTSTP=0; ! JobPassSig(SIGTSTP); } if (got_SIGTTOU) { got_SIGTTOU=0; ! JobPassSig(SIGTTOU); } if (got_SIGTTIN) { got_SIGTTIN=0; ! JobPassSig(SIGTTIN); } if (got_SIGWINCH) { got_SIGWINCH=0; ! JobPassSig(SIGWINCH); } - #endif } /*- --- 316,396 ---- switch(sig) { case SIGINT: got_SIGINT++; + got_signal = 1; break; case SIGHUP: got_SIGHUP++; + got_signal = 1; break; case SIGQUIT: got_SIGQUIT++; + got_signal = 1; break; case SIGTERM: got_SIGTERM++; + got_signal = 1; break; ! #ifdef USE_PGRP case SIGTSTP: got_SIGTSTP++; + got_signal = 1; break; case SIGTTOU: got_SIGTTOU++; + got_signal = 1; break; case SIGTTIN: got_SIGTTIN++; + got_signal = 1; break; case SIGWINCH: got_SIGWINCH++; + got_signal = 1; break; #endif } } static void ! handle_all_signals() { + if (got_signal) + got_signal = 0; + else + return; + if (got_SIGINT) { got_SIGINT=0; ! handle_signal(SIGINT); } if (got_SIGHUP) { got_SIGHUP=0; ! handle_signal(SIGHUP); } if (got_SIGQUIT) { got_SIGQUIT=0; ! handle_signal(SIGQUIT); } if (got_SIGTERM) { got_SIGTERM=0; ! handle_signal(SIGTERM); } if (got_SIGTSTP) { got_SIGTSTP=0; ! handle_signal(SIGTSTP); } if (got_SIGTTOU) { got_SIGTTOU=0; ! handle_signal(SIGTTOU); } if (got_SIGTTIN) { got_SIGTTIN=0; ! handle_signal(SIGTTIN); } if (got_SIGWINCH) { got_SIGWINCH=0; ! handle_signal(SIGWINCH); } } /*- *************** *** 398,411 **** *----------------------------------------------------------------------- */ static void ! JobCondPassSig(void *jobp, /* Job to biff */ void *signop) /* Signal to send it */ { Job *job = (Job *)jobp; int signo = *(int *)signop; if (DEBUG(JOB)) { (void)fprintf(stdout, ! "JobCondPassSig passing signal %d to child %ld.\n", signo, (long)job->pid); (void)fflush(stdout); } --- 404,417 ---- *----------------------------------------------------------------------- */ static void ! pass_signal_to_job(void *jobp, /* Job to biff */ void *signop) /* Signal to send it */ { Job *job = (Job *)jobp; int signo = *(int *)signop; if (DEBUG(JOB)) { (void)fprintf(stdout, ! "pass_signal_to_job passing signal %d to child %ld.\n", signo, (long)job->pid); (void)fflush(stdout); } *************** *** 423,438 **** *----------------------------------------------------------------------- */ static void ! JobPassSig(int signo) /* The signal number we've received */ { sigset_t nmask, omask; struct sigaction act; if (DEBUG(JOB)) { ! (void)fprintf(stdout, "JobPassSig(%d) called.\n", signo); (void)fflush(stdout); } ! Lst_ForEach(&jobs, JobCondPassSig, &signo); /* * Deal with proper cleanup based on the signal received. We only run --- 429,444 ---- *----------------------------------------------------------------------- */ static void ! handle_signal(int signo) /* The signal number we've received */ { sigset_t nmask, omask; struct sigaction act; if (DEBUG(JOB)) { ! (void)fprintf(stdout, "handle_signal(%d) called.\n", signo); (void)fflush(stdout); } ! Lst_ForEach(&jobs, pass_signal_to_job, &signo); /* * Deal with proper cleanup based on the signal received. We only run *************** *** 470,476 **** if (DEBUG(JOB)) { (void)fprintf(stdout, ! "JobPassSig passing signal to self, mask = %x.\n", ~0 & ~(1 << (signo-1))); (void)fflush(stdout); } --- 476,482 ---- if (DEBUG(JOB)) { (void)fprintf(stdout, ! "handle_signal passing signal to self, mask = %x.\n", ~0 & ~(1 << (signo-1))); (void)fflush(stdout); } *************** *** 479,485 **** (void)KILL(getpid(), signo); signo = SIGCONT; ! Lst_ForEach(&jobs, JobCondPassSig, &signo); (void)sigprocmask(SIG_SETMASK, &omask, NULL); sigprocmask(SIG_SETMASK, &omask, NULL); --- 485,491 ---- (void)KILL(getpid(), signo); signo = SIGCONT; ! Lst_ForEach(&jobs, pass_signal_to_job, &signo); (void)sigprocmask(SIG_SETMASK, &omask, NULL); sigprocmask(SIG_SETMASK, &omask, NULL); *************** *** 1594,1600 **** } while ((pid = waitpid((pid_t) -1, &status, WNOHANG|WUNTRACED)) > 0) { ! HandleSigs(); debug_printf("Process %ld exited or stopped.\n", (long)pid); jnode = Lst_Find(&jobs, JobCmpPid, &pid); --- 1600,1606 ---- } while ((pid = waitpid((pid_t) -1, &status, WNOHANG|WUNTRACED)) > 0) { ! handle_all_signals(); debug_printf("Process %ld exited or stopped.\n", (long)pid); jnode = Lst_Find(&jobs, JobCmpPid, &pid); *************** *** 1659,1665 **** timeout.tv_usec = SEL_USEC; nfds = select(outputsn+1, readfdsp, NULL, NULL, &timeout); ! HandleSigs(); if (nfds > 0) { for (ln = Lst_First(&jobs); nfds && ln != NULL; ln = Lst_Adv(ln)) { --- 1665,1671 ---- timeout.tv_usec = SEL_USEC; nfds = select(outputsn+1, readfdsp, NULL, NULL, &timeout); ! handle_all_signals(); if (nfds > 0) { for (ln = Lst_First(&jobs); nfds && ln != NULL; ln = Lst_Adv(ln)) { *************** *** 1689,1694 **** --- 1695,1708 ---- (void)JobStart(gn, 0); } + static void + setup_signal(int sig) + { + if (signal(sig, SIG_IGN) != SIG_IGN) { + (void)signal(sig, SigHandler); + } + } + /*- *----------------------------------------------------------------------- * Job_Init -- *************** *** 1726,1743 **** * Catch the four signals that POSIX specifies if they aren't ignored. * JobPassSig will take care of calling JobInterrupt if appropriate. */ ! if (signal(SIGINT, SIG_IGN) != SIG_IGN) { ! (void)signal(SIGINT, SigHandler); ! } ! if (signal(SIGHUP, SIG_IGN) != SIG_IGN) { ! (void)signal(SIGHUP, SigHandler); ! } ! if (signal(SIGQUIT, SIG_IGN) != SIG_IGN) { ! (void)signal(SIGQUIT, SigHandler); ! } ! if (signal(SIGTERM, SIG_IGN) != SIG_IGN) { ! (void)signal(SIGTERM, SigHandler); ! } /* * There are additional signals that need to be caught and passed if * either the export system wants to be told directly of signals or if --- 1740,1749 ---- * Catch the four signals that POSIX specifies if they aren't ignored. * JobPassSig will take care of calling JobInterrupt if appropriate. */ ! setup_signal(SIGINT); ! setup_signal(SIGHUP); ! setup_signal(SIGQUIT); ! setup_signal(SIGTERM); /* * There are additional signals that need to be caught and passed if * either the export system wants to be told directly of signals or if *************** *** 1745,1762 **** * signals from the terminal driver as we own the terminal) */ #if defined(USE_PGRP) ! if (signal(SIGTSTP, SIG_IGN) != SIG_IGN) { ! (void)signal(SIGTSTP, SigHandler); ! } ! if (signal(SIGTTOU, SIG_IGN) != SIG_IGN) { ! (void)signal(SIGTTOU, SigHandler); ! } ! if (signal(SIGTTIN, SIG_IGN) != SIG_IGN) { ! (void)signal(SIGTTIN, SigHandler); ! } ! if (signal(SIGWINCH, SIG_IGN) != SIG_IGN) { ! (void)signal(SIGWINCH, SigHandler); ! } #endif if ((begin_node->type & OP_DUMMY) == 0) { --- 1751,1760 ---- * signals from the terminal driver as we own the terminal) */ #if defined(USE_PGRP) ! setup_signal(SIGTSTP); ! setup_signal(SIGTTOU); ! setup_signal(SIGTTIN); ! setup_signal(SIGWINCH); #endif if ((begin_node->type & OP_DUMMY) == 0) {