diff options
Diffstat (limited to 'plugins/runcmd.c')
-rw-r--r-- | plugins/runcmd.c | 74 |
1 files changed, 37 insertions, 37 deletions
diff --git a/plugins/runcmd.c b/plugins/runcmd.c index 14300ee5..4155796c 100644 --- a/plugins/runcmd.c +++ b/plugins/runcmd.c | |||
@@ -16,6 +16,8 @@ | |||
16 | * | 16 | * |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #define NAGIOSPLUG_API_C 1 | ||
20 | |||
19 | /** includes **/ | 21 | /** includes **/ |
20 | #include "runcmd.h" | 22 | #include "runcmd.h" |
21 | #ifdef HAVE_SYS_WAIT_H | 23 | #ifdef HAVE_SYS_WAIT_H |
@@ -45,20 +47,17 @@ | |||
45 | * occur in any number of threads simultaneously. */ | 47 | * occur in any number of threads simultaneously. */ |
46 | static pid_t *np_pids = NULL; | 48 | static pid_t *np_pids = NULL; |
47 | 49 | ||
48 | /* If OPEN_MAX isn't defined, we try the sysconf syscall first. | 50 | /* Try sysconf(_SC_OPEN_MAX) first, as it can be higher than OPEN_MAX. |
49 | * If that fails, we fall back to an educated guess which is accurate | 51 | * If that fails and the macro isn't defined, we fall back to an educated |
50 | * on Linux and some other systems. There's no guarantee that our guess is | 52 | * guess. There's no guarantee that our guess is adequate and the program |
51 | * adequate and the program will die with SIGSEGV if it isn't and the | 53 | * will die with SIGSEGV if it isn't and the upper boundary is breached. */ |
52 | * upper boundary is breached. */ | 54 | #ifdef _SC_OPEN_MAX |
53 | #ifdef OPEN_MAX | 55 | static long maxfd = 0; |
56 | #elif defined(OPEN_MAX) | ||
54 | # define maxfd OPEN_MAX | 57 | # define maxfd OPEN_MAX |
55 | #else | 58 | #else /* sysconf macro unavailable, so guess (may be wildly inaccurate) */ |
56 | # ifndef _SC_OPEN_MAX /* sysconf macro unavailable, so guess */ | 59 | # define maxfd 256 |
57 | # define maxfd 256 | 60 | #endif |
58 | # else | ||
59 | static int maxfd = 0; | ||
60 | # endif /* _SC_OPEN_MAX */ | ||
61 | #endif /* OPEN_MAX */ | ||
62 | 61 | ||
63 | 62 | ||
64 | /** prototypes **/ | 63 | /** prototypes **/ |
@@ -70,7 +69,7 @@ static int np_fetch_output(int, output *, int) | |||
70 | 69 | ||
71 | static int np_runcmd_close(int); | 70 | static int np_runcmd_close(int); |
72 | 71 | ||
73 | /* imported from utils.h */ | 72 | /* prototype imported from utils.h */ |
74 | extern void die (int, const char *, ...) | 73 | extern void die (int, const char *, ...) |
75 | __attribute__((__noreturn__,__format__(__printf__, 2, 3))); | 74 | __attribute__((__noreturn__,__format__(__printf__, 2, 3))); |
76 | 75 | ||
@@ -80,13 +79,11 @@ extern void die (int, const char *, ...) | |||
80 | * through this api and thus achieve async-safeness throughout the api */ | 79 | * through this api and thus achieve async-safeness throughout the api */ |
81 | void np_runcmd_init(void) | 80 | void np_runcmd_init(void) |
82 | { | 81 | { |
83 | #if !defined(OPEN_MAX) && defined(_SC_OPEN_MAX) | 82 | #ifndef maxfd |
84 | if(!maxfd) { | 83 | if(!maxfd && (maxfd = sysconf(_SC_OPEN_MAX)) < 0) { |
85 | if((maxfd = sysconf(_SC_OPEN_MAX)) < 0) { | 84 | /* possibly log or emit a warning here, since there's no |
86 | /* possibly log or emit a warning here, since there's no | 85 | * guarantee that our guess at maxfd will be adequate */ |
87 | * guarantee that our guess at maxfd will be adequate */ | 86 | maxfd = 256; |
88 | maxfd = 256; | ||
89 | } | ||
90 | } | 87 | } |
91 | #endif | 88 | #endif |
92 | 89 | ||
@@ -123,9 +120,9 @@ np_runcmd_open(const char *cmdstring, int *pfd, int *pfderr) | |||
123 | /* make copy of command string so strtok() doesn't silently modify it */ | 120 | /* make copy of command string so strtok() doesn't silently modify it */ |
124 | /* (the calling program may want to access it later) */ | 121 | /* (the calling program may want to access it later) */ |
125 | cmdlen = strlen(cmdstring); | 122 | cmdlen = strlen(cmdstring); |
126 | cmd = malloc(cmdlen + 1); | 123 | if((cmd = malloc(cmdlen + 1)) == NULL) return -1; |
127 | if (cmd == NULL) return -1; | ||
128 | memcpy(cmd, cmdstring, cmdlen); | 124 | memcpy(cmd, cmdstring, cmdlen); |
125 | cmd[cmdlen] = '\0'; | ||
129 | 126 | ||
130 | /* This is not a shell, so we don't handle "???" */ | 127 | /* This is not a shell, so we don't handle "???" */ |
131 | if (strstr (cmdstring, "\"")) return -1; | 128 | if (strstr (cmdstring, "\"")) return -1; |
@@ -257,7 +254,7 @@ popen_timeout_alarm_handler (int signo) | |||
257 | static int | 254 | static int |
258 | np_fetch_output(int fd, output *op, int flags) | 255 | np_fetch_output(int fd, output *op, int flags) |
259 | { | 256 | { |
260 | size_t len = 0, i = 0; | 257 | size_t len = 0, i = 0, lineno = 0; |
261 | size_t rsf = 6, ary_size = 0; /* rsf = right shift factor, dec'ed uncond once */ | 258 | size_t rsf = 6, ary_size = 0; /* rsf = right shift factor, dec'ed uncond once */ |
262 | char *buf = NULL; | 259 | char *buf = NULL; |
263 | int ret; | 260 | int ret; |
@@ -278,13 +275,12 @@ np_fetch_output(int fd, output *op, int flags) | |||
278 | return ret; | 275 | return ret; |
279 | } | 276 | } |
280 | 277 | ||
281 | if(!op->buf || !op->buflen) return 0; | 278 | /* some plugins may want to keep output unbroken, and some commands |
282 | 279 | * will yield no output, so return here for those */ | |
283 | /* some plugins may want to keep output unbroken */ | 280 | if(flags & RUNCMD_NO_ARRAYS || !op->buf || !op->buflen) |
284 | if(flags & RUNCMD_NO_ARRAYS) | ||
285 | return op->buflen; | 281 | return op->buflen; |
286 | 282 | ||
287 | /* and some may want both (*sigh*) */ | 283 | /* and some may want both */ |
288 | if(flags & RUNCMD_NO_ASSOC) { | 284 | if(flags & RUNCMD_NO_ASSOC) { |
289 | buf = malloc(op->buflen); | 285 | buf = malloc(op->buflen); |
290 | memcpy(buf, op->buf, op->buflen); | 286 | memcpy(buf, op->buf, op->buflen); |
@@ -293,30 +289,34 @@ np_fetch_output(int fd, output *op, int flags) | |||
293 | 289 | ||
294 | op->line = NULL; | 290 | op->line = NULL; |
295 | op->lens = NULL; | 291 | op->lens = NULL; |
296 | len = i = 0; | 292 | i = 0; |
297 | while(i < op->buflen) { | 293 | while(i < op->buflen) { |
298 | /* make sure we have enough memory */ | 294 | /* make sure we have enough memory */ |
299 | if(len >= ary_size) { | 295 | if(lineno >= ary_size) { |
300 | ary_size = op->buflen >> --rsf; | 296 | /* ary_size must never be zero */ |
297 | do { | ||
298 | ary_size = op->buflen >> --rsf; | ||
299 | } while(!ary_size); | ||
300 | |||
301 | op->line = realloc(op->line, ary_size * sizeof(char *)); | 301 | op->line = realloc(op->line, ary_size * sizeof(char *)); |
302 | op->lens = realloc(op->lens, ary_size * sizeof(size_t)); | 302 | op->lens = realloc(op->lens, ary_size * sizeof(size_t)); |
303 | } | 303 | } |
304 | 304 | ||
305 | /* set the pointer to the string */ | 305 | /* set the pointer to the string */ |
306 | op->line[len] = &buf[i]; | 306 | op->line[lineno] = &buf[i]; |
307 | 307 | ||
308 | /* hop to next newline or end of buffer */ | 308 | /* hop to next newline or end of buffer */ |
309 | while(buf[i] != '\n' && i < op->buflen) i++; | 309 | while(buf[i] != '\n' && i < op->buflen) i++; |
310 | buf[i] = '\0'; | 310 | buf[i] = '\0'; |
311 | 311 | ||
312 | /* calculate the string length using pointer difference */ | 312 | /* calculate the string length using pointer difference */ |
313 | op->lens[len] = (size_t)&buf[i] - (size_t)op->line[len]; | 313 | op->lens[lineno] = (size_t)&buf[i] - (size_t)op->line[lineno]; |
314 | 314 | ||
315 | len++; | 315 | lineno++; |
316 | i++; | 316 | i++; |
317 | } | 317 | } |
318 | 318 | ||
319 | return len; | 319 | return lineno; |
320 | } | 320 | } |
321 | 321 | ||
322 | 322 | ||