diff -ur ppp-2.4.4.orig/pppd/main.c ppp-2.4.4.sigterm/pppd/main.c --- ppp-2.4.4.orig/pppd/main.c 2006-06-04 07:52:50 +0400 +++ ppp-2.4.4.sigterm/pppd/main.c 2007-03-18 16:37:46 +0300 @@ -211,6 +211,8 @@ bool bundle_eof; bool bundle_terminating; +sigset_t ignored_signals; /* to be ignored due to kill_my_pg() call */ + /* * We maintain a list of child process pids and * functions to call when they exit. @@ -253,7 +255,6 @@ static void cleanup_db __P((void)); #endif -static void handle_events __P((void)); void print_link_stats __P((void)); extern char *ttyname __P((int)); @@ -602,7 +603,7 @@ /* * handle_events - wait for something to happen and respond to it. */ -static void +void handle_events() { struct timeval timo; @@ -726,6 +727,8 @@ * be sufficient. */ signal(SIGPIPE, SIG_IGN); + + sigemptyset(&ignored_signals); } /* @@ -1382,12 +1385,6 @@ kill_my_pg(sig) int sig; { - struct sigaction act, oldact; - - sigemptyset(&act.sa_mask); /* unnecessary in fact */ - 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 @@ -1399,8 +1396,15 @@ * would be delivered after the current signal handler exits, * leading to an infinite loop. */ - sigaction(sig, &act, &oldact); - sigaction(sig, &oldact, NULL); + if (sigismember(&ignored_signals, sig)) + { + sigdelset(&ignored_signals, sig); + } + else + { + sigaddset(&ignored_signals, sig); + kill(0, sig); + } } @@ -1442,6 +1446,7 @@ /* Send the signal to the [dis]connector process(es) also */ kill_my_pg(sig); notify(sigreceived, sig); + status = EXIT_USER_REQUEST; if (waiting) siglongjmp(sigjmp, 1); } diff -ur ppp-2.4.4.orig/pppd/pppd.h ppp-2.4.4.sigterm/pppd/pppd.h --- ppp-2.4.4.orig/pppd/pppd.h 2005-08-26 03:59:34 +0400 +++ ppp-2.4.4.sigterm/pppd/pppd.h 2007-03-18 16:39:10 +0300 @@ -464,6 +464,7 @@ */ /* Procedures exported from main.c. */ +void handle_events __P((void)); /* wait for smth to happen and respond to it*/ void set_ifunit __P((int)); /* set stuff that depends on ifunit */ void detach __P((void)); /* Detach from controlling tty */ void die __P((int)); /* Cleanup and exit */ diff -ur ppp-2.4.4.orig/pppd/sys-linux.c ppp-2.4.4.sigterm/pppd/sys-linux.c --- ppp-2.4.4.orig/pppd/sys-linux.c 2005-08-27 02:44:35 +0400 +++ ppp-2.4.4.sigterm/pppd/sys-linux.c 2007-03-18 16:41:28 +0300 @@ -996,8 +996,10 @@ if (!default_device) inittermios.c_lflag &= ~(ECHO | ECHONL); - if (tcsetattr(tty_fd, TCSAFLUSH, &inittermios) < 0) { - if (! ok_error (errno)) + // Ugly hack - with TCSAFLUSH it hangs if no modem is connected + // to COM port. + if (tcsetattr(tty_fd, TCSANOW, &inittermios) < 0) { + if (! ok_error (errno)) warn("tcsetattr: %m (line %d)", __LINE__); } } diff -ur ppp-2.4.4.orig/pppd/tty.c ppp-2.4.4.sigterm/pppd/tty.c --- ppp-2.4.4.orig/pppd/tty.c 2006-06-04 11:04:57 +0400 +++ ppp-2.4.4.sigterm/pppd/tty.c 2007-03-18 16:46:48 +0300 @@ -690,6 +690,7 @@ status = EXIT_INIT_FAILED; goto errret; } + handle_events(); if (got_sigterm) { disconnect_tty(); goto errret; @@ -700,9 +701,11 @@ if (connector && connector[0]) { if (device_script(connector, ttyfd, ttyfd, 0) < 0) { error("Connect script failed"); - status = EXIT_CONNECT_FAILED; + if (status != EXIT_USER_REQUEST) + status = EXIT_CONNECT_FAILED; goto errret; } + handle_events(); if (got_sigterm) { disconnect_tty(); goto errret; @@ -729,6 +732,7 @@ error("Failed to reopen %s: %m", devnam); status = EXIT_OPEN_FAILED; } + handle_events(); if (!persist || errno != EINTR || hungup || got_sigterm) goto errret; }