diff options
author | Sven Nierlein <sven@nierlein.de> | 2019-02-15 09:36:28 (GMT) |
---|---|---|
committer | Sven Nierlein <sven@nierlein.de> | 2019-02-15 09:36:28 (GMT) |
commit | 7cafb0e84550035fe671662c293122be975065ca (patch) | |
tree | 5d80a8e80854edc41a72da668a89485505d7e5dc /lib/utils_cmd.c | |
parent | 2962148d8bac3a65f1fb5e1a948e3f0a86a42a1a (diff) | |
download | monitoring-plugins-7cafb0e84550035fe671662c293122be975065ca.tar.gz |
check_by_ssh: fix child process leak on timeoutsrefs/pull/1583/head
When check_by_ssh runs into a timeout it simply exits keeping all child processes running.
Simply adopting the kill loop from runcmd_timeout_alarm_handler() fixes this.
Signed-off-by: Sven Nierlein <sven@nierlein.de>
Diffstat (limited to 'lib/utils_cmd.c')
-rw-r--r-- | lib/utils_cmd.c | 42 |
1 files changed, 17 insertions, 25 deletions
diff --git a/lib/utils_cmd.c b/lib/utils_cmd.c index 7eb9a3a..795840d 100644 --- a/lib/utils_cmd.c +++ b/lib/utils_cmd.c | |||
@@ -40,6 +40,7 @@ | |||
40 | 40 | ||
41 | /** includes **/ | 41 | /** includes **/ |
42 | #include "common.h" | 42 | #include "common.h" |
43 | #include "utils.h" | ||
43 | #include "utils_cmd.h" | 44 | #include "utils_cmd.h" |
44 | #include "utils_base.h" | 45 | #include "utils_base.h" |
45 | #include <fcntl.h> | 46 | #include <fcntl.h> |
@@ -65,31 +66,6 @@ extern char **environ; | |||
65 | # define SIG_ERR ((Sigfunc *)-1) | 66 | # define SIG_ERR ((Sigfunc *)-1) |
66 | #endif | 67 | #endif |
67 | 68 | ||
68 | /* This variable must be global, since there's no way the caller | ||
69 | * can forcibly slay a dead or ungainly running program otherwise. | ||
70 | * Multithreading apps and plugins can initialize it (via CMD_INIT) | ||
71 | * in an async safe manner PRIOR to calling cmd_run() or cmd_run_array() | ||
72 | * for the first time. | ||
73 | * | ||
74 | * The check for initialized values is atomic and can | ||
75 | * occur in any number of threads simultaneously. */ | ||
76 | static pid_t *_cmd_pids = NULL; | ||
77 | |||
78 | /* Try sysconf(_SC_OPEN_MAX) first, as it can be higher than OPEN_MAX. | ||
79 | * If that fails and the macro isn't defined, we fall back to an educated | ||
80 | * guess. There's no guarantee that our guess is adequate and the program | ||
81 | * will die with SIGSEGV if it isn't and the upper boundary is breached. */ | ||
82 | #define DEFAULT_MAXFD 256 /* fallback value if no max open files value is set */ | ||
83 | #define MAXFD_LIMIT 8192 /* upper limit of open files */ | ||
84 | #ifdef _SC_OPEN_MAX | ||
85 | static long maxfd = 0; | ||
86 | #elif defined(OPEN_MAX) | ||
87 | # define maxfd OPEN_MAX | ||
88 | #else /* sysconf macro unavailable, so guess (may be wildly inaccurate) */ | ||
89 | # define maxfd DEFAULT_MAXFD | ||
90 | #endif | ||
91 | |||
92 | |||
93 | /** prototypes **/ | 69 | /** prototypes **/ |
94 | static int _cmd_open (char *const *, int *, int *) | 70 | static int _cmd_open (char *const *, int *, int *) |
95 | __attribute__ ((__nonnull__ (1, 2, 3))); | 71 | __attribute__ ((__nonnull__ (1, 2, 3))); |
@@ -406,3 +382,19 @@ cmd_file_read ( char *filename, output *out, int flags) | |||
406 | 382 | ||
407 | return 0; | 383 | return 0; |
408 | } | 384 | } |
385 | |||
386 | void | ||
387 | timeout_alarm_handler (int signo) | ||
388 | { | ||
389 | size_t i; | ||
390 | if (signo == SIGALRM) { | ||
391 | printf (_("%s - Plugin timed out after %d seconds\n"), | ||
392 | state_text(timeout_state), timeout_interval); | ||
393 | |||
394 | if(_cmd_pids) for(i = 0; i < maxfd; i++) { | ||
395 | if(_cmd_pids[i] != 0) kill(_cmd_pids[i], SIGKILL); | ||
396 | } | ||
397 | |||
398 | exit (timeout_state); | ||
399 | } | ||
400 | } | ||