-
Notifications
You must be signed in to change notification settings - Fork 31
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
sleep 10 | read
hangs interactive shell after ^Z
#750
Comments
Thank you for the pointers in #763 (comment), @McDutchie! I'd say it is a different bug than #750, tough. The following line seems to cause the problem: ksh/src/cmd/ksh93/bltins/sleep.c Line 143 in 9ea4e32
This conversion is actually not valid in C as shown by this experiment #include <math.h>
#include <stdio.h>
int main(void) {
double d = INFINITY;
printf("double = %f, int = %d\n", d, (int) d);
} $ clang -fsanitize=undefined inf.c && ./a.out
inf.c:6:42: runtime error: inf is outside the range of representable values of type 'int'
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior inf.c:6:42
double = inf, int = 2147483647 and the C99 standard itself:
|
Thanks for that. Looks like Here is a patch that should fix undefined behaviour and implement diff --git a/src/cmd/ksh93/bltins/sleep.c b/src/cmd/ksh93/bltins/sleep.c
index e849ef44b..a899e8279 100644
--- a/src/cmd/ksh93/bltins/sleep.c
+++ b/src/cmd/ksh93/bltins/sleep.c
@@ -29,6 +29,7 @@
#include <error.h>
#include <errno.h>
#include <tmx.h>
+#include <ast_float.h>
#include "builtins.h"
#include "FEATURE/time"
#include "FEATURE/poll"
@@ -140,9 +141,27 @@ skip:
*/
void sh_delay(double t, int sflag)
{
- int n = (int)t;
+ uint32_t n;
Tv_t ts, tx;
+#if _lib_fpclassify
+ switch (fpclassify(t))
+ {
+ case FP_NAN:
+ errormsg(SH_DICT,ERROR_exit(1),e_number,"NaN");
+ UNREACHABLE();
+ case FP_INFINITE:
+ ts.tv_sec = 0xFFFFFFFF; /* uint32_t max */
+ ts.tv_nsec = 0;
+ while (1)
+ {
+ tvsleep(&ts, NULL);
+ if ((sh.trapnote & (SH_SIGSET | SH_SIGTRAP)) || sflag)
+ return;
+ }
+ }
+#endif
+ n = (uint32_t)t;
ts.tv_sec = n;
ts.tv_nsec = 1000000000 * (t - (double)n);
while(tvsleep(&ts, &tx) < 0) |
Thank you, @McDutchie! I confirm that your patch fixes the issue described in #763 (comment). $ strace arch/linux.arm64-64/bin/ksh -c 'sleep inf'
...
rt_sigaction(SIGWINCH, {sa_handler=0x44ee5c, sa_mask=[], sa_flags=SA_INTERRUPT}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGALRM, {sa_handler=0x44ee5c, sa_mask=[], sa_flags=SA_INTERRUPT}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=4294967295, tv_nsec=0}, |
Found on comp.unix.shell:
The text was updated successfully, but these errors were encountered: