aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2023-07-12 11:52:06 +0100
committerRon Yorston <rmy@pobox.com>2023-07-12 11:52:06 +0100
commitb2901ce8efa050da00e0f3a73f3be9bf9402deea (patch)
tree6a5d2262a464867c38594f41f8ab5d33047ce307
parent8e699173370d68262273390e1b631300d9c5017c (diff)
downloadbusybox-w32-b2901ce8efa050da00e0f3a73f3be9bf9402deea.tar.gz
busybox-w32-b2901ce8efa050da00e0f3a73f3be9bf9402deea.tar.bz2
busybox-w32-b2901ce8efa050da00e0f3a73f3be9bf9402deea.zip
ash: fix 'read' shell built-in (2)
Enabling polling in the previous commit resulted in the following incorrect behaviour: { echo -n te; sleep 3; echo st; } | (read -t 1 x; echo "$x") An empty "$x" is echoed immediately, not after 1 second. { echo -n te; sleep 1; echo st; } | (read -t 3 x; echo "$x") An empty "$x" is echoed immediately. "test" should be echoed after 1 second. This arises because poll(2) from gnulib is unable to handle anonymous pipes properly due do deficiencies in Microsoft Windows. These have been acknowledged and fixed in relation to select(2): https://lists.gnu.org/archive/html/bug-gnulib/2014-06/msg00051.html Apply a similar fix to poll(2). Costs 104-156 bytes.
-rw-r--r--win32/poll.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/win32/poll.c b/win32/poll.c
index dd3b2d1cb..4b825c5cc 100644
--- a/win32/poll.c
+++ b/win32/poll.c
@@ -469,6 +469,9 @@ poll (struct pollfd *pfd, nfds_t nfd, int timeout)
469 MSG msg; 469 MSG msg;
470 int rc = 0; 470 int rc = 0;
471 nfds_t i; 471 nfds_t i;
472 DWORD real_timeout = 0;
473 int save_timeout = timeout;
474 clock_t tend = clock () + timeout;
472 475
473 if (nfd > INT_MAX || timeout < -1) 476 if (nfd > INT_MAX || timeout < -1)
474 { 477 {
@@ -480,6 +483,14 @@ poll (struct pollfd *pfd, nfds_t nfd, int timeout)
480 hEvent = CreateEvent (NULL, FALSE, FALSE, NULL); 483 hEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
481 484
482restart: 485restart:
486 /* How much is left to wait? */
487 timeout = save_timeout;
488 if (timeout != INFTIM)
489 {
490 clock_t now = clock ();
491 real_timeout = tend > now ? tend - now : 0;
492 }
493
483 handle_array[0] = hEvent; 494 handle_array[0] = hEvent;
484 nhandles = 1; 495 nhandles = 1;
485 FD_ZERO (&rfds); 496 FD_ZERO (&rfds);
@@ -620,7 +631,7 @@ restart:
620 rc++; 631 rc++;
621 } 632 }
622 633
623 if (!rc && timeout == INFTIM) 634 if (!rc && (save_timeout == INFTIM || (real_timeout != 0 && nhandles > 1)))
624 { 635 {
625 SleepEx (1, TRUE); 636 SleepEx (1, TRUE);
626 goto restart; 637 goto restart;