summaryrefslogtreecommitdiffstats
path: root/plugins/popen.c
diff options
context:
space:
mode:
authorLorenz Kästle <12514511+RincewindsHat@users.noreply.github.com>2025-09-15 13:18:17 +0200
committerGitHub <noreply@github.com>2025-09-15 13:18:17 +0200
commit8ef825d85fb4d09c32ca44c545d6eb8d995ddea4 (patch)
tree5ab7b18797dfd5849dec7827c87ca3bb5fcb0993 /plugins/popen.c
parenta3cf9041af810770daf5d9b83f1906fa9bb0dd11 (diff)
parent204cf956f0b3db90d079321ee957b3860da7e33f (diff)
downloadmonitoring-plugins-8ef825d85fb4d09c32ca44c545d6eb8d995ddea4.tar.gz
Merge pull request #2149 from RincewindsHat/clang-format
Clang format
Diffstat (limited to 'plugins/popen.c')
-rw-r--r--plugins/popen.c68
1 files changed, 45 insertions, 23 deletions
diff --git a/plugins/popen.c b/plugins/popen.c
index cfe930b6..c596d1e0 100644
--- a/plugins/popen.c
+++ b/plugins/popen.c
@@ -68,7 +68,7 @@ void popen_timeout_alarm_handler(int /*signo*/);
68#endif 68#endif
69 69
70#ifndef WIFEXITED 70#ifndef WIFEXITED
71# define WIFEXITED(stat_val) (((stat_val)&255) == 0) 71# define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
72#endif 72#endif
73 73
74/* 4.3BSD Reno <signal.h> doesn't define SIG_ERR */ 74/* 4.3BSD Reno <signal.h> doesn't define SIG_ERR */
@@ -96,24 +96,28 @@ FILE *spopen(const char *cmdstring) {
96 env[1] = NULL; 96 env[1] = NULL;
97 97
98 /* if no command was passed, return with no error */ 98 /* if no command was passed, return with no error */
99 if (cmdstring == NULL) 99 if (cmdstring == NULL) {
100 return (NULL); 100 return (NULL);
101 }
101 102
102 char *cmd = NULL; 103 char *cmd = NULL;
103 /* make copy of command string so strtok() doesn't silently modify it */ 104 /* make copy of command string so strtok() doesn't silently modify it */
104 /* (the calling program may want to access it later) */ 105 /* (the calling program may want to access it later) */
105 cmd = malloc(strlen(cmdstring) + 1); 106 cmd = malloc(strlen(cmdstring) + 1);
106 if (cmd == NULL) 107 if (cmd == NULL) {
107 return NULL; 108 return NULL;
109 }
108 strcpy(cmd, cmdstring); 110 strcpy(cmd, cmdstring);
109 111
110 /* This is not a shell, so we don't handle "???" */ 112 /* This is not a shell, so we don't handle "???" */
111 if (strstr(cmdstring, "\"")) 113 if (strstr(cmdstring, "\"")) {
112 return NULL; 114 return NULL;
115 }
113 116
114 /* allow single quotes, but only if non-whitesapce doesn't occur on both sides */ 117 /* allow single quotes, but only if non-whitesapce doesn't occur on both sides */
115 if (strstr(cmdstring, " ' ") || strstr(cmdstring, "'''")) 118 if (strstr(cmdstring, " ' ") || strstr(cmdstring, "'''")) {
116 return NULL; 119 return NULL;
120 }
117 121
118 int argc; 122 int argc;
119 char **argv = NULL; 123 char **argv = NULL;
@@ -140,15 +144,17 @@ FILE *spopen(const char *cmdstring) {
140 144
141 if (strstr(str, "'") == str) { /* handle SIMPLE quoted strings */ 145 if (strstr(str, "'") == str) { /* handle SIMPLE quoted strings */
142 str++; 146 str++;
143 if (!strstr(str, "'")) 147 if (!strstr(str, "'")) {
144 return NULL; /* balanced? */ 148 return NULL; /* balanced? */
149 }
145 cmd = 1 + strstr(str, "'"); 150 cmd = 1 + strstr(str, "'");
146 str[strcspn(str, "'")] = 0; 151 str[strcspn(str, "'")] = 0;
147 } else if (strcspn(str, "'") < strcspn(str, " \t\r\n")) { 152 } else if (strcspn(str, "'") < strcspn(str, " \t\r\n")) {
148 /* handle --option='foo bar' strings */ 153 /* handle --option='foo bar' strings */
149 char *tmp = str + strcspn(str, "'") + 1; 154 char *tmp = str + strcspn(str, "'") + 1;
150 if (!strstr(tmp, "'")) 155 if (!strstr(tmp, "'")) {
151 return NULL; /* balanced? */ 156 return NULL; /* balanced? */
157 }
152 tmp += strcspn(tmp, "'") + 1; 158 tmp += strcspn(tmp, "'") + 1;
153 *tmp = 0; 159 *tmp = 0;
154 cmd = tmp + 1; 160 cmd = tmp + 1;
@@ -161,8 +167,9 @@ FILE *spopen(const char *cmdstring) {
161 } 167 }
162 } 168 }
163 169
164 if (cmd && strlen(cmd) == strspn(cmd, " \t\r\n")) 170 if (cmd && strlen(cmd) == strspn(cmd, " \t\r\n")) {
165 cmd = NULL; 171 cmd = NULL;
172 }
166 173
167 argv[i++] = str; 174 argv[i++] = str;
168 } 175 }
@@ -171,22 +178,26 @@ FILE *spopen(const char *cmdstring) {
171 long maxfd = mp_open_max(); 178 long maxfd = mp_open_max();
172 179
173 if (childpid == NULL) { /* first time through */ 180 if (childpid == NULL) { /* first time through */
174 if ((childpid = calloc((size_t)maxfd, sizeof(pid_t))) == NULL) 181 if ((childpid = calloc((size_t)maxfd, sizeof(pid_t))) == NULL) {
175 return (NULL); 182 return (NULL);
183 }
176 } 184 }
177 185
178 if (child_stderr_array == NULL) { /* first time through */ 186 if (child_stderr_array == NULL) { /* first time through */
179 if ((child_stderr_array = calloc((size_t)maxfd, sizeof(int))) == NULL) 187 if ((child_stderr_array = calloc((size_t)maxfd, sizeof(int))) == NULL) {
180 return (NULL); 188 return (NULL);
189 }
181 } 190 }
182 191
183 int pfd[2]; 192 int pfd[2];
184 if (pipe(pfd) < 0) 193 if (pipe(pfd) < 0) {
185 return (NULL); /* errno set by pipe() */ 194 return (NULL); /* errno set by pipe() */
195 }
186 196
187 int pfderr[2]; 197 int pfderr[2];
188 if (pipe(pfderr) < 0) 198 if (pipe(pfderr) < 0) {
189 return (NULL); /* errno set by pipe() */ 199 return (NULL); /* errno set by pipe() */
200 }
190 201
191#ifdef REDHAT_SPOPEN_ERROR 202#ifdef REDHAT_SPOPEN_ERROR
192 if (signal(SIGCHLD, popen_sigchld_handler) == SIG_ERR) { 203 if (signal(SIGCHLD, popen_sigchld_handler) == SIG_ERR) {
@@ -195,8 +206,9 @@ FILE *spopen(const char *cmdstring) {
195#endif 206#endif
196 207
197 pid_t pid; 208 pid_t pid;
198 if ((pid = fork()) < 0) 209 if ((pid = fork()) < 0) {
199 return (NULL); /* errno set by fork() */ 210 return (NULL); /* errno set by fork() */
211 }
200 212
201 if (pid == 0) { /* child */ 213 if (pid == 0) { /* child */
202 close(pfd[0]); 214 close(pfd[0]);
@@ -210,17 +222,20 @@ FILE *spopen(const char *cmdstring) {
210 close(pfderr[1]); 222 close(pfderr[1]);
211 } 223 }
212 /* close all descriptors in childpid[] */ 224 /* close all descriptors in childpid[] */
213 for (i = 0; i < maxfd; i++) 225 for (i = 0; i < maxfd; i++) {
214 if (childpid[i] > 0) 226 if (childpid[i] > 0) {
215 close(i); 227 close(i);
228 }
229 }
216 230
217 execve(argv[0], argv, env); 231 execve(argv[0], argv, env);
218 _exit(0); 232 _exit(0);
219 } 233 }
220 234
221 close(pfd[1]); /* parent */ 235 close(pfd[1]); /* parent */
222 if ((child_process = fdopen(pfd[0], "r")) == NULL) 236 if ((child_process = fdopen(pfd[0], "r")) == NULL) {
223 return (NULL); 237 return (NULL);
238 }
224 close(pfderr[1]); 239 close(pfderr[1]);
225 240
226 childpid[fileno(child_process)] = pid; /* remember child pid for this fd */ 241 childpid[fileno(child_process)] = pid; /* remember child pid for this fd */
@@ -229,17 +244,20 @@ FILE *spopen(const char *cmdstring) {
229} 244}
230 245
231int spclose(FILE *fp) { 246int spclose(FILE *fp) {
232 if (childpid == NULL) 247 if (childpid == NULL) {
233 return (1); /* popen() has never been called */ 248 return (1); /* popen() has never been called */
249 }
234 250
235 pid_t pid; 251 pid_t pid;
236 int fd = fileno(fp); 252 int fd = fileno(fp);
237 if ((pid = childpid[fd]) == 0) 253 if ((pid = childpid[fd]) == 0) {
238 return (1); /* fp wasn't opened by popen() */ 254 return (1); /* fp wasn't opened by popen() */
255 }
239 256
240 childpid[fd] = 0; 257 childpid[fd] = 0;
241 if (fclose(fp) == EOF) 258 if (fclose(fp) == EOF) {
242 return (1); 259 return (1);
260 }
243 261
244#ifdef REDHAT_SPOPEN_ERROR 262#ifdef REDHAT_SPOPEN_ERROR
245 while (!childtermd) 263 while (!childtermd)
@@ -247,20 +265,24 @@ int spclose(FILE *fp) {
247#endif 265#endif
248 266
249 int status; 267 int status;
250 while (waitpid(pid, &status, 0) < 0) 268 while (waitpid(pid, &status, 0) < 0) {
251 if (errno != EINTR) 269 if (errno != EINTR) {
252 return (1); /* error other than EINTR from waitpid() */ 270 return (1); /* error other than EINTR from waitpid() */
271 }
272 }
253 273
254 if (WIFEXITED(status)) 274 if (WIFEXITED(status)) {
255 return (WEXITSTATUS(status)); /* return child's termination status */ 275 return (WEXITSTATUS(status)); /* return child's termination status */
276 }
256 277
257 return (1); 278 return (1);
258} 279}
259 280
260#ifdef REDHAT_SPOPEN_ERROR 281#ifdef REDHAT_SPOPEN_ERROR
261void popen_sigchld_handler(int signo) { 282void popen_sigchld_handler(int signo) {
262 if (signo == SIGCHLD) 283 if (signo == SIGCHLD) {
263 childtermd = 1; 284 childtermd = 1;
285 }
264} 286}
265#endif 287#endif
266 288