diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2018-02-11 13:48:52 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2018-02-11 13:48:52 +0100 |
commit | e015d0659fd3039c321b179190834c7e5909522a (patch) | |
tree | 47598b30a85362468e541f4b3790dcb6d9a3e9d8 | |
parent | a3ec3bd0f85befdc95657a249b4cc789667440d7 (diff) | |
download | busybox-w32-e015d0659fd3039c321b179190834c7e5909522a.tar.gz busybox-w32-e015d0659fd3039c321b179190834c7e5909522a.tar.bz2 busybox-w32-e015d0659fd3039c321b179190834c7e5909522a.zip |
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 898c3054e..97e9e680a 100644 --- a/networking/arping.c +++ b/networking/arping.c | |||
@@ -413,28 +413,37 @@ int arping_main(int argc UNUSED_PARAM, char **argv) | |||
413 | printf(" from %s %s\n", inet_ntoa(src), device); | 413 | printf(" from %s %s\n", inet_ntoa(src), device); |
414 | } | 414 | } |
415 | 415 | ||
416 | packet = xmalloc(4096); | ||
417 | |||
416 | signal_SA_RESTART_empty_mask(SIGINT, (void (*)(int))finish); | 418 | signal_SA_RESTART_empty_mask(SIGINT, (void (*)(int))finish); |
417 | signal_SA_RESTART_empty_mask(SIGALRM, (void (*)(int))catcher); | 419 | signal_SA_RESTART_empty_mask(SIGALRM, (void (*)(int))catcher); |
418 | 420 | ||
421 | /* Send the first packet, arm ALRM */ | ||
419 | catcher(); | 422 | catcher(); |
420 | 423 | ||
421 | packet = xmalloc(4096); | ||
422 | while (1) { | 424 | while (1) { |
423 | sigset_t sset, osset; | 425 | sigset_t sset; |
424 | struct sockaddr_ll from; | 426 | struct sockaddr_ll from; |
425 | socklen_t alen = sizeof(from); | 427 | socklen_t alen = sizeof(from); |
426 | int cc; | 428 | int cc; |
427 | 429 | ||
430 | sigemptyset(&sset); | ||
431 | sigaddset(&sset, SIGALRM); | ||
432 | sigaddset(&sset, SIGINT); | ||
433 | /* Unblock SIGALRM so that the previously called alarm() | ||
434 | * can prevent recvfrom from blocking forever in case the | ||
435 | * inherited procmask is blocking SIGALRM. | ||
436 | */ | ||
437 | sigprocmask(SIG_UNBLOCK, &sset, NULL); | ||
438 | |||
428 | cc = recvfrom(sock_fd, packet, 4096, 0, (struct sockaddr *) &from, &alen); | 439 | cc = recvfrom(sock_fd, packet, 4096, 0, (struct sockaddr *) &from, &alen); |
440 | |||
441 | /* Don't allow SIGALRMs while we process the reply */ | ||
442 | sigprocmask(SIG_BLOCK, &sset, NULL); | ||
429 | if (cc < 0) { | 443 | if (cc < 0) { |
430 | bb_perror_msg("recvfrom"); | 444 | bb_perror_msg("recvfrom"); |
431 | continue; | 445 | continue; |
432 | } | 446 | } |
433 | sigemptyset(&sset); | ||
434 | sigaddset(&sset, SIGALRM); | ||
435 | sigaddset(&sset, SIGINT); | ||
436 | sigprocmask(SIG_BLOCK, &sset, &osset); | ||
437 | recv_pack(packet, cc, &from); | 447 | recv_pack(packet, cc, &from); |
438 | sigprocmask(SIG_SETMASK, &osset, NULL); | ||
439 | } | 448 | } |
440 | } | 449 | } |