summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPádraig Brady <P@draigBrady.com>2011-07-08 14:49:05 +0100
committerPádraig Brady <P@draigBrady.com>2011-07-08 15:11:27 +0100
commit5a647a05e20cb6f91f1aef95b2c83f8ebb03a67c (patch)
tree1765b44cbf5ab02b75730c1abad095b2b0053cde
parent4d90d29899917ec16ea5806a0456501e5e948960 (diff)
downloadcoreutils-5a647a05e20cb6f91f1aef95b2c83f8ebb03a67c.tar.xz
timeout: handle signals more transparently
* m4/jm-macros.m4: Define HAVE_SETRLIMIT. * src/timeout.c: If the child exited with a signal, raise that signal to the timeout process itself, so that callers may also see the signal status. Use setrlimit to disable core dumps for the timeout process, which would be generated by some signals.
-rw-r--r--m4/jm-macros.m42
-rw-r--r--src/timeout.c24
2 files changed, 25 insertions, 1 deletions
diff --git a/m4/jm-macros.m4 b/m4/jm-macros.m4
index ec553105f..9bb6fa425 100644
--- a/m4/jm-macros.m4
+++ b/m4/jm-macros.m4
@@ -65,6 +65,8 @@ AC_DEFUN([coreutils_MACROS],
# Used by sort.c.
AC_CHECK_FUNCS_ONCE([nl_langinfo])
+ # Used by timeout.c
+ AC_CHECK_FUNCS_ONCE([setrlimit])
# Used by tail.c.
AC_CHECK_FUNCS([inotify_init],
diff --git a/src/timeout.c b/src/timeout.c
index ab54ed675..ef660a717 100644
--- a/src/timeout.c
+++ b/src/timeout.c
@@ -58,6 +58,12 @@
#include "error.h"
#include "quote.h"
+#if HAVE_SETRLIMIT
+/* FreeBSD 5.0 at least needs <sys/types.h> and <sys/time.h> included
+ before <sys/resource.h>. Currently "system.h" includes <sys/time.h>. */
+# include <sys/resource.h>
+#endif
+
#define PROGRAM_NAME "timeout"
#define AUTHORS proper_name_utf8 ("Padraig Brady", "P\303\241draig Brady")
@@ -370,7 +376,23 @@ main (int argc, char **argv)
if (WIFEXITED (status))
status = WEXITSTATUS (status);
else if (WIFSIGNALED (status))
- status = WTERMSIG (status) + 128; /* what sh does at least. */
+ {
+ int sig = WTERMSIG (status);
+#if HAVE_SETRLIMIT && defined RLIMIT_CORE
+ if (!timed_out)
+ {
+ /* exit with the signal flag set, but avoid core files. */
+ if (setrlimit (RLIMIT_CORE, &(struct rlimit) {0,0}) == 0)
+ {
+ signal (sig, SIG_DFL);
+ raise (sig);
+ }
+ else
+ error (0, errno, _("warning: disabling core dumps failed"));
+ }
+#endif
+ status = sig + 128; /* what sh returns for signaled processes. */
+ }
else
{
/* shouldn't happen. */