The sleep builtin currently doesn't do much in the way of signal
management, so for example it will return on SIGWINCH, which I think most
users will be particularly surprised by the first time they notice a sleep
ending early due to a window resize.
I looked at adding more signal handling to the current select-based
implementation but then realized it would be a lot easier to just use
nanosleep(2).
Both select() and nanosleep() first appear in 1997's XSH Issue 5 so I don't
know if we need to worry much about systems without it. (The patch leaves
the select/pselect code as fallback though).
---
diff --git a/config.h.in b/config.h.in
index c2750a2a..1b6a1853 100644
--- a/config.h.in
+++ b/config.h.in
@@ -771,6 +771,9 @@
/* Define if you have the mkstemp function. */
#undef HAVE_MKSTEMP
+/* Define if you have the nonosleep function. */
+#undef HAVE_NANOSLEEP
+
/* Define if you have the pathconf function. */
#undef HAVE_PATHCONF
diff --git a/configure.ac b/configure.ac
index 29f50438..de7d693c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -850,9 +850,9 @@ AC_REPLACE_FUNCS(rename)
dnl checks for c library functions
AC_CHECK_FUNCS(bcopy bzero clock_gettime confstr faccessat fnmatch \
getaddrinfo gethostbyname getservbyname getservent
inet_aton \
- imaxdiv memmove pathconf putenv raise random regcomp
regexec \
- setenv setlinebuf setlocale setvbuf siginterrupt strchr \
- sysconf syslog tcgetattr times ttyname tzset unsetenv)
+ imaxdiv memmove nanosleep pathconf putenv raise random
regcomp \
+ regexec setenv setlinebuf setlocale setvbuf siginterrupt \
+ strchr sysconf syslog tcgetattr times ttyname tzset
unsetenv)
AC_CHECK_FUNCS(vasprintf asprintf)
AC_CHECK_FUNCS(isascii isblank isgraph isprint isspace isxdigit)
diff --git a/lib/sh/ufuncs.c b/lib/sh/ufuncs.c
index 247224d6..b3894450 100644
--- a/lib/sh/ufuncs.c
+++ b/lib/sh/ufuncs.c
@@ -82,7 +82,26 @@ falarm (unsigned int secs, unsigned int usecs)
/* A version of sleep using fractional seconds and select. I'd like to use
`usleep', but it's already taken */
-#if defined (HAVE_TIMEVAL) && (defined (HAVE_SELECT) || defined
(HAVE_PSELECT))
+#if defined (HAVE_NANOSLEEP)
+int
+fsleep(unsigned int sec, unsigned int usec)
+{
+ int r;
+ struct timespec req, rem;
+
+ req.tv_sec = sec;
+ req.tv_nsec = usec * 1000;
+
+ for (;;)
+{
+ QUIT;
+ r = nanosleep (, );
+ if (r == 0 || errno != EINTR)
+return r;
+ req = rem;
+}
+}
+#elif defined (HAVE_TIMEVAL) && (defined (HAVE_SELECT) || defined
(HAVE_PSELECT))
int
fsleep(unsigned int sec, unsigned int usec)
{
From a33289b218028b6d72966d8253646d6f174e09a5 Mon Sep 17 00:00:00 2001
From: Grisha Levit
Date: Thu, 29 Jun 2023 21:55:05 -0400
Subject: [PATCH] fsleep: use nanosleep, handle signals
---
config.h.in | 3 +++
configure.ac| 6 +++---
lib/sh/ufuncs.c | 21 -
3 files changed, 26 insertions(+), 4 deletions(-)
diff --git a/config.h.in b/config.h.in
index c2750a2a..1b6a1853 100644
--- a/config.h.in
+++ b/config.h.in
@@ -771,6 +771,9 @@
/* Define if you have the mkstemp function. */
#undef HAVE_MKSTEMP
+/* Define if you have the nonosleep function. */
+#undef HAVE_NANOSLEEP
+
/* Define if you have the pathconf function. */
#undef HAVE_PATHCONF
diff --git a/configure.ac b/configure.ac
index 29f50438..de7d693c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -850,9 +850,9 @@ AC_REPLACE_FUNCS(rename)
dnl checks for c library functions
AC_CHECK_FUNCS(bcopy bzero clock_gettime confstr faccessat fnmatch \
getaddrinfo gethostbyname getservbyname getservent inet_aton \
- imaxdiv memmove pathconf putenv raise random regcomp regexec \
- setenv setlinebuf setlocale setvbuf siginterrupt strchr \
- sysconf syslog tcgetattr times ttyname tzset unsetenv)
+ imaxdiv memmove nanosleep pathconf putenv raise random regcomp \
+ regexec setenv setlinebuf setlocale setvbuf siginterrupt \
+ strchr sysconf syslog tcgetattr times ttyname tzset unsetenv)
AC_CHECK_FUNCS(vasprintf asprintf)
AC_CHECK_FUNCS(isascii isblank isgraph isprint isspace isxdigit)
diff --git a/lib/sh/ufuncs.c b/lib/sh/ufuncs.c
index 247224d6..b3894450 100644
--- a/lib/sh/ufuncs.c
+++ b/lib/sh/ufuncs.c
@@ -82,7 +82,26 @@ falarm (unsigned int secs, unsigned int usecs)
/* A version of sleep using fractional seconds and select. I'd like to use
`usleep', but it's already taken */
-#if defined (HAVE_TIMEVAL) && (defined (HAVE_SELECT) || defined (HAVE_PSELECT))
+#if defined (HAVE_NANOSLEEP)
+int
+fsleep(unsigned int sec, unsigned int usec)
+{
+ int r;
+ struct timespec req, rem;
+
+ req.tv_sec = sec;
+ req.tv_nsec = usec * 1000;
+
+ for (;;)
+{
+ QUIT;
+ r = nanosleep (, );
+ if (r == 0 || errno != EINTR)
+return r;
+ req = rem;
+}
+}
+#elif defined (HAVE_TIMEVAL) && (defined (HAVE_SELECT) || defined (HAVE_PSELECT))
int