diff options
Diffstat (limited to 'lib/utils_cmd.c')
-rw-r--r-- | lib/utils_cmd.c | 50 |
1 files changed, 26 insertions, 24 deletions
diff --git a/lib/utils_cmd.c b/lib/utils_cmd.c index 9e214bd4..795840d3 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,29 +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 | #ifdef _SC_OPEN_MAX | ||
83 | static long maxfd = 0; | ||
84 | #elif defined(OPEN_MAX) | ||
85 | # define maxfd OPEN_MAX | ||
86 | #else /* sysconf macro unavailable, so guess (may be wildly inaccurate) */ | ||
87 | # define maxfd 256 | ||
88 | #endif | ||
89 | |||
90 | |||
91 | /** prototypes **/ | 69 | /** prototypes **/ |
92 | static int _cmd_open (char *const *, int *, int *) | 70 | static int _cmd_open (char *const *, int *, int *) |
93 | __attribute__ ((__nonnull__ (1, 2, 3))); | 71 | __attribute__ ((__nonnull__ (1, 2, 3))); |
@@ -112,10 +90,18 @@ cmd_init (void) | |||
112 | if (!maxfd && (maxfd = sysconf (_SC_OPEN_MAX)) < 0) { | 90 | if (!maxfd && (maxfd = sysconf (_SC_OPEN_MAX)) < 0) { |
113 | /* possibly log or emit a warning here, since there's no | 91 | /* possibly log or emit a warning here, since there's no |
114 | * guarantee that our guess at maxfd will be adequate */ | 92 | * guarantee that our guess at maxfd will be adequate */ |
115 | maxfd = 256; | 93 | maxfd = DEFAULT_MAXFD; |
116 | } | 94 | } |
117 | #endif | 95 | #endif |
118 | 96 | ||
97 | /* if maxfd is unnaturally high, we force it to a lower value | ||
98 | * ( e.g. on SunOS, when ulimit is set to unlimited: 2147483647 this would cause | ||
99 | * a segfault when following calloc is called ... ) */ | ||
100 | |||
101 | if ( maxfd > MAXFD_LIMIT ) { | ||
102 | maxfd = MAXFD_LIMIT; | ||
103 | } | ||
104 | |||
119 | if (!_cmd_pids) | 105 | if (!_cmd_pids) |
120 | _cmd_pids = calloc (maxfd, sizeof (pid_t)); | 106 | _cmd_pids = calloc (maxfd, sizeof (pid_t)); |
121 | } | 107 | } |
@@ -396,3 +382,19 @@ cmd_file_read ( char *filename, output *out, int flags) | |||
396 | 382 | ||
397 | return 0; | 383 | return 0; |
398 | } | 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 | } | ||