diff options
Diffstat (limited to 'gdb/utils.c')
-rw-r--r-- | gdb/utils.c | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/gdb/utils.c b/gdb/utils.c index cc93915..16405d1 100644 --- a/gdb/utils.c +++ b/gdb/utils.c @@ -24,6 +24,7 @@ #include "gdb_assert.h" #include <ctype.h> #include "gdb_string.h" +#include "gdb_wait.h" #include "event-top.h" #include "exceptions.h" #include "gdbthread.h" @@ -3784,6 +3785,78 @@ producer_is_gcc_ge_4 (const char *producer) return minor; } +#ifdef HAVE_WAITPID + +#ifdef SIGALRM + +/* SIGALRM handler for waitpid_with_timeout. */ + +static void +sigalrm_handler (int signo) +{ + /* Nothing to do. */ +} + +#endif + +/* Wrapper to wait for child PID to die with TIMEOUT. + TIMEOUT is the time to stop waiting in seconds. + If TIMEOUT is zero, pass WNOHANG to waitpid. + Returns PID if it was successfully waited for, otherwise -1. + + Timeouts are currently implemented with alarm and SIGALRM. + If the host does not support them, this waits "forever". + It would be odd though for a host to have waitpid and not SIGALRM. */ + +pid_t +wait_to_die_with_timeout (pid_t pid, int *status, int timeout) +{ + pid_t waitpid_result; + + gdb_assert (pid > 0); + gdb_assert (timeout >= 0); + + if (timeout > 0) + { +#ifdef SIGALRM +#if defined (HAVE_SIGACTION) && defined (SA_RESTART) + struct sigaction sa, old_sa; + + sa.sa_handler = sigalrm_handler; + sigemptyset (&sa.sa_mask); + sa.sa_flags = 0; + sigaction (SIGALRM, &sa, &old_sa); +#else + void (*ofunc) (); + + ofunc = (void (*)()) signal (SIGALRM, sigalrm_handler); +#endif + + alarm (timeout); +#endif + + waitpid_result = waitpid (pid, status, 0); + +#ifdef SIGALRM + alarm (0); +#if defined (HAVE_SIGACTION) && defined (SA_RESTART) + sigaction (SIGALRM, &old_sa, NULL); +#else + signal (SIGALRM, ofunc); +#endif +#endif + } + else + waitpid_result = waitpid (pid, status, WNOHANG); + + if (waitpid_result == pid) + return pid; + else + return -1; +} + +#endif /* HAVE_WAITPID */ + /* Provide a prototype to silence -Wmissing-prototypes. */ extern initialize_file_ftype _initialize_utils; |