]> git.ozlabs.org Git - ppp.git/commitdiff
Only kill the whole process group if we have detached
authorPaul Mackerras <paulus@samba.org>
Mon, 23 Jun 2008 11:47:18 +0000 (11:47 +0000)
committerPaul Mackerras <paulus@samba.org>
Mon, 23 Jun 2008 11:47:18 +0000 (11:47 +0000)
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
pppd/pppd.h

index c03fd438a90074553f9132e13bbdf0b467032d28..4e1952b1da6227b83ff3453c4412a5652c095346 100644 (file)
@@ -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 <stdio.h>
 #include <ctype.h>
@@ -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;
     }
 }
index ecfb50948e7142b3e4ba46fd10c8c9cabcd3111b..cf9840a416bbd9a57098fdeb9d4d0c10bd8882d4 100644 (file)
@@ -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 */