diff options
author | Ron Yorston <rmy@pobox.com> | 2023-07-12 11:52:06 +0100 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2023-07-12 11:52:06 +0100 |
commit | b2901ce8efa050da00e0f3a73f3be9bf9402deea (patch) | |
tree | 6a5d2262a464867c38594f41f8ab5d33047ce307 | |
parent | 8e699173370d68262273390e1b631300d9c5017c (diff) | |
download | busybox-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.c | 13 |
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 | ||
482 | restart: | 485 | restart: |
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; |