summaryrefslogtreecommitdiffstats
path: root/plugins/runcmd.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/runcmd.c')
-rw-r--r--plugins/runcmd.c74
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. */
46static pid_t *np_pids = NULL; 48static 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 55static 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
59static 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
71static int np_runcmd_close(int); 70static int np_runcmd_close(int);
72 71
73/* imported from utils.h */ 72/* prototype imported from utils.h */
74extern void die (int, const char *, ...) 73extern 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 */
81void np_runcmd_init(void) 80void 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)
257static int 254static int
258np_fetch_output(int fd, output *op, int flags) 255np_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