]> git.ozlabs.org Git - ppp.git/blobdiff - pppd/main.c
fix random signals blocking in kill_my_pg()
[ppp.git] / pppd / main.c
index 4171accd7204b1dc1c64c2f12829d7042857c1c5..0be799820739344bd9aa45344b19c26a67d68b03 100644 (file)
@@ -40,7 +40,7 @@
  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#define RCSID  "$Id: main.c,v 1.129 2003/09/23 15:11:58 kad Exp $"
+#define RCSID  "$Id: main.c,v 1.134 2004/04/12 04:53:00 kad Exp $"
 
 #include <stdio.h>
 #include <ctype.h>
 
 #include <stdio.h>
 #include <ctype.h>
@@ -589,7 +589,8 @@ main(argc, argv)
         */
     disconnect:
        new_phase(PHASE_DISCONNECT);
         */
     disconnect:
        new_phase(PHASE_DISCONNECT);
-       the_channel->disconnect();
+       if (the_channel->disconnect)
+           the_channel->disconnect();
 
     fail:
        if (the_channel->cleanup)
 
     fail:
        if (the_channel->cleanup)
@@ -1172,6 +1173,7 @@ print_link_stats()
        info("Connect time %d.%d minutes.", t/10, t%10);
        info("Sent %u bytes, received %u bytes.",
            link_stats.bytes_out, link_stats.bytes_in);
        info("Connect time %d.%d minutes.", t/10, t%10);
        info("Sent %u bytes, received %u bytes.",
            link_stats.bytes_out, link_stats.bytes_in);
+       link_stats_valid = 0;
     }
 }
 
     }
 }
 
@@ -1328,6 +1330,7 @@ timeleft(tvp)
 
 /*
  * kill_my_pg - send a signal to our process group, and ignore it ourselves.
 
 /*
  * kill_my_pg - send a signal to our process group, and ignore it ourselves.
+ * We assume that sig is currently blocked.
  */
 static void
 kill_my_pg(sig)
  */
 static void
 kill_my_pg(sig)
@@ -1335,9 +1338,23 @@ kill_my_pg(sig)
 {
     struct sigaction act, oldact;
 
 {
     struct sigaction act, oldact;
 
+    sigemptyset(&act.sa_mask);
+    sigaddset(&act.sa_mask, sig);
+
     act.sa_handler = SIG_IGN;
     act.sa_flags = 0;
     kill(0, sig);
     act.sa_handler = SIG_IGN;
     act.sa_flags = 0;
     kill(0, sig);
+    /*
+     * The kill() above made the signal pending for us, as well as
+     * the rest of our process group, but we don't want it delivered
+     * to us.  It is blocked at the moment.  Setting it to be ignored
+     * will cause the pending signal to be discarded.  If we did the
+     * kill() after setting the signal to be ignored, it is unspecified
+     * (by POSIX) whether the signal is immediately discarded or left
+     * pending, and in fact Linux would leave it pending, and so it
+     * would be delivered after the current signal handler exits,
+     * leading to an infinite loop.
+     */
     sigaction(sig, &act, &oldact);
     sigaction(sig, &oldact, NULL);
 }
     sigaction(sig, &act, &oldact);
     sigaction(sig, &oldact, NULL);
 }