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;
77 int64_t rlimitResult=0;
79 if (!prog || !*prog) {
80 /* execve(3) A component of the file does not name an existing file or file is an empty string. */
85 bpipe = (BPIPE *)malloc(sizeof(BPIPE));
86 memset(bpipe, 0, sizeof(BPIPE));
87 mode_read = (mode[0] == 'r');
88 mode_write = (mode[0] == 'w' || mode[1] == 'w');
89 /* mode is at least 2 bytes long, can be 3, rs, rws, ws */
90 mode_shell = (mode[1] == 's' || (mode[1] && mode[2] == 's'));
91 /* Build arguments for running program. */
92 tprog = get_pool_memory(PM_FNAME);
93 pm_strcpy(tprog, prog);
95 build_sh_argc_argv(tprog, &bargc, bargv, MAX_ARGV);
98 build_argc_argv(tprog, &bargc, bargv, MAX_ARGV);
101 /* Unable to parse the command, avoid segfault after the fork() */
102 if (bargc == 0 || bargv[0] == NULL) {
103 free_pool_memory(tprog);
105 /* execve(3) A component of the file does not name an existing file or file is an empty string. */
111 printf("argc=%d\n", bargc);
112 for (i=0; i<bargc; i++) {
113 printf("argc=%d argv=%s:\n", i, bargv[i]);
117 /* Each pipe is one way, write one end, read the other, so we need two */
118 if (mode_write && pipe(writep) == -1) {
121 free_pool_memory(tprog);
125 if (mode_read && pipe(readp) == -1) {
132 free_pool_memory(tprog);
137 /* Many systems doesn't have the correct system call
138 * to determine the FD list to close.
140 #if !defined(HAVE_FCNTL_F_CLOSEM) && !defined(HAVE_CLOSEFROM)
141 if (getrlimit(RLIMIT_NOFILE, &rl) == -1) {
142 rlimitResult = sysconf(_SC_OPEN_MAX);
144 rlimitResult = rl.rlim_max;
148 /* Start worker process */
149 switch (bpipe->worker_pid = fork()) {
161 free_pool_memory(tprog);
168 dup2(writep[0], 0); /* Dup our write to his stdin */
171 close(readp[0]); /* Close unused child fds */
172 dup2(readp[1], 1); /* dup our read to his stdout */
173 dup2(readp[1], 2); /* and his stderr */
176 #if HAVE_FCNTL_F_CLOSEM
181 for (i=rlimitResult; i >= 3; i--) {
186 /* Setup the environment if requested, we do not use execvpe()
187 * because it's not wildly available
188 * TODO: Implement envp to windows version of bpipe
192 execvp(bargv[0], bargv); /* call the program */
193 /* Convert errno into an exit code for later analysis */
194 for (i=0; i< num_execvp_errors; i++) {
195 if (execvp_errors[i] == errno) {
196 _exit(200 + i); /* exit code => errno */
199 /* Do not flush stdio */
200 _exit(255); /* unknown errno */
202 default: /* parent */
205 free_pool_memory(tprog);
207 close(readp[1]); /* close unused parent fds */
208 bpipe->rfd = fdopen(readp[0], "r"); /* open file descriptor */
212 bpipe->wfd = fdopen(writep[1], "w");
214 bpipe->worker_stime = time(NULL);
217 bpipe->timer_id = start_child_timer(NULL, bpipe->worker_pid, wait);
222 /* Close the write pipe only */
223 int close_wpipe(BPIPE *bpipe)
229 if (fclose(bpipe->wfd) != 0) {
238 * Close both pipes and free resources
240 * Returns: 0 on success
243 int close_bpipe(BPIPE *bpipe)
262 if (bpipe->wait == 0) {
263 wait_option = 0; /* wait indefinitely */
265 wait_option = WNOHANG; /* don't hang */
267 remaining_wait = bpipe->wait;
269 /* wait for worker child to exit */
271 Dmsg2(100, "Wait for %d opt=%d\n", bpipe->worker_pid, wait_option);
273 wpid = waitpid(bpipe->worker_pid, &chldstatus, wait_option);
274 } while (wpid == -1 && (errno == EINTR || errno == EAGAIN));
275 if (wpid == bpipe->worker_pid || wpid == -1) {
278 Dmsg3(100, "Got break wpid=%d status=%d ERR=%s\n", wpid, chldstatus,
279 wpid==-1?be.bstrerror():"none");
282 Dmsg3(100, "Got wpid=%d status=%d ERR=%s\n", wpid, chldstatus,
283 wpid==-1?strerror(errno):"none");
284 if (remaining_wait > 0) {
285 bmicrosleep(1, 0); /* wait one second */
288 stat = ETIME; /* set error status */
290 break; /* don't wait any longer */
294 if (WIFEXITED(chldstatus)) { /* process exit()ed */
295 stat = WEXITSTATUS(chldstatus);
297 Dmsg1(100, "Non-zero status %d returned from child.\n", stat);
298 stat |= b_errno_exit; /* exit status returned */
300 Dmsg1(100, "child status=%d\n", stat & ~b_errno_exit);
301 } else if (WIFSIGNALED(chldstatus)) { /* process died */
303 stat = WTERMSIG(chldstatus);
305 stat = 1; /* fake child status */
307 Dmsg1(100, "Child died from signal %d\n", stat);
308 stat |= b_errno_signal; /* exit signal returned */
311 if (bpipe->timer_id) {
312 stop_child_timer(bpipe->timer_id);
315 Dmsg2(100, "returning stat=%d,%d\n", stat & ~(b_errno_exit|b_errno_signal), stat);
320 * Build argc and argv from a string
322 static void build_argc_argv(char *cmd, int *bargc, char *bargv[], int max_argv)
329 for (i=0; i<max_argv; i++)
334 while (*p && (*p == ' ' || *p == '\t'))
336 if (*p == '\"' || *p == '\'') {
341 while (*p && argc < MAX_ARGV) {
344 while (*q && *q != quote)
348 while (*q && *q != ' ')
355 while (*p && (*p == ' ' || *p == '\t'))
357 if (*p == '\"' || *p == '\'') {
365 #endif /* HAVE_WIN32 */
368 * Run an external program. Optionally wait a specified number
369 * of seconds. Program killed if wait exceeded. Optionally
370 * return the output from the program (normally a single line).
372 * If the watchdog kills the program, fgets returns, and ferror is set
373 * to 1 (=>SUCCESS), so we check if the watchdog killed the program.
375 * Contrary to my normal calling conventions, this program
377 * Returns: 0 on success
378 * non-zero on error == berrno status
380 int run_program(char *prog, int wait, POOLMEM *&results)
387 bpipe = open_bpipe(prog, wait, mode);
392 int len = sizeof_pool_memory(results) - 1;
393 fgets(results, len, bpipe->rfd);
395 if (feof(bpipe->rfd)) {
398 stat1 = ferror(bpipe->rfd);
402 Dmsg2(100, "Run program fgets stat=%d ERR=%s\n", stat1, be.bstrerror(errno));
403 } else if (stat1 != 0) {
404 Dmsg1(100, "Run program fgets stat=%d\n", stat1);
405 if (bpipe->timer_id) {
406 Dmsg1(100, "Run program fgets killed=%d\n", bpipe->timer_id->killed);
407 /* NB: I'm not sure it is really useful for run_program. Without the
408 * following lines run_program would not detect if the program was killed
409 * by the watchdog. */
410 if (bpipe->timer_id->killed) {
412 pm_strcpy(results, _("Program killed by Bacula (timeout)\n"));
416 stat2 = close_bpipe(bpipe);
417 stat1 = stat2 != 0 ? stat2 : stat1;
418 Dmsg1(100, "Run program returning %d\n", stat1);
423 * Run an external program. Optionally wait a specified number
424 * of seconds. Program killed if wait exceeded (it is done by the
425 * watchdog, as fgets is a blocking function).
427 * If the watchdog kills the program, fgets returns, and ferror is set
428 * to 1 (=>SUCCESS), so we check if the watchdog killed the program.
430 * Return the full output from the program (not only the first line).
432 * Contrary to my normal calling conventions, this program
434 * Returns: 0 on success
435 * non-zero on error == berrno status
438 int run_program_full_output(char *prog, int wait, POOLMEM *&results, char *env[])
445 const int bufsize = 32000;
450 tmp = get_pool_memory(PM_MESSAGE);
451 buf = (char *)malloc(bufsize+1);
455 bpipe = open_bpipe(prog, wait, mode, env);
465 fgets(buf, bufsize, bpipe->rfd);
468 if (feof(bpipe->rfd)) {
470 Dmsg1(100, "Run program fgets stat=%d\n", stat1);
473 stat1 = ferror(bpipe->rfd);
477 Dmsg2(100, "Run program fgets stat=%d ERR=%s\n", stat1, be.bstrerror());
479 } else if (stat1 != 0) {
480 Dmsg1(200, "Run program fgets stat=%d\n", stat1);
481 if (bpipe->timer_id && bpipe->timer_id->killed) {
482 Dmsg1(100, "Run program saw fgets killed=%d\n", bpipe->timer_id->killed);
488 * We always check whether the timer killed the program. We would see
489 * an eof even when it does so we just have to trust the killed flag
490 * and set the timer values to avoid edge cases where the program ends
491 * just as the timer kills it.
493 if (bpipe->timer_id && bpipe->timer_id->killed) {
494 Dmsg1(100, "Run program fgets killed=%d\n", bpipe->timer_id->killed);
495 pm_strcpy(tmp, _("Program killed by Bacula (timeout)\n"));
498 pm_strcpy(results, tmp);
499 Dmsg3(200, "resadr=0x%x reslen=%d res=%s\n", results, strlen(results), results);
500 stat2 = close_bpipe(bpipe);
501 stat1 = stat2 != 0 ? stat2 : stat1;
503 Dmsg1(100, "Run program returning %d\n", stat1);
505 free_pool_memory(tmp);