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 | } |
