From 7e54469ed4f3c2ecc1006475dcd10df1d1fe35d3 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Mon, 23 Jun 2008 11:47:18 +0000 Subject: [PATCH] Only kill the whole process group if we have detached Previously we always sent a signal to the whole of our current process group when we got a signal such as SIGINT or SIGTERM. That's OK if we have detached, because then we have our own process group, but not if we haven't, because there might be other processes in our process group that we don't know about. In the latter case we now just send the signal individually to the child processes that we have forked off to run things like the connect script, charshunt or pty command. --- pppd/main.c | 33 +++++++++++++++++++++++++-------- pppd/pppd.h | 4 ++-- 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/pppd/main.c b/pppd/main.c index c03fd43..4e1952b 100644 --- a/pppd/main.c +++ b/pppd/main.c @@ -66,7 +66,7 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#define RCSID "$Id: main.c,v 1.155 2006/12/19 10:22:11 paulus Exp $" +#define RCSID "$Id: main.c,v 1.156 2008/06/23 11:47:18 paulus Exp $" #include #include @@ -220,6 +220,7 @@ struct subprocess { char *prog; void (*done) __P((void *)); void *arg; + int killable; struct subprocess *next; }; @@ -1383,7 +1384,21 @@ kill_my_pg(sig) int sig; { struct sigaction act, oldact; + struct subprocess *chp; + + if (!detached) { + /* + * There might be other things in our process group that we + * didn't start that would get hit if we did a kill(0), so + * just send the signal individually to our children. + */ + for (chp = children; chp != NULL; chp = chp->next) + if (chp->killable) + kill(chp->pid, sig); + return; + } + /* We've done a setsid(), so we can just use a kill(0) */ sigemptyset(&act.sa_mask); /* unnecessary in fact */ act.sa_handler = SIG_IGN; act.sa_flags = 0; @@ -1633,15 +1648,15 @@ device_script(program, in, out, dont_wait) } if (pid != 0) { - if (dont_wait) { - record_child(pid, program, NULL, NULL); - status = 0; - } else { + record_child(pid, program, NULL, NULL, 1); + status = 0; + if (!dont_wait) { while (waitpid(pid, &status, 0) < 0) { if (errno == EINTR) continue; fatal("error waiting for (dis)connection process: %m"); } + forget_child(pid, status); --conn_running; } return (status == 0 ? 0 : -1); @@ -1663,7 +1678,7 @@ device_script(program, in, out, dont_wait) /* - * run-program - execute a program with given arguments, + * run_program - execute a program with given arguments, * but don't wait for it unless wait is non-zero. * If the program can't be executed, logs an error unless * must_exist is 0 and the program file doesn't exist. @@ -1706,7 +1721,7 @@ run_program(prog, args, must_exist, done, arg, wait) if (pid != 0) { if (debug) dbglog("Script %s started (pid %d)", prog, pid); - record_child(pid, prog, done, arg); + record_child(pid, prog, done, arg, 0); if (wait) { while (waitpid(pid, &status, 0) < 0) { if (errno == EINTR) @@ -1749,11 +1764,12 @@ run_program(prog, args, must_exist, done, arg, wait) * to use. */ void -record_child(pid, prog, done, arg) +record_child(pid, prog, done, arg, killable) int pid; char *prog; void (*done) __P((void *)); void *arg; + int killable; { struct subprocess *chp; @@ -1768,6 +1784,7 @@ record_child(pid, prog, done, arg) chp->done = done; chp->arg = arg; chp->next = children; + chp->killable = killable; children = chp; } } diff --git a/pppd/pppd.h b/pppd/pppd.h index ecfb509..cf9840a 100644 --- a/pppd/pppd.h +++ b/pppd/pppd.h @@ -39,7 +39,7 @@ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * $Id: pppd.h,v 1.95 2008/06/15 07:03:05 paulus Exp $ + * $Id: pppd.h,v 1.96 2008/06/23 11:47:18 paulus Exp $ */ /* @@ -474,7 +474,7 @@ void timeout __P((void (*func)(void *), void *arg, int s, int us)); /* Call func(arg) after s.us seconds */ void untimeout __P((void (*func)(void *), void *arg)); /* Cancel call to func(arg) */ -void record_child __P((int, char *, void (*) (void *), void *)); +void record_child __P((int, char *, void (*) (void *), void *, int)); pid_t safe_fork __P((int, int, int)); /* Fork & close stuff in child */ int device_script __P((char *cmd, int in, int out, int dont_wait)); /* Run `cmd' with given stdin and stdout */ -- 2.39.2