From 610b2ee0e31ce3e9ced7ea5e518d516033176734 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Mon, 7 Sep 2020 14:18:14 -0700 Subject: [PATCH] HOST: Implement timeouts on Hurd. The existing implementation didn't work and I do not know why. Hurd isn't documented to have different behavior for signals on execl(). The timeouts were not firing, however. This implementation does work. Thanks to Friedrich Beckmann for reporting the issue (via Debian buildd). --- src/language/utilities/host.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/language/utilities/host.c b/src/language/utilities/host.c index 1ab7cc1d02..6298db2d8b 100644 --- a/src/language/utilities/host.c +++ b/src/language/utilities/host.c @@ -122,6 +122,11 @@ run_command (const char *command, struct timespec timeout) { /* Running in the child. */ +#if __GNU__ + /* Hurd doesn't support inheriting process timers in a way that works. */ + if (setpgid (0, 0) < 0) + error (1, errno, _("Failed to set process group.")); +#else /* Set up timeout. */ if (timeout.tv_sec < TYPE_MAXIMUM (time_t)) { @@ -140,6 +145,7 @@ run_command (const char *command, struct timespec timeout) if (setitimer (ITIMER_REAL, &it, NULL) < 0) error (1, errno, _("Failed to set timeout.")); } +#endif /* Set up file descriptors: - /dev/null for stdin @@ -174,7 +180,15 @@ run_command (const char *command, struct timespec timeout) int error = 0; for (;;) { - pid_t retval = waitpid (pid, &status, 0); +#if __GNU__ + if (timespec_cmp (current_timespec (), timeout) >= 0) + kill (-pid, SIGALRM); + + int flags = WNOHANG; +#else + int flags = 0; +#endif + pid_t retval = waitpid (pid, &status, flags); if (retval == pid) break; else if (retval < 0) @@ -185,6 +199,10 @@ run_command (const char *command, struct timespec timeout) break; } } +#if __GNU__ + else if (retval == 0) + sleep (1); +#endif else NOT_REACHED (); } -- 2.30.2