diff options
Diffstat (limited to 'plugins/runcmd.c')
| -rw-r--r-- | plugins/runcmd.c | 33 |
1 files changed, 7 insertions, 26 deletions
diff --git a/plugins/runcmd.c b/plugins/runcmd.c index 1a7c904f..bc0a4974 100644 --- a/plugins/runcmd.c +++ b/plugins/runcmd.c | |||
| @@ -44,6 +44,8 @@ | |||
| 44 | # include <sys/wait.h> | 44 | # include <sys/wait.h> |
| 45 | #endif | 45 | #endif |
| 46 | 46 | ||
| 47 | #include "./utils.h" | ||
| 48 | |||
| 47 | /** macros **/ | 49 | /** macros **/ |
| 48 | #ifndef WEXITSTATUS | 50 | #ifndef WEXITSTATUS |
| 49 | # define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8) | 51 | # define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8) |
| @@ -67,19 +69,6 @@ | |||
| 67 | * occur in any number of threads simultaneously. */ | 69 | * occur in any number of threads simultaneously. */ |
| 68 | static pid_t *np_pids = NULL; | 70 | static pid_t *np_pids = NULL; |
| 69 | 71 | ||
| 70 | /* Try sysconf(_SC_OPEN_MAX) first, as it can be higher than OPEN_MAX. | ||
| 71 | * If that fails and the macro isn't defined, we fall back to an educated | ||
| 72 | * guess. There's no guarantee that our guess is adequate and the program | ||
| 73 | * will die with SIGSEGV if it isn't and the upper boundary is breached. */ | ||
| 74 | #ifdef _SC_OPEN_MAX | ||
| 75 | static long maxfd = 0; | ||
| 76 | #elif defined(OPEN_MAX) | ||
| 77 | # define maxfd OPEN_MAX | ||
| 78 | #else /* sysconf macro unavailable, so guess (may be wildly inaccurate) */ | ||
| 79 | # define maxfd 256 | ||
| 80 | #endif | ||
| 81 | |||
| 82 | |||
| 83 | /** prototypes **/ | 72 | /** prototypes **/ |
| 84 | static int np_runcmd_open(const char *, int *, int *) | 73 | static int np_runcmd_open(const char *, int *, int *) |
| 85 | __attribute__((__nonnull__(1, 2, 3))); | 74 | __attribute__((__nonnull__(1, 2, 3))); |
| @@ -99,14 +88,7 @@ extern void die (int, const char *, ...) | |||
| 99 | * through this api and thus achieve async-safeness throughout the api */ | 88 | * through this api and thus achieve async-safeness throughout the api */ |
| 100 | void np_runcmd_init(void) | 89 | void np_runcmd_init(void) |
| 101 | { | 90 | { |
| 102 | #ifndef maxfd | 91 | long maxfd = mp_open_max(); |
| 103 | if(!maxfd && (maxfd = sysconf(_SC_OPEN_MAX)) < 0) { | ||
| 104 | /* possibly log or emit a warning here, since there's no | ||
| 105 | * guarantee that our guess at maxfd will be adequate */ | ||
| 106 | maxfd = 256; | ||
| 107 | } | ||
| 108 | #endif | ||
| 109 | |||
| 110 | if(!np_pids) np_pids = calloc(maxfd, sizeof(pid_t)); | 92 | if(!np_pids) np_pids = calloc(maxfd, sizeof(pid_t)); |
| 111 | } | 93 | } |
| 112 | 94 | ||
| @@ -133,10 +115,6 @@ np_runcmd_open(const char *cmdstring, int *pfd, int *pfderr) | |||
| 133 | env[0] = strdup("LC_ALL=C"); | 115 | env[0] = strdup("LC_ALL=C"); |
| 134 | env[1] = '\0'; | 116 | env[1] = '\0'; |
| 135 | 117 | ||
| 136 | /* if no command was passed, return with no error */ | ||
| 137 | if (cmdstring == NULL) | ||
| 138 | return -1; | ||
| 139 | |||
| 140 | /* make copy of command string so strtok() doesn't silently modify it */ | 118 | /* make copy of command string so strtok() doesn't silently modify it */ |
| 141 | /* (the calling program may want to access it later) */ | 119 | /* (the calling program may want to access it later) */ |
| 142 | cmdlen = strlen(cmdstring); | 120 | cmdlen = strlen(cmdstring); |
| @@ -213,6 +191,7 @@ np_runcmd_open(const char *cmdstring, int *pfd, int *pfderr) | |||
| 213 | /* close all descriptors in np_pids[] | 191 | /* close all descriptors in np_pids[] |
| 214 | * This is executed in a separate address space (pure child), | 192 | * This is executed in a separate address space (pure child), |
| 215 | * so we don't have to worry about async safety */ | 193 | * so we don't have to worry about async safety */ |
| 194 | long maxfd = mp_open_max(); | ||
| 216 | for (i = 0; i < maxfd; i++) | 195 | for (i = 0; i < maxfd; i++) |
| 217 | if(np_pids[i] > 0) | 196 | if(np_pids[i] > 0) |
| 218 | close (i); | 197 | close (i); |
| @@ -222,7 +201,7 @@ np_runcmd_open(const char *cmdstring, int *pfd, int *pfderr) | |||
| 222 | } | 201 | } |
| 223 | 202 | ||
| 224 | /* parent picks up execution here */ | 203 | /* parent picks up execution here */ |
| 225 | /* close childs descriptors in our address space */ | 204 | /* close children descriptors in our address space */ |
| 226 | close(pfd[1]); | 205 | close(pfd[1]); |
| 227 | close(pfderr[1]); | 206 | close(pfderr[1]); |
| 228 | 207 | ||
| @@ -240,6 +219,7 @@ np_runcmd_close(int fd) | |||
| 240 | pid_t pid; | 219 | pid_t pid; |
| 241 | 220 | ||
| 242 | /* make sure this fd was opened by popen() */ | 221 | /* make sure this fd was opened by popen() */ |
| 222 | long maxfd = mp_open_max(); | ||
| 243 | if(fd < 0 || fd > maxfd || !np_pids || (pid = np_pids[fd]) == 0) | 223 | if(fd < 0 || fd > maxfd || !np_pids || (pid = np_pids[fd]) == 0) |
| 244 | return -1; | 224 | return -1; |
| 245 | 225 | ||
| @@ -263,6 +243,7 @@ runcmd_timeout_alarm_handler (int signo) | |||
| 263 | if (signo == SIGALRM) | 243 | if (signo == SIGALRM) |
| 264 | puts(_("CRITICAL - Plugin timed out while executing system call")); | 244 | puts(_("CRITICAL - Plugin timed out while executing system call")); |
| 265 | 245 | ||
| 246 | long maxfd = mp_open_max(); | ||
| 266 | if(np_pids) for(i = 0; i < maxfd; i++) { | 247 | if(np_pids) for(i = 0; i < maxfd; i++) { |
| 267 | if(np_pids[i] != 0) kill(np_pids[i], SIGKILL); | 248 | if(np_pids[i] != 0) kill(np_pids[i], SIGKILL); |
| 268 | } | 249 | } |
