diff options
-rw-r--r-- | networking/nc_bloaty.c | 55 |
1 files changed, 24 insertions, 31 deletions
diff --git a/networking/nc_bloaty.c b/networking/nc_bloaty.c index 192e42fe5..f8c375362 100644 --- a/networking/nc_bloaty.c +++ b/networking/nc_bloaty.c | |||
@@ -582,11 +582,10 @@ void oprint(int direction, unsigned char *p, unsigned bc); | |||
582 | #endif | 582 | #endif |
583 | 583 | ||
584 | /* readwrite: | 584 | /* readwrite: |
585 | handle stdin/stdout/network I/O. Bwahaha!! -- the select loop from hell. | 585 | handle stdin/stdout/network I/O. Bwahaha!! -- the i/o loop from hell. |
586 | In this instance, return what might become our exit status. */ | 586 | In this instance, return what might become our exit status. */ |
587 | static int readwrite(void) | 587 | static int readwrite(void) |
588 | { | 588 | { |
589 | int rr; | ||
590 | char *zp = zp; /* gcc */ /* stdin buf ptr */ | 589 | char *zp = zp; /* gcc */ /* stdin buf ptr */ |
591 | char *np = np; /* net-in buf ptr */ | 590 | char *np = np; /* net-in buf ptr */ |
592 | unsigned rzleft; | 591 | unsigned rzleft; |
@@ -594,45 +593,41 @@ static int readwrite(void) | |||
594 | unsigned netretry; /* net-read retry counter */ | 593 | unsigned netretry; /* net-read retry counter */ |
595 | unsigned fds_open; | 594 | unsigned fds_open; |
596 | 595 | ||
597 | /* if you don't have all this FD_* macro hair in sys/types.h, you'll have to | 596 | struct pollfd pfds[2]; |
598 | either find it or do your own bit-bashing: *ding1 |= (1 << fd), etc... */ | 597 | pfds[0].fd = STDIN_FILENO; |
599 | fd_set ding1; /* for select loop */ | 598 | pfds[0].events = POLLIN; |
600 | fd_set ding2; | 599 | pfds[1].fd = netfd; |
601 | FD_ZERO(&ding1); | 600 | pfds[1].events = POLLIN; |
602 | FD_SET(netfd, &ding1); | ||
603 | FD_SET(STDIN_FILENO, &ding1); | ||
604 | fds_open = 2; | ||
605 | 601 | ||
602 | fds_open = 2; | ||
606 | netretry = 2; | 603 | netretry = 2; |
607 | rzleft = rnleft = 0; | 604 | rzleft = rnleft = 0; |
608 | if (o_interval) | 605 | if (o_interval) |
609 | sleep(o_interval); /* pause *before* sending stuff, too */ | 606 | sleep(o_interval); /* pause *before* sending stuff, too */ |
610 | 607 | ||
611 | /* and now the big ol' select shoveling loop ... */ | 608 | /* and now the big ol' shoveling loop ... */ |
612 | /* nc 1.10 has "while (FD_ISSET(netfd)" here */ | 609 | /* nc 1.10 has "while (FD_ISSET(netfd)" here */ |
613 | while (fds_open) { | 610 | while (fds_open) { |
611 | int rr; | ||
612 | int poll_tmout_ms; | ||
614 | unsigned wretry = 8200; /* net-write sanity counter */ | 613 | unsigned wretry = 8200; /* net-write sanity counter */ |
615 | 614 | ||
616 | ding2 = ding1; /* FD_COPY ain't portable... */ | 615 | poll_tmout_ms = -1; |
617 | /* some systems, notably linux, crap into their select timers on return, so | ||
618 | we create a expendable copy and give *that* to select. */ | ||
619 | if (o_wait) { | 616 | if (o_wait) { |
620 | struct timeval tmp_timer; | 617 | poll_tmout_ms = INT_MAX; |
621 | tmp_timer.tv_sec = o_wait; | 618 | if (o_wait < INT_MAX / 1000) |
622 | tmp_timer.tv_usec = 0; | 619 | poll_tmout_ms = o_wait * 1000; |
623 | /* highest possible fd is netfd (3) */ | 620 | } |
624 | rr = select(netfd+1, &ding2, NULL, NULL, &tmp_timer); | 621 | rr = poll(pfds, 2, poll_tmout_ms); |
625 | } else | ||
626 | rr = select(netfd+1, &ding2, NULL, NULL, NULL); | ||
627 | if (rr < 0 && errno != EINTR) { /* might have gotten ^Zed, etc */ | 622 | if (rr < 0 && errno != EINTR) { /* might have gotten ^Zed, etc */ |
628 | holler_perror("select"); | 623 | holler_perror("poll"); |
629 | close(netfd); | 624 | close(netfd); |
630 | return 1; | 625 | return 1; |
631 | } | 626 | } |
632 | /* if we have a timeout AND stdin is closed AND we haven't heard anything | 627 | /* if we have a timeout AND stdin is closed AND we haven't heard anything |
633 | from the net during that time, assume it's dead and close it too. */ | 628 | from the net during that time, assume it's dead and close it too. */ |
634 | if (rr == 0) { | 629 | if (rr == 0) { |
635 | if (!FD_ISSET(STDIN_FILENO, &ding1)) { | 630 | if (!pfds[0].revents) { |
636 | netretry--; /* we actually try a coupla times. */ | 631 | netretry--; /* we actually try a coupla times. */ |
637 | if (!netretry) { | 632 | if (!netretry) { |
638 | if (o_verbose > 1) /* normally we don't care */ | 633 | if (o_verbose > 1) /* normally we don't care */ |
@@ -641,19 +636,17 @@ static int readwrite(void) | |||
641 | return 0; /* not an error! */ | 636 | return 0; /* not an error! */ |
642 | } | 637 | } |
643 | } | 638 | } |
644 | } /* select timeout */ | 639 | } /* timeout */ |
645 | /* xxx: should we check the exception fds too? The read fds seem to give | ||
646 | us the right info, and none of the examples I found bothered. */ | ||
647 | 640 | ||
648 | /* Ding!! Something arrived, go check all the incoming hoppers, net first */ | 641 | /* Ding!! Something arrived, go check all the incoming hoppers, net first */ |
649 | if (FD_ISSET(netfd, &ding2)) { /* net: ding! */ | 642 | if (pfds[1].revents) { /* net: ding! */ |
650 | rr = read(netfd, bigbuf_net, BIGSIZ); | 643 | rr = read(netfd, bigbuf_net, BIGSIZ); |
651 | if (rr <= 0) { | 644 | if (rr <= 0) { |
652 | if (rr < 0 && o_verbose > 1) { | 645 | if (rr < 0 && o_verbose > 1) { |
653 | /* nc 1.10 doesn't do this */ | 646 | /* nc 1.10 doesn't do this */ |
654 | bb_perror_msg("net read"); | 647 | bb_perror_msg("net read"); |
655 | } | 648 | } |
656 | FD_CLR(netfd, &ding1); /* net closed */ | 649 | pfds[1].fd = -1; /* don't poll for netfd anymore */ |
657 | fds_open--; | 650 | fds_open--; |
658 | rzleft = 0; /* can't write anymore: broken pipe */ | 651 | rzleft = 0; /* can't write anymore: broken pipe */ |
659 | } else { | 652 | } else { |
@@ -669,12 +662,12 @@ Debug("got %d from the net, errno %d", rr, errno); | |||
669 | goto shovel; | 662 | goto shovel; |
670 | 663 | ||
671 | /* okay, suck more stdin */ | 664 | /* okay, suck more stdin */ |
672 | if (FD_ISSET(STDIN_FILENO, &ding2)) { /* stdin: ding! */ | 665 | if (pfds[0].revents) { /* stdin: ding! */ |
673 | rr = read(STDIN_FILENO, bigbuf_in, BIGSIZ); | 666 | rr = read(STDIN_FILENO, bigbuf_in, BIGSIZ); |
674 | /* Considered making reads here smaller for UDP mode, but 8192-byte | 667 | /* Considered making reads here smaller for UDP mode, but 8192-byte |
675 | mobygrams are kinda fun and exercise the reassembler. */ | 668 | mobygrams are kinda fun and exercise the reassembler. */ |
676 | if (rr <= 0) { /* at end, or fukt, or ... */ | 669 | if (rr <= 0) { /* at end, or fukt, or ... */ |
677 | FD_CLR(STDIN_FILENO, &ding1); /* disable stdin */ | 670 | pfds[0].fd = -1; /* disable stdin */ |
678 | /*close(STDIN_FILENO); - not really necessary */ | 671 | /*close(STDIN_FILENO); - not really necessary */ |
679 | /* Let peer know we have no more data */ | 672 | /* Let peer know we have no more data */ |
680 | /* nc 1.10 doesn't do this: */ | 673 | /* nc 1.10 doesn't do this: */ |
@@ -718,7 +711,7 @@ Debug("wrote %d to net, errno %d", rr, errno); | |||
718 | } /* rzleft */ | 711 | } /* rzleft */ |
719 | if (o_interval) { /* cycle between slow lines, or ... */ | 712 | if (o_interval) { /* cycle between slow lines, or ... */ |
720 | sleep(o_interval); | 713 | sleep(o_interval); |
721 | continue; /* ...with hairy select loop... */ | 714 | continue; /* ...with hairy loop... */ |
722 | } | 715 | } |
723 | if (rzleft || rnleft) { /* shovel that shit till they ain't */ | 716 | if (rzleft || rnleft) { /* shovel that shit till they ain't */ |
724 | wretry--; /* none left, and get another load */ | 717 | wretry--; /* none left, and get another load */ |