pppd/main.c | 40 ++++++++++++++++------------------------ pppd/pppd.h | 1 + pppd/sys-linux.c | 6 ++++-- pppd/tty.c | 6 +++++- 4 files changed, 26 insertions(+), 27 deletions(-) diff --git a/pppd/main.c b/pppd/main.c index 014d614..fabce24 100644 --- a/pppd/main.c +++ b/pppd/main.c @@ -211,6 +211,8 @@ int error_count; 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. @@ -254,7 +256,6 @@ static void delete_db_key __P((const char *)); static void cleanup_db __P((void)); #endif -static void handle_events __P((void)); void print_link_stats __P((void)); extern char *ttyname __P((int)); @@ -603,7 +604,7 @@ main(argc, argv) /* * handle_events - wait for something to happen and respond to it. */ -static void +void handle_events() { struct timeval timo; @@ -727,6 +728,8 @@ setup_signals() * be sufficient. */ signal(SIGPIPE, SIG_IGN); + + sigemptyset(&ignored_signals); } /* @@ -1383,26 +1386,6 @@ static void 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; - 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 @@ -1414,8 +1397,15 @@ kill_my_pg(sig) * 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); + } } @@ -1436,6 +1426,7 @@ hup(sig) /* 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); } @@ -1457,6 +1448,7 @@ term(sig) /* 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 --git a/pppd/pppd.h b/pppd/pppd.h index cf9840a..cb083bb 100644 --- a/pppd/pppd.h +++ b/pppd/pppd.h @@ -465,6 +465,7 @@ extern struct channel *the_channel; */ /* 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 --git a/pppd/sys-linux.c b/pppd/sys-linux.c index b675c97..5125960 100644 --- a/pppd/sys-linux.c +++ b/pppd/sys-linux.c @@ -1020,8 +1020,10 @@ void restore_tty (int tty_fd) 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 --git a/pppd/tty.c b/pppd/tty.c index d571b11..4cf0090 100644 --- a/pppd/tty.c +++ b/pppd/tty.c @@ -690,6 +690,7 @@ int connect_tty() status = EXIT_INIT_FAILED; goto errretf; } + handle_events(); if (got_sigterm) { disconnect_tty(); goto errretf; @@ -700,9 +701,11 @@ int connect_tty() 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 errretf; } + handle_events(); if (got_sigterm) { disconnect_tty(); goto errretf; @@ -729,6 +732,7 @@ int connect_tty() error("Failed to reopen %s: %m", devnam); status = EXIT_OPEN_FAILED; } + handle_events(); if (!persist || errno != EINTR || hungup || got_sigterm) goto errret; }