diff options
author | Denys Vlasenko | 2018-02-11 13:48:52 +0100 |
---|---|---|
committer | Denys Vlasenko | 2018-02-11 13:48:52 +0100 |
commit | e015d0659fd3039c321b179190834c7e5909522a (patch) | |
tree | 47598b30a85362468e541f4b3790dcb6d9a3e9d8 | |
parent | a3ec3bd0f85befdc95657a249b4cc789667440d7 (diff) | |
download | busybox-e015d0659fd3039c321b179190834c7e5909522a.zip busybox-e015d0659fd3039c321b179190834c7e5909522a.tar.gz |
arping: fix the case when inherited signal mask masks out ALRM
function old new delta
arping_main 1629 1635 +6
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | networking/arping.c | 23 |
1 files changed, 16 insertions, 7 deletions
diff --git a/networking/arping.c b/networking/arping.c index 898c305..97e9e68 100644 --- a/networking/arping.c +++ b/networking/arping.c @@ -413,28 +413,37 @@ int arping_main(int argc UNUSED_PARAM, char **argv) printf(" from %s %s\n", inet_ntoa(src), device); } + packet = xmalloc(4096); + signal_SA_RESTART_empty_mask(SIGINT, (void (*)(int))finish); signal_SA_RESTART_empty_mask(SIGALRM, (void (*)(int))catcher); + /* Send the first packet, arm ALRM */ catcher(); - packet = xmalloc(4096); while (1) { - sigset_t sset, osset; + sigset_t sset; struct sockaddr_ll from; socklen_t alen = sizeof(from); int cc; + sigemptyset(&sset); + sigaddset(&sset, SIGALRM); + sigaddset(&sset, SIGINT); + /* Unblock SIGALRM so that the previously called alarm() + * can prevent recvfrom from blocking forever in case the + * inherited procmask is blocking SIGALRM. + */ + sigprocmask(SIG_UNBLOCK, &sset, NULL); + cc = recvfrom(sock_fd, packet, 4096, 0, (struct sockaddr *) &from, &alen); + + /* Don't allow SIGALRMs while we process the reply */ + sigprocmask(SIG_BLOCK, &sset, NULL); if (cc < 0) { bb_perror_msg("recvfrom"); continue; } - sigemptyset(&sset); - sigaddset(&sset, SIGALRM); - sigaddset(&sset, SIGINT); - sigprocmask(SIG_BLOCK, &sset, &osset); recv_pack(packet, cc, &from); - sigprocmask(SIG_SETMASK, &osset, NULL); } } |