]> git.ozlabs.org Git - ppp.git/blobdiff - pppd/main.c
fix pid handling
[ppp.git] / pppd / main.c
index 8fab86467254d267c36fb40559eced0baeaada5a..5de88e4482e8e2aec3ddd3861275fbca6440d269 100644 (file)
@@ -18,7 +18,7 @@
  */
 
 #ifndef lint
-static char rcsid[] = "$Id: main.c,v 1.74 1999/04/12 06:24:46 paulus Exp $";
+static char rcsid[] = "$Id: main.c,v 1.76 1999/04/16 11:35:06 paulus Exp $";
 #endif
 
 #include <stdio.h>
@@ -77,7 +77,6 @@ char *progname;                       /* Name of this program */
 char hostname[MAXNAMELEN];     /* Our hostname */
 static char pidfilename[MAXPATHLEN];   /* name of pid file */
 static char ppp_devnam[MAXPATHLEN]; /* name of PPP tty (maybe ttypx) */
-static pid_t pid;              /* Our pid */
 static uid_t uid;              /* Our real user-id */
 static int conn_running;       /* we have a [dis]connector running */
 
@@ -126,6 +125,20 @@ int link_stats_valid;
 
 static int charshunt_pid;      /* Process ID for charshunt */
 
+/*
+ * We maintain a list of child process pids and
+ * functions to call when they exit.
+ */
+struct subprocess {
+    pid_t      pid;
+    char       *prog;
+    void       (*done) __P((void *));
+    void       *arg;
+    struct subprocess *next;
+};
+
+static struct subprocess *children;
+
 /* Prototypes for procedures local to this file. */
 
 static void create_pidfile __P((void));
@@ -206,6 +219,18 @@ main(argc, argv)
     phase = PHASE_INITIALIZE;
     log_to_fd = -1;
 
+    /*
+     * Ensure that fds 0, 1, 2 are open, to /dev/null if nowhere else.
+     * This way we can close 0, 1, 2 in detach() without clobbering
+     * a fd that we are using.
+     */
+    if ((i = open("/dev/null", O_RDWR)) >= 0) {
+       while (0 <= i && i <= 2)
+           i = dup(i);
+       if (i >= 0)
+           close(i);
+    }
+
     script_env = NULL;
 
     /* Initialize syslog facilities */
@@ -328,7 +353,6 @@ main(argc, argv)
      */
     if (!nodetach && !updetach)
        detach();
-    pid = getpid();
     p = getlogin();
     if (p == NULL) {
        pw = getpwuid(uid);
@@ -455,7 +479,7 @@ main(argc, argv)
            for (;;) {
                if (sigsetjmp(sigjmp, 1) == 0) {
                    sigprocmask(SIG_BLOCK, &mask, NULL);
-                   if (kill_link) {
+                   if (kill_link || got_sigchld) {
                        sigprocmask(SIG_UNBLOCK, &mask, NULL);
                    } else {
                        waiting = 1;
@@ -687,7 +711,7 @@ main(argc, argv)
        for (phase = PHASE_ESTABLISH; phase != PHASE_DEAD; ) {
            if (sigsetjmp(sigjmp, 1) == 0) {
                sigprocmask(SIG_BLOCK, &mask, NULL);
-               if (kill_link || open_ccp_flag) {
+               if (kill_link || open_ccp_flag || got_sigchld) {
                    sigprocmask(SIG_UNBLOCK, &mask, NULL);
                } else {
                    waiting = 1;
@@ -786,7 +810,7 @@ main(argc, argv)
            do {
                if (sigsetjmp(sigjmp, 1) == 0) {
                    sigprocmask(SIG_BLOCK, &mask, NULL);
-                   if (kill_link) {
+                   if (kill_link || got_sigchld) {
                        sigprocmask(SIG_UNBLOCK, &mask, NULL);
                    } else {
                        waiting = 1;
@@ -809,8 +833,15 @@ main(argc, argv)
     }
 
     /* Wait for scripts to finish */
-    while (n_children > 0)
+    while (n_children > 0) {
+       if (debug) {
+           struct subprocess *chp;
+           dbglog("Waiting for %d child processes...", n_children);
+           for (chp = children; chp != NULL; chp = chp->next)
+               dbglog("  script %s, pid %d", chp->prog, chp->pid);
+       }
        reap_kids(1);
+    }
 
     die(0);
     return 0;
@@ -838,12 +869,11 @@ detach()
     }
     setsid();
     chdir("/");
-    close(0);                  /* XXX we should make sure that none */
-    close(1);                  /* of the fds we need are <= 2 */
+    close(0);
+    close(1);
     close(2);
     detached = 1;
     log_to_fd = -1;
-    pid = getpid();
     /* update pid file if it has been written already */
     if (pidfilename[0])
        create_pidfile();
@@ -875,13 +905,13 @@ create_pidfile()
     slprintf(pidfilename, sizeof(pidfilename), "%s%s.pid",
             _PATH_VARRUN, ifname);
     if ((pidfile = fopen(pidfilename, "w")) != NULL) {
-       fprintf(pidfile, "%d\n", pid);
+       fprintf(pidfile, "%d\n", getpid());
        (void) fclose(pidfile);
     } else {
        error("Failed to create pid file %s: %m", pidfilename);
        pidfilename[0] = 0;
     }
-    slprintf(numbuf, sizeof(numbuf), "%d", pid);
+    slprintf(numbuf, sizeof(numbuf), "%d", getpid());
     script_setenv("PPPD_PID", numbuf);
 }
 
@@ -1382,20 +1412,6 @@ device_script(program, in, out, dont_wait)
 }
 
 
-/*
- * We maintain a list of child process pids and
- * functions to call when they exit.
- */
-struct subprocess {
-    pid_t      pid;
-    char       *prog;
-    void       (*done) __P((void *));
-    void       *arg;
-    struct subprocess *next;
-};
-
-struct subprocess *children;
-
 /*
  * run-program - execute a program with given arguments,
  * but don't wait for it.
@@ -1488,7 +1504,7 @@ run_program(prog, args, must_exist, done, arg)
     }
 
     if (debug)
-       dbglog("Script %s started; pid = %d", prog, pid);
+       dbglog("Script %s started (pid %d)", prog, pid);
     record_child(pid, prog, done, arg);
 
     return pid;