tftp: fix bad interaction betweel poll() and alarm(). Closes bug 3061
authorDenys Vlasenko <dvlasenk@redhat.com>
Mon, 10 Jan 2011 11:51:44 +0000 (12:51 +0100)
committerDenys Vlasenko <dvlasenk@redhat.com>
Mon, 10 Jan 2011 11:51:44 +0000 (12:51 +0100)
This was breaking timeout handling.

function                                             old     new   delta
tftp_progress_update                                   -      45     +45
tftp_progress_done                                     -      32     +32
tftp_protocol                                       1839    1858     +19
tftp_progress_init                                     9      15      +6
tftp_main                                            298     286     -12
------------------------------------------------------------------------------
(add/remove: 2/0 grow/shrink: 2/1 up/down: 102/-12)            Total: 90 bytes

Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
libbb/progress.c
networking/tftp.c

index 4c2763c53930f109440e8fb3d57468c584113202..74e80a39e8c13edc8f0d44e133cb5760b133f5cf 100644 (file)
@@ -78,7 +78,7 @@ void FAST_FUNC bb_progress_update(bb_progress_t *p,
        /* Do not update on every call
         * (we can be called on every network read!) */
        if (since_last_update == 0 && !totalsize)
-                       return;
+               return;
 
        beg_and_transferred = beg_range + transferred;
        ratio = 100;
index 04c8f0ebba19d95571440401c5633b1952af39a5..fcd933f6ad76adcd416b347faa6fa6eb3a7032b1 100644 (file)
@@ -105,39 +105,22 @@ struct BUG_G_too_big {
 #define error_pkt_str    (error_pkt + 4)
 
 #if ENABLE_FEATURE_TFTP_PROGRESS_BAR
-/* SIGALRM logic nicked from the wget applet */
-static void progress_meter(int flag)
+static void tftp_progress_update(void)
 {
-       /* We can be called from signal handler */
-       int save_errno = errno;
-
-       if (flag == -1) { /* first call to progress_meter */
-               bb_progress_init(&G.pmt);
-       }
-
        bb_progress_update(&G.pmt, G.file, 0, G.pos, G.size);
-
-       if (flag == 0) {
-               /* last call to progress_meter */
-               alarm(0);
-               bb_putchar_stderr('\n');
-       } else {
-               if (flag == -1) { /* first call to progress_meter */
-                       signal_SA_RESTART_empty_mask(SIGALRM, progress_meter);
-               }
-               alarm(1);
-       }
-
-       errno = save_errno;
 }
 static void tftp_progress_init(void)
 {
-       progress_meter(-1);
+       bb_progress_init(&G.pmt);
+       tftp_progress_update();
 }
 static void tftp_progress_done(void)
 {
-       if (G.pmt.inited)
-               progress_meter(0);
+       if (G.pmt.inited) {
+               tftp_progress_update();
+               bb_putchar_stderr('\n');
+               G.pmt.inited = 0;
+       }
 }
 #else
 # define tftp_progress_init() ((void)0)
@@ -460,9 +443,10 @@ static int tftp_protocol(
                xsendto(socket_fd, xbuf, send_len, &peer_lsa->u.sa, peer_lsa->len);
 
 #if ENABLE_FEATURE_TFTP_PROGRESS_BAR
-               if (ENABLE_TFTP && remote_file) /* tftp */
+               if (ENABLE_TFTP && remote_file) /* tftp */
                        G.pos = (block_nr - 1) * (uoff_t)blksize;
-               }
+               if (G.pmt.inited)
+                       tftp_progress_update();
 #endif
                /* Was it final ACK? then exit */
                if (finished && (opcode == TFTP_ACK))
@@ -479,6 +463,7 @@ static int tftp_protocol(
                case 0:
                        retries--;
                        if (retries == 0) {
+                               tftp_progress_done();
                                bb_error_msg("timeout");
                                goto ret; /* no err packet sent */
                        }