+2022-02-25 Paul Eggert <eggert@cs.ucla.edu>
+
+ nanosleep: simplify by using pselect
+ GNU Emacs avoids Gnulib’s ‘select’ module and uses only pselect,
+ which it implements in a special way on MS-DOS.
+ Unfortunately, though, nanosleep uses ‘select’;
+ problem reported by Lars Ingebrigtsen (Bug#32452#74).
+ As far as I can tell, Gnulib nanosleep's use of
+ ‘select’ with signals is only for ancient platforms
+ that Gnulib no longer cares about, so remove that use of ‘select’.
+ I don’t know of any platforms that still need this fallback code,
+ but just in case, fall back to pselect instead, while removing
+ signal handling that it shouldn’t be needed nowadays.
+ * lib/nanosleep.c: Do not include sig-handler.h, sys/time.h.
+ (SIGCONT, suspended, sighandler, my_usleep): Remove.
+ (nanosleep) [!HAVE_BUG_BIG_NANOSLEEP && !(_WIN32 && !__CYGWIN__)]:
+ Just call pselect.
+ * m4/nanosleep.m4 (gl_FUNC_NANOSLEEP): Do not check for sys/time.h
+ or call gl_FUNC_SELECT. Do not include sys/time.h or worry
+ about LIBSOCKET.
+ (gl_PREREQ_NANOSLEEP): Remove as it’s no longer needed.
+ All uses removed.
+ * modules/nanosleep (Depends-on): Add pselect.
+ Remove select, sigaction, sys_time.
+
2022-02-24 Paul Eggert <eggert@cs.ucla.edu>
userspec: warn about '.' separator
#include <time.h>
#include "intprops.h"
-#include "sig-handler.h"
#include "verify.h"
#include <stdbool.h>
#include <sys/select.h>
#include <signal.h>
-#include <sys/time.h>
#include <errno.h>
#include <unistd.h>
}
#else
-/* Unix platforms lacking nanosleep. */
-
-/* Some systems (MSDOS) don't have SIGCONT.
- Using SIGTERM here turns the signal-handling code below
- into a no-op on such systems. */
-# ifndef SIGCONT
-# define SIGCONT SIGTERM
-# endif
-
-static sig_atomic_t volatile suspended;
-
-/* Handle SIGCONT. */
-
-static _GL_ASYNC_SAFE void
-sighandler (int sig)
-{
- suspended = 1;
-}
-
-/* Suspend execution for at least *TS_DELAY seconds. */
-
-static int
-my_usleep (const struct timespec *ts_delay)
-{
- struct timeval tv_delay;
- tv_delay.tv_sec = ts_delay->tv_sec;
- tv_delay.tv_usec = (ts_delay->tv_nsec + 999) / 1000;
- if (tv_delay.tv_usec == 1000000)
- {
- if (tv_delay.tv_sec == TYPE_MAXIMUM (time_t))
- tv_delay.tv_usec = 1000000 - 1; /* close enough */
- else
- {
- tv_delay.tv_sec++;
- tv_delay.tv_usec = 0;
- }
- }
- return select (0, NULL, NULL, NULL, &tv_delay);
-}
+/* Other platforms lacking nanosleep.
+ It's not clear whether these are still practical porting targets.
+ For now, just fall back on pselect. */
/* Suspend execution for at least *REQUESTED_DELAY seconds. The
*REMAINING_DELAY part isn't implemented yet. */
nanosleep (const struct timespec *requested_delay,
struct timespec *remaining_delay)
{
- static bool initialized;
-
- if (requested_delay->tv_nsec < 0 || BILLION <= requested_delay->tv_nsec)
- {
- errno = EINVAL;
- return -1;
- }
-
- /* set up sig handler */
- if (! initialized)
- {
- struct sigaction oldact;
-
- sigaction (SIGCONT, NULL, &oldact);
- if (get_handler (&oldact) != SIG_IGN)
- {
- struct sigaction newact;
-
- newact.sa_handler = sighandler;
- sigemptyset (&newact.sa_mask);
- newact.sa_flags = 0;
- sigaction (SIGCONT, &newact, NULL);
- }
- initialized = true;
- }
-
- suspended = 0;
-
- if (my_usleep (requested_delay) == -1)
- {
- if (suspended)
- {
- /* Calculate time remaining. */
- /* FIXME: the code in sleep doesn't use this, so there's no
- rush to implement it. */
-
- errno = EINTR;
- }
- return -1;
- }
-
- /* FIXME: Restore sig handler? */
-
- return 0;
+ return pselect (0, NULL, NULL, NULL, requested_delay, NULL);
}
#endif
-# serial 40
+# serial 41
dnl From Jim Meyering.
dnl Check for the nanosleep function.
dnl Persuade glibc and Solaris <time.h> to declare nanosleep.
AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
- AC_CHECK_HEADERS_ONCE([sys/time.h])
- AC_REQUIRE([gl_FUNC_SELECT])
-
AC_CHECK_DECLS_ONCE([alarm])
nanosleep_save_libs=$LIBS
#include <errno.h>
#include <limits.h>
#include <signal.h>
- #if HAVE_SYS_TIME_H
- #include <sys/time.h>
- #endif
#include <time.h>
#include <unistd.h>
#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
AC_DEFINE([HAVE_BUG_BIG_NANOSLEEP], [1],
[Define to 1 if nanosleep mishandles large arguments.])
;;
- *)
- # The replacement uses select(). Add $LIBSOCKET to $LIB_NANOSLEEP.
- for ac_lib in $LIBSOCKET; do
- case " $LIB_NANOSLEEP " in
- *" $ac_lib "*) ;;
- *) LIB_NANOSLEEP="$LIB_NANOSLEEP $ac_lib";;
- esac
- done
- ;;
esac
;;
esac
fi
LIBS=$nanosleep_save_libs
])
-
-# Prerequisites of lib/nanosleep.c.
-AC_DEFUN([gl_PREREQ_NANOSLEEP],
-[
- AC_CHECK_HEADERS_ONCE([sys/select.h])
- gl_PREREQ_SIG_HANDLER_H
-])
extensions
multiarch
intprops [test $HAVE_NANOSLEEP = 0 || test $REPLACE_NANOSLEEP = 1]
-select [test $HAVE_NANOSLEEP = 0 || test $REPLACE_NANOSLEEP = 1]
-sigaction [test $HAVE_NANOSLEEP = 0 || test $REPLACE_NANOSLEEP = 1]
+pselect [test $HAVE_NANOSLEEP = 0 || test $REPLACE_NANOSLEEP = 1]
stdbool [test $HAVE_NANOSLEEP = 0 || test $REPLACE_NANOSLEEP = 1]
sys_select [test $HAVE_NANOSLEEP = 0 || test $REPLACE_NANOSLEEP = 1]
-sys_time [test $HAVE_NANOSLEEP = 0 || test $REPLACE_NANOSLEEP = 1]
verify [test $HAVE_NANOSLEEP = 0 || test $REPLACE_NANOSLEEP = 1]
configure.ac:
gl_FUNC_NANOSLEEP
gl_CONDITIONAL([GL_COND_OBJ_NANOSLEEP],
[test $HAVE_NANOSLEEP = 0 || test $REPLACE_NANOSLEEP = 1])
-AM_COND_IF([GL_COND_OBJ_NANOSLEEP], [
- gl_PREREQ_NANOSLEEP
-])
gl_TIME_MODULE_INDICATOR([nanosleep])
Makefile.am: