Bug Summary

File:libglusterfs/src/run.c
Location:line 311, column 17
Description:Value stored to 'ret' is never read

Annotated Source Code

1/*
2 Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
3 This file is part of GlusterFS.
4
5 This file is licensed to you under your choice of the GNU Lesser
6 General Public License, version 3 or any later version (LGPLv3 or
7 later), or the GNU General Public License, version 2 (GPLv2), in all
8 cases as published by the Free Software Foundation.
9*/
10
11#ifndef _GNU_SOURCE1
12#define _GNU_SOURCE1
13#endif
14
15#include <stdio.h>
16#include <unistd.h>
17#include <stdlib.h>
18#include <stdarg.h>
19#include <string.h>
20#include <errno(*__errno_location ()).h>
21#include <fcntl.h>
22#include <dirent.h>
23#include <assert.h>
24#include <signal.h>
25#include <sys/wait.h>
26#include <sys/resource.h>
27
28#ifdef RUN_STANDALONE
29#define GF_CALLOC(n, s, t)__gf_calloc (n, s, t) calloc(n, s)
30#define GF_ASSERT(cond)do { if (!(cond)) { do { do { if (0) printf ("Assertion failed: "
"cond"); } while (0); _gf_log_callingfn ("", "run.c", __FUNCTION__
, 30, GF_LOG_ERROR, "Assertion failed: " "cond"); } while (0)
; } } while (0)
assert(cond)((cond) ? (void) (0) : __assert_fail ("cond", "run.c", 30, __PRETTY_FUNCTION__
))
31#define GF_REALLOC(p, s)__gf_realloc (p, s) realloc(p, s)
32#define GF_FREE(p)__gf_free (p) free(p)
33#define gf_strdup(s) strdup(s)
34#define gf_vasprintf(p, f, va) vasprintf(p, f, va)
35#define gf_loglevel_t int
36#define gf_log(dom, levl, fmt, args...)do { do { if (0) printf (fmt, args...); } while (0); _gf_log (
dom, "run.c", __FUNCTION__, 36, levl, fmt, args...); } while (
0)
printf("LOG: " fmt "\n", ##args)
37#define LOG_DEBUG 0
38#ifdef __linux__1
39#define GF_LINUX_HOST_OS1
40#endif
41#else /* ! RUN_STANDALONE */
42#include "glusterfs.h"
43#include "common-utils.h"
44#endif
45
46#include "run.h"
47
48void
49runinit (runner_t *runner)
50{
51 int i = 0;
52
53 runner->argvlen = 64;
54 runner->argv = GF_CALLOC (runner->argvlen,__gf_calloc (runner->argvlen, sizeof (*runner->argv), gf_common_mt_run_argv
)
55 sizeof (*runner->argv),__gf_calloc (runner->argvlen, sizeof (*runner->argv), gf_common_mt_run_argv
)
56 gf_common_mt_run_argv)__gf_calloc (runner->argvlen, sizeof (*runner->argv), gf_common_mt_run_argv
)
;
57 runner->runerr = runner->argv ? 0 : errno(*__errno_location ());
58 runner->chpid = -1;
59 for (i = 0; i < 3; i++) {
60 runner->chfd[i] = -1;
61 runner->chio[i] = NULL((void*)0);
62 }
63}
64
65FILE *
66runner_chio (runner_t *runner, int fd)
67{
68 GF_ASSERT (fd > 0 && fd < 3)do { if (!(fd > 0 && fd < 3)) { do { do { if (0
) printf ("Assertion failed: " "fd > 0 && fd < 3"
); } while (0); _gf_log_callingfn ("", "run.c", __FUNCTION__,
68, GF_LOG_ERROR, "Assertion failed: " "fd > 0 && fd < 3"
); } while (0); } } while (0)
;
69
70 if ((fd > 0) && (fd < 3))
71 return runner->chio[fd];
72
73 return NULL((void*)0);
74}
75
76static void
77runner_insert_arg (runner_t *runner, char *arg)
78{
79 int i = 0;
80
81 GF_ASSERT (arg)do { if (!(arg)) { do { do { if (0) printf ("Assertion failed: "
"arg"); } while (0); _gf_log_callingfn ("", "run.c", __FUNCTION__
, 81, GF_LOG_ERROR, "Assertion failed: " "arg"); } while (0);
} } while (0)
;
82
83 if (runner->runerr)
84 return;
85
86 for (i = 0; i < runner->argvlen; i++) {
87 if (runner->argv[i] == NULL((void*)0))
88 break;
89 }
90 GF_ASSERT (i < runner->argvlen)do { if (!(i < runner->argvlen)) { do { do { if (0) printf
("Assertion failed: " "i < runner->argvlen"); } while (
0); _gf_log_callingfn ("", "run.c", __FUNCTION__, 90, GF_LOG_ERROR
, "Assertion failed: " "i < runner->argvlen"); } while (
0); } } while (0)
;
91
92 if (i == runner->argvlen - 1) {
93 runner->argv = GF_REALLOC (runner->argv,__gf_realloc (runner->argv, runner->argvlen * 2 * sizeof
(*runner->argv))
94 runner->argvlen * 2 * sizeof (*runner->argv))__gf_realloc (runner->argv, runner->argvlen * 2 * sizeof
(*runner->argv))
;
95 if (!runner->argv) {
96 runner->runerr = errno(*__errno_location ());
97 return;
98 }
99 memset (/* "+" is aware of the type of its left side,
100 * no need to multiply with type-size */
101 runner->argv + runner->argvlen,
102 0, runner->argvlen * sizeof (*runner->argv));
103 runner->argvlen *= 2;
104 }
105
106 runner->argv[i] = arg;
107}
108
109void
110runner_add_arg (runner_t *runner, const char *arg)
111{
112 arg = gf_strdup (arg);
113 if (!arg) {
114 runner->runerr = errno(*__errno_location ());
115 return;
116 }
117
118 runner_insert_arg (runner, (char *)arg);
119}
120
121static void
122runner_va_add_args (runner_t *runner, va_list argp)
123{
124 const char *arg;
125
126 while ((arg = va_arg (argp, const char *)__builtin_va_arg(argp, const char *)))
127 runner_add_arg (runner, arg);
128}
129
130void
131runner_add_args (runner_t *runner, ...)
132{
133 va_list argp;
134
135 va_start (argp, runner)__builtin_va_start(argp, runner);
136 runner_va_add_args (runner, argp);
137 va_end (argp)__builtin_va_end(argp);
138}
139
140void
141runner_argprintf (runner_t *runner, const char *format, ...)
142{
143 va_list argva;
144 char *arg = NULL((void*)0);
145 int ret = 0;
146
147 va_start (argva, format)__builtin_va_start(argva, format);
148 ret = gf_vasprintf (&arg, format, argva);
149 va_end (argva)__builtin_va_end(argva);
150
151 if (ret < 0) {
152 runner->runerr = errno(*__errno_location ());
153 return;
154 }
155
156 runner_insert_arg (runner, arg);
157}
158
159void
160runner_log (runner_t *runner, const char *dom, gf_loglevel_t lvl,
161 const char *msg)
162{
163 char *buf = NULL((void*)0);
164 size_t len = 0;
165 int i = 0;
166
167 if (runner->runerr)
168 return;
169
170 for (i = 0;; i++) {
171 if (runner->argv[i] == NULL((void*)0))
172 break;
173 len += (strlen (runner->argv[i]) + 1);
174 }
175
176 buf = GF_CALLOC (1, len + 1, gf_common_mt_run_logbuf)__gf_calloc (1, len + 1, gf_common_mt_run_logbuf);
177 if (!buf) {
178 runner->runerr = errno(*__errno_location ());
179 return;
180 }
181 for (i = 0;; i++) {
182 if (runner->argv[i] == NULL((void*)0))
183 break;
184 strcat (buf, runner->argv[i]);
185 strcat (buf, " ");
186 }
187 if (len > 0)
188 buf[len - 1] = '\0';
189
190 gf_log (dom, lvl, "%s: %s", msg, buf)do { do { if (0) printf ("%s: %s", msg, buf); } while (0); _gf_log
(dom, "run.c", __FUNCTION__, 190, lvl, "%s: %s", msg, buf); }
while (0)
;
191
192 GF_FREE (buf)__gf_free (buf);
193}
194
195void
196runner_redir (runner_t *runner, int fd, int tgt_fd)
197{
198 GF_ASSERT (fd > 0 && fd < 3)do { if (!(fd > 0 && fd < 3)) { do { do { if (0
) printf ("Assertion failed: " "fd > 0 && fd < 3"
); } while (0); _gf_log_callingfn ("", "run.c", __FUNCTION__,
198, GF_LOG_ERROR, "Assertion failed: " "fd > 0 && fd < 3"
); } while (0); } } while (0)
;
199
200 if ((fd > 0) && (fd < 3))
201 runner->chfd[fd] = (tgt_fd >= 0) ? tgt_fd : -2;
202}
203
204int
205runner_start (runner_t *runner)
206{
207 int pi[3][2] = {{-1, -1}, {-1, -1}, {-1, -1}};
208 int xpi[2];
209 int ret = 0;
210 int errno_priv = 0;
211 int i = 0;
212 sigset_t set;
213
214 if (runner->runerr) {
215 errno(*__errno_location ()) = runner->runerr;
216 return -1;
217 }
218
219 GF_ASSERT (runner->argv[0])do { if (!(runner->argv[0])) { do { do { if (0) printf ("Assertion failed: "
"runner->argv[0]"); } while (0); _gf_log_callingfn ("", "run.c"
, __FUNCTION__, 219, GF_LOG_ERROR, "Assertion failed: " "runner->argv[0]"
); } while (0); } } while (0)
;
220
221 /* set up a channel to child to communicate back
222 * possible execve(2) failures
223 */
224 ret = pipe(xpi);
225 if (ret != -1)
226 ret = fcntl (xpi[1], F_SETFD2, FD_CLOEXEC1);
227
228 for (i = 0; i < 3; i++) {
229 if (runner->chfd[i] != -2)
230 continue;
231 ret = pipe (pi[i]);
232 if (ret != -1) {
233 runner->chio[i] = fdopen (pi[i][i ? 0 : 1], i ? "r" : "w");
234 if (!runner->chio[i])
235 ret = -1;
236 }
237 }
238
239 if (ret != -1)
240 runner->chpid = fork ();
241 switch (runner->chpid) {
242 case -1:
243 errno_priv = errno(*__errno_location ());
244 close (xpi[0]);
245 close (xpi[1]);
246 for (i = 0; i < 3; i++) {
247 close (pi[i][0]);
248 close (pi[i][1]);
249 }
250 errno(*__errno_location ()) = errno_priv;
251 return -1;
252 case 0:
253 for (i = 0; i < 3; i++)
254 close (pi[i][i ? 0 : 1]);
255 close (xpi[0]);
256 ret = 0;
257
258 for (i = 0; i < 3; i++) {
259 if (ret == -1)
260 break;
261 switch (runner->chfd[i]) {
262 case -1:
263 /* no redir */
264 break;
265 case -2:
266 /* redir to pipe */
267 ret = dup2 (pi[i][i ? 1 : 0], i);
268 break;
269 default:
270 /* redir to file */
271 ret = dup2 (runner->chfd[i], i);
272 }
273 }
274
275 if (ret != -1 ) {
276#ifdef GF_LINUX_HOST_OS1
277 DIR *d = NULL((void*)0);
278 struct dirent *de = NULL((void*)0);
279 char *e = NULL((void*)0);
280
281 d = opendir ("/proc/self/fd");
282 if (d) {
283 while ((de = readdir (d))) {
284 i = strtoul (de->d_name, &e, 10);
285 if (*e == '\0' && i > 2 &&
286 i != dirfd (d) && i != xpi[1])
287 close (i);
288 }
289 closedir (d);
290 } else
291 ret = -1;
292#else
293 struct rlimit rl;
294 ret = getrlimit (RLIMIT_NOFILERLIMIT_NOFILE, &rl);
295 GF_ASSERT (ret == 0)do { if (!(ret == 0)) { do { do { if (0) printf ("Assertion failed: "
"ret == 0"); } while (0); _gf_log_callingfn ("", "run.c", __FUNCTION__
, 295, GF_LOG_ERROR, "Assertion failed: " "ret == 0"); } while
(0); } } while (0)
;
296
297 for (i = 3; i < rl.rlim_cur; i++) {
298 if (i != xpi[1])
299 close (i);
300 }
301#endif
302 }
303
304 if (ret != -1) {
305 /* save child from inheriting our singal handling */
306 sigemptyset (&set);
307 sigprocmask (SIG_SETMASK2, &set, NULL((void*)0));
308
309 execvp (runner->argv[0], runner->argv);
310 }
311 ret = write (xpi[1], &errno(*__errno_location ()), sizeof (errno(*__errno_location ())));
Value stored to 'ret' is never read
312 _exit (1);
313 }
314
315 errno_priv = errno(*__errno_location ());
316 for (i = 0; i < 3; i++)
317 close (pi[i][i ? 1 : 0]);
318 close (xpi[1]);
319 if (ret == -1) {
320 for (i = 0; i < 3; i++) {
321 if (runner->chio[i]) {
322 fclose (runner->chio[i]);
323 runner->chio[i] = NULL((void*)0);
324 }
325 }
326 } else {
327 ret = read (xpi[0], (char *)&errno_priv, sizeof (errno_priv));
328 close (xpi[0]);
329 if (ret <= 0)
330 return 0;
331 GF_ASSERT (ret == sizeof (errno_priv))do { if (!(ret == sizeof (errno_priv))) { do { do { if (0) printf
("Assertion failed: " "ret == sizeof (errno_priv)"); } while
(0); _gf_log_callingfn ("", "run.c", __FUNCTION__, 331, GF_LOG_ERROR
, "Assertion failed: " "ret == sizeof (errno_priv)"); } while
(0); } } while (0)
;
332 }
333 errno(*__errno_location ()) = errno_priv;
334 return -1;
335}
336
337int
338runner_end_reuse (runner_t *runner)
339{
340 int i = 0;
341 int ret = -1;
342 int chstat = 0;
343
344 if (runner->chpid > 0) {
345 if (waitpid (runner->chpid, &chstat, 0) == runner->chpid)
346 ret = chstat;
347 }
348
349 for (i = 0; i < 3; i++) {
350 if (runner->chio[i]) {
351 fclose (runner->chio[i]);
352 runner->chio[i] = NULL((void*)0);
353 }
354 }
355
356 return ret;
357}
358
359int
360runner_end (runner_t *runner)
361{
362 int i = 0;
363 int ret = -1;
364 char **p = NULL((void*)0);
365
366 ret = runner_end_reuse (runner);
367
368 if (runner->argv) {
369 for (p = runner->argv; *p; p++)
370 GF_FREE (*p)__gf_free (*p);
371 GF_FREE (runner->argv)__gf_free (runner->argv);
372 }
373 for (i = 0; i < 3; i++)
374 close (runner->chfd[i]);
375
376 return ret;
377}
378
379static int
380runner_run_generic (runner_t *runner, int (*rfin)(runner_t *runner))
381{
382 int ret = 0;
383
384 ret = runner_start (runner);
385
386 return -(rfin (runner) || ret);
387}
388
389int
390runner_run (runner_t *runner)
391{
392 return runner_run_generic (runner, runner_end);
393}
394
395
396int
397runner_run_nowait (runner_t *runner)
398{
399 int pid;
400
401 pid = fork ();
402
403 if (!pid) {
404 setsid ();
405 _exit (runner_start (runner));
406 }
407
408 if (pid > 0)
409 runner->chpid = pid;
410 return runner_end (runner);
411}
412
413
414int
415runner_run_reuse (runner_t *runner)
416{
417 return runner_run_generic (runner, runner_end_reuse);
418}
419
420int
421runcmd (const char *arg, ...)
422{
423 runner_t runner;
424 va_list argp;
425
426 runinit (&runner);
427 /* ISO C requires a named argument before '...' */
428 runner_add_arg (&runner, arg);
429
430 va_start (argp, arg)__builtin_va_start(argp, arg);
431 runner_va_add_args (&runner, argp);
432 va_end (argp)__builtin_va_end(argp);
433
434 return runner_run (&runner);
435}
436
437#ifdef RUN_DO_TESTS
438static void
439TBANNER (const char *txt)
440{
441 printf("######\n### testing %s\n", txt);
442}
443
444int
445main (int argc, char **argv)
446{
447 runner_t runner;
448 char buf[80];
449 char *wdbuf;;
450 int ret;
451 int fd;
452 long pathmax = pathconf ("/", _PC_PATH_MAX_PC_PATH_MAX);
453 struct timeval tv = {0,};
454 struct timeval *tvp = NULL((void*)0);
455
456 wdbuf = malloc (pathmax);
457 assert (wdbuf)((wdbuf) ? (void) (0) : __assert_fail ("wdbuf", "run.c", 457,
__PRETTY_FUNCTION__))
;
458 getcwd (wdbuf, pathmax);
459
460 TBANNER ("basic functionality");
461 runcmd ("echo", "a", "b", NULL((void*)0));
462
463 TBANNER ("argv extension");
464 runcmd ("echo", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
465 "11", "12", "13", "14", "15", "16", "17", "18", "19", "20",
466 "21", "22", "23", "24", "25", "26", "27", "28", "29", "30",
467 "31", "32", "33", "34", "35", "36", "37", "38", "39", "40",
468 "41", "42", "43", "44", "45", "46", "47", "48", "49", "50",
469 "51", "52", "53", "54", "55", "56", "57", "58", "59", "60",
470 "61", "62", "63", "64", "65", "66", "67", "68", "69", "70",
471 "71", "72", "73", "74", "75", "76", "77", "78", "79", "80",
472 "81", "82", "83", "84", "85", "86", "87", "88", "89", "90",
473 "91", "92", "93", "94", "95", "96", "97", "98", "99", "100", NULL((void*)0));
474
475 TBANNER ("add_args, argprintf, log, and popen-style functionality");
476 runinit (&runner);
477 runner_add_args (&runner, "echo", "pid:", NULL((void*)0));
478 runner_argprintf (&runner, "%d\n", getpid());
479 runner_add_arg (&runner, "wd:");
480 runner_add_arg (&runner, wdbuf);
481 runner_redir (&runner, 1, RUN_PIPE-1);
482 runner_start (&runner);
483 runner_log (&runner, "(x)", LOG_DEBUG, "starting program");
484 while (fgets (buf, sizeof(buf), runner_chio (&runner, 1)))
485 printf ("got: %s", buf);
486 runner_end (&runner);
487
488 TBANNER ("execve error reporting");
489 ret = runcmd ("bafflavvitty", NULL((void*)0));
490 printf ("%d %d [%s]\n", ret, errno(*__errno_location ()), strerror (errno(*__errno_location ())));
491
492 TBANNER ("output redirection");
493 fd = mkstemp ("/tmp/foof");
494 assert (fd != -1)((fd != -1) ? (void) (0) : __assert_fail ("fd != -1", "run.c"
, 494, __PRETTY_FUNCTION__))
;
495 runinit (&runner);
496 runner_add_args (&runner, "echo", "foo", NULL((void*)0));
497 runner_redir (&runner, 1, fd);
498 ret = runner_run (&runner);
499 printf ("%d", ret);
500 if (ret != 0)
501 printf (" %d [%s]", errno(*__errno_location ()), strerror (errno(*__errno_location ())));
502 putchar ('\n');
503
504 if (argc > 1) {
505 tv.tv_sec = strtoul (argv[1], NULL((void*)0), 10);
506 if (tv.tv_sec > 0)
507 tvp = &tv;
508 select (0, 0, 0, 0, tvp);
509 }
510
511 return 0;
512}
513#endif