2 Bacula(R) - The Network Backup Solution
4 Copyright (C) 2000-2017 Kern Sibbald
6 The original author of Bacula is Kern Sibbald, with contributions
7 from many others, a complete list can be found in the file AUTHORS.
9 You may use this file and others of this release according to the
10 license defined in the LICENSE file, which includes the Affero General
11 Public License, v3.0 ("AGPLv3") and some additional permissions and
12 terms pursuant to its AGPLv3 Section 7.
14 This notice must be preserved when any source code is
15 conveyed and/or propagated.
17 Bacula(R) is a registered trademark of Kern Sibbald.
20 * bpipe.c bi-directional pipe
22 * Kern Sibbald, November MMII
29 #include <sys/resource.h>
31 int execvp_errors[] = {
44 int num_execvp_errors = (int)(sizeof(execvp_errors)/sizeof(int));
49 #if !defined(HAVE_WIN32)
50 static void build_argc_argv(char *cmd, int *bargc, char *bargv[], int max_arg);
52 void build_sh_argc_argv(char *cmd, int *bargc, char *bargv[], int max_arg)
54 bargv[0] = (char *)"/bin/sh";
55 bargv[1] = (char *)"-c";
62 * Run an external program. Optionally wait a specified number
63 * of seconds. Program killed if wait exceeded. We open
64 * a bi-directional pipe so that the user can read from and
65 * write to the program.
67 BPIPE *open_bpipe(char *prog, int wait, const char *mode, char *envp[])
69 char *bargv[MAX_ARGV];
71 int readp[2], writep[2];
73 int mode_read, mode_write, mode_shell;
76 #if !defined(HAVE_FCNTL_F_CLOSEM) && !defined(HAVE_CLOSEFROM)
78 int64_t rlimitResult=0;
81 if (!prog || !*prog) {
82 /* execve(3) A component of the file does not name an existing file or file is an empty string. */
87 bpipe = (BPIPE *)malloc(sizeof(BPIPE));
88 memset(bpipe, 0, sizeof(BPIPE));
89 mode_read = (mode[0] == 'r');
90 mode_write = (mode[0] == 'w' || mode[1] == 'w');
91 /* mode is at least 2 bytes long, can be 3, rs, rws, ws */
92 mode_shell = (mode[1] == 's' || (mode[1] && mode[2] == 's'));
93 /* Build arguments for running program. */
94 tprog = get_pool_memory(PM_FNAME);
95 pm_strcpy(tprog, prog);
97 build_sh_argc_argv(tprog, &bargc, bargv, MAX_ARGV);
100 build_argc_argv(tprog, &bargc, bargv, MAX_ARGV);
103 /* Unable to parse the command, avoid segfault after the fork() */
104 if (bargc == 0 || bargv[0] == NULL) {
105 free_pool_memory(tprog);
107 /* execve(3) A component of the file does not name an existing file or file is an empty string. */
113 printf("argc=%d\n", bargc);
114 for (i=0; i<bargc; i++) {
115 printf("argc=%d argv=%s:\n", i, bargv[i]);
119 /* Each pipe is one way, write one end, read the other, so we need two */
120 if (mode_write && pipe(writep) == -1) {
123 free_pool_memory(tprog);
127 if (mode_read && pipe(readp) == -1) {
134 free_pool_memory(tprog);
139 /* Many systems doesn't have the correct system call
140 * to determine the FD list to close.
142 #if !defined(HAVE_FCNTL_F_CLOSEM) && !defined(HAVE_CLOSEFROM)
143 if (getrlimit(RLIMIT_NOFILE, &rl) == -1) {
144 rlimitResult = sysconf(_SC_OPEN_MAX);
146 rlimitResult = rl.rlim_max;
150 /* Start worker process */
151 switch (bpipe->worker_pid = fork()) {
163 free_pool_memory(tprog);
170 dup2(writep[0], 0); /* Dup our write to his stdin */
173 close(readp[0]); /* Close unused child fds */
174 dup2(readp[1], 1); /* dup our read to his stdout */
175 dup2(readp[1], 2); /* and his stderr */
178 #if HAVE_FCNTL_F_CLOSEM
183 for (i=rlimitResult; i >= 3; i--) {
188 /* Setup the environment if requested, we do not use execvpe()
189 * because it's not wildly available
190 * TODO: Implement envp to windows version of bpipe
194 execvp(bargv[0], bargv); /* call the program */
195 /* Convert errno into an exit code for later analysis */
196 for (i=0; i< num_execvp_errors; i++) {
197 if (execvp_errors[i] == errno) {
198 _exit(200 + i); /* exit code => errno */
201 /* Do not flush stdio */
202 _exit(255); /* unknown errno */
204 default: /* parent */
207 free_pool_memory(tprog);
209 close(readp[1]); /* close unused parent fds */
210 bpipe->rfd = fdopen(readp[0], "r"); /* open file descriptor */
214 bpipe->wfd = fdopen(writep[1], "w");
216 bpipe->worker_stime = time(NULL);
219 bpipe->timer_id = start_child_timer(NULL, bpipe->worker_pid, wait);
224 /* Close the write pipe only */
225 int close_wpipe(BPIPE *bpipe)
231 if (fclose(bpipe->wfd) != 0) {
240 * Close both pipes and free resources
242 * Returns: 0 on success
245 int close_bpipe(BPIPE *bpipe)
264 if (bpipe->wait == 0) {
265 wait_option = 0; /* wait indefinitely */
267 wait_option = WNOHANG; /* don't hang */
269 remaining_wait = bpipe->wait;
271 /* wait for worker child to exit */
273 Dmsg2(100, "Wait for %d opt=%d\n", bpipe->worker_pid, wait_option);
275 wpid = waitpid(bpipe->worker_pid, &chldstatus, wait_option);
276 } while (wpid == -1 && (errno == EINTR || errno == EAGAIN));
277 if (wpid == bpipe->worker_pid || wpid == -1) {
280 Dmsg3(100, "Got break wpid=%d status=%d ERR=%s\n", wpid, chldstatus,
281 wpid==-1?be.bstrerror():"none");
284 Dmsg3(100, "Got wpid=%d status=%d ERR=%s\n", wpid, chldstatus,
285 wpid==-1?strerror(errno):"none");
286 if (remaining_wait > 0) {
287 bmicrosleep(1, 0); /* wait one second */
290 stat = ETIME; /* set error status */
292 break; /* don't wait any longer */
296 if (WIFEXITED(chldstatus)) { /* process exit()ed */
297 stat = WEXITSTATUS(chldstatus);
299 Dmsg1(100, "Non-zero status %d returned from child.\n", stat);
300 stat |= b_errno_exit; /* exit status returned */
302 Dmsg1(100, "child status=%d\n", stat & ~b_errno_exit);
303 } else if (WIFSIGNALED(chldstatus)) { /* process died */
305 stat = WTERMSIG(chldstatus);
307 stat = 1; /* fake child status */
309 Dmsg1(100, "Child died from signal %d\n", stat);
310 stat |= b_errno_signal; /* exit signal returned */
313 if (bpipe->timer_id) {
314 stop_child_timer(bpipe->timer_id);
317 Dmsg2(100, "returning stat=%d,%d\n", stat & ~(b_errno_exit|b_errno_signal), stat);
322 * Build argc and argv from a string
324 static void build_argc_argv(char *cmd, int *bargc, char *bargv[], int max_argv)
331 for (i=0; i<max_argv; i++)
336 while (*p && (*p == ' ' || *p == '\t'))
338 if (*p == '\"' || *p == '\'') {
343 while (*p && argc < MAX_ARGV) {
346 while (*q && *q != quote)
350 while (*q && *q != ' ')
357 while (*p && (*p == ' ' || *p == '\t'))
359 if (*p == '\"' || *p == '\'') {
367 #endif /* HAVE_WIN32 */
370 * Run an external program. Optionally wait a specified number
371 * of seconds. Program killed if wait exceeded. Optionally
372 * return the output from the program (normally a single line).
374 * If the watchdog kills the program, fgets returns, and ferror is set
375 * to 1 (=>SUCCESS), so we check if the watchdog killed the program.
377 * Contrary to my normal calling conventions, this program
379 * Returns: 0 on success
380 * non-zero on error == berrno status
382 int run_program(char *prog, int wait, POOLMEM *&results)
389 bpipe = open_bpipe(prog, wait, mode);
394 int len = sizeof_pool_memory(results) - 1;
395 fgets(results, len, bpipe->rfd);
397 if (feof(bpipe->rfd)) {
400 stat1 = ferror(bpipe->rfd);
404 Dmsg2(100, "Run program fgets stat=%d ERR=%s\n", stat1, be.bstrerror(errno));
405 } else if (stat1 != 0) {
406 Dmsg1(100, "Run program fgets stat=%d\n", stat1);
407 if (bpipe->timer_id) {
408 Dmsg1(100, "Run program fgets killed=%d\n", bpipe->timer_id->killed);
409 /* NB: I'm not sure it is really useful for run_program. Without the
410 * following lines run_program would not detect if the program was killed
411 * by the watchdog. */
412 if (bpipe->timer_id->killed) {
414 pm_strcpy(results, _("Program killed by Bacula (timeout)\n"));
418 stat2 = close_bpipe(bpipe);
419 stat1 = stat2 != 0 ? stat2 : stat1;
420 Dmsg1(100, "Run program returning %d\n", stat1);
425 * Run an external program. Optionally wait a specified number
426 * of seconds. Program killed if wait exceeded (it is done by the
427 * watchdog, as fgets is a blocking function).
429 * If the watchdog kills the program, fgets returns, and ferror is set
430 * to 1 (=>SUCCESS), so we check if the watchdog killed the program.
432 * Return the full output from the program (not only the first line).
434 * Contrary to my normal calling conventions, this program
436 * Returns: 0 on success
437 * non-zero on error == berrno status
440 int run_program_full_output(char *prog, int wait, POOLMEM *&results, char *env[])
447 const int bufsize = 32000;
452 tmp = get_pool_memory(PM_MESSAGE);
453 buf = (char *)malloc(bufsize+1);
457 bpipe = open_bpipe(prog, wait, mode, env);
467 fgets(buf, bufsize, bpipe->rfd);
470 if (feof(bpipe->rfd)) {
472 Dmsg1(100, "Run program fgets stat=%d\n", stat1);
475 stat1 = ferror(bpipe->rfd);
479 Dmsg2(100, "Run program fgets stat=%d ERR=%s\n", stat1, be.bstrerror());
481 } else if (stat1 != 0) {
482 Dmsg1(200, "Run program fgets stat=%d\n", stat1);
483 if (bpipe->timer_id && bpipe->timer_id->killed) {
484 Dmsg1(100, "Run program saw fgets killed=%d\n", bpipe->timer_id->killed);
490 * We always check whether the timer killed the program. We would see
491 * an eof even when it does so we just have to trust the killed flag
492 * and set the timer values to avoid edge cases where the program ends
493 * just as the timer kills it.
495 if (bpipe->timer_id && bpipe->timer_id->killed) {
496 Dmsg1(100, "Run program fgets killed=%d\n", bpipe->timer_id->killed);
497 pm_strcpy(tmp, _("Program killed by Bacula (timeout)\n"));
500 pm_strcpy(results, tmp);
501 Dmsg3(200, "resadr=0x%x reslen=%d res=%s\n", results, strlen(results), results);
502 stat2 = close_bpipe(bpipe);
503 stat1 = stat2 != 0 ? stat2 : stat1;
505 Dmsg1(100, "Run program returning %d\n", stat1);
507 free_pool_memory(tmp);