From: pali <7141871+pali@users.noreply.github.com> Date: Mon, 25 May 2020 05:35:55 +0000 (+0200) Subject: pppd: Handle SIGINT and SIGTERM during interrupted syscalls (#148) X-Git-Tag: ppp-2.4.9~60 X-Git-Url: https://git.ozlabs.org/?p=ppp.git;a=commitdiff_plain;h=c319558b8cacad7d27f04c7d612e44b67f273434 pppd: Handle SIGINT and SIGTERM during interrupted syscalls (#148) When pppd receives SIGINT or SIGTERM it should handle it and not try to restart interrupted syscall. This change fixes problem that pppd cannot be terminated by SIGINT or SIGTERM signal when pppd plugins are used. Signed-off-by: Pali Rohár --- diff --git a/pppd/plugins/passprompt.c b/pppd/plugins/passprompt.c index babb6dc..44e3815 100644 --- a/pppd/plugins/passprompt.c +++ b/pppd/plugins/passprompt.c @@ -74,7 +74,7 @@ static int promptpass(char *user, char *passwd) if (red == 0) break; if (red < 0) { - if (errno == EINTR) + if (errno == EINTR && !got_sigterm) continue; error("Can't read secret from %s: %m", promptprog); readgood = -1; @@ -86,7 +86,7 @@ static int promptpass(char *user, char *passwd) /* now wait for child to exit */ while (waitpid(kid, &wstat, 0) < 0) { - if (errno != EINTR) { + if (errno != EINTR || got_sigterm) { warn("error waiting for %s: %m", promptprog); break; } diff --git a/pppd/plugins/radius/sendserver.c b/pppd/plugins/radius/sendserver.c index f68aa67..0c0ef30 100644 --- a/pppd/plugins/radius/sendserver.c +++ b/pppd/plugins/radius/sendserver.c @@ -302,7 +302,7 @@ int rc_send_server (SEND_DATA *data, char *msg, REQUEST_INFO *info) FD_SET (sockfd, &readfds); if (select (sockfd + 1, &readfds, NULL, NULL, &authtime) < 0) { - if (errno == EINTR) + if (errno == EINTR && !got_sigterm) continue; error("rc_send_server: select: %m"); memset (secret, '\0', sizeof (secret)); diff --git a/pppd/plugins/rp-pppoe/discovery.c b/pppd/plugins/rp-pppoe/discovery.c index a4e4cec..fd851de 100644 --- a/pppd/plugins/rp-pppoe/discovery.c +++ b/pppd/plugins/rp-pppoe/discovery.c @@ -369,7 +369,7 @@ waitForPADO(PPPoEConnection *conn, int timeout) while(1) { r = select(conn->discoverySocket+1, &readable, NULL, NULL, &tv); - if (r >= 0 || errno != EINTR) break; + if (r >= 0 || errno != EINTR || got_sigterm) break; } if (r < 0) { error("select (waitForPADO): %m"); @@ -550,7 +550,7 @@ waitForPADS(PPPoEConnection *conn, int timeout) while(1) { r = select(conn->discoverySocket+1, &readable, NULL, NULL, &tv); - if (r >= 0 || errno != EINTR) break; + if (r >= 0 || errno != EINTR || got_sigterm) break; } if (r < 0) { error("select (waitForPADS): %m"); @@ -622,7 +622,7 @@ discovery(PPPoEConnection *conn) do { padiAttempts++; - if (padiAttempts > conn->discoveryAttempts) { + if (got_sigterm || padiAttempts > conn->discoveryAttempts) { warn("Timeout waiting for PADO packets"); close(conn->discoverySocket); conn->discoverySocket = -1; @@ -638,7 +638,7 @@ discovery(PPPoEConnection *conn) timeout = conn->discoveryTimeout; do { padrAttempts++; - if (padrAttempts > conn->discoveryAttempts) { + if (got_sigterm || padrAttempts > conn->discoveryAttempts) { warn("Timeout waiting for PADS packets"); close(conn->discoverySocket); conn->discoverySocket = -1; diff --git a/pppd/plugins/winbind.c b/pppd/plugins/winbind.c index 4638f46..0c395c3 100644 --- a/pppd/plugins/winbind.c +++ b/pppd/plugins/winbind.c @@ -443,7 +443,7 @@ unsigned int run_ntlm_auth(const char *username, return NOT_AUTHENTICATED; } - while ((wait(&status) == -1) && errno == EINTR) + while ((wait(&status) == -1) && errno == EINTR && !got_sigterm) ; if ((authenticated == AUTHENTICATED) && nt_key && !got_user_session_key) { diff --git a/pppd/pppd.h b/pppd/pppd.h index 4ab2ac1..f44fe01 100644 --- a/pppd/pppd.h +++ b/pppd/pppd.h @@ -223,6 +223,7 @@ struct notifier { * Global variables. */ +extern int got_sigterm; /* SIGINT or SIGTERM was received */ extern int hungup; /* Physical layer has disconnected */ extern int ifunit; /* Interface unit number */ extern char ifname[]; /* Interface name */ diff --git a/pppd/sys-solaris.c b/pppd/sys-solaris.c index 65b173a..a85c733 100644 --- a/pppd/sys-solaris.c +++ b/pppd/sys-solaris.c @@ -2427,7 +2427,7 @@ dlpi_get_reply(fd, reply, expected_prim, maxlen) pfd.events = POLLIN | POLLPRI; do { n = poll(&pfd, 1, 1000); - } while (n == -1 && errno == EINTR); + } while (n == -1 && errno == EINTR && !got_sigterm); if (n <= 0) return -1; diff --git a/pppd/utils.c b/pppd/utils.c index 3602aa6..23189d0 100644 --- a/pppd/utils.c +++ b/pppd/utils.c @@ -835,7 +835,7 @@ complete_read(int fd, void *buf, size_t count) for (done = 0; done < count; ) { nb = read(fd, ptr, count - done); if (nb < 0) { - if (errno == EINTR) + if (errno == EINTR && !got_sigterm) continue; return -1; }