aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--networking/arping.c23
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}