summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko2018-02-11 13:48:52 +0100
committerDenys Vlasenko2018-02-11 13:48:52 +0100
commite015d0659fd3039c321b179190834c7e5909522a (patch)
tree47598b30a85362468e541f4b3790dcb6d9a3e9d8
parenta3ec3bd0f85befdc95657a249b4cc789667440d7 (diff)
downloadbusybox-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.c23
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);
}
}