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 | ||
