summaryrefslogtreecommitdiffstats
path: root/plugins/runcmd.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/runcmd.c')
-rw-r--r--plugins/runcmd.c33
1 files changed, 7 insertions, 26 deletions
diff --git a/plugins/runcmd.c b/plugins/runcmd.c
index 1a7c904..bc0a497 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. */
68static pid_t *np_pids = NULL; 70static 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
75static 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 **/
84static int np_runcmd_open(const char *, int *, int *) 73static 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 */
100void np_runcmd_init(void) 89void 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 }