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
30 #include <sys/resource.h>
32 /* If not available, use a wrapper that will not use it */
33 #define getrlimit(a,b) -1
36 int execvp_errors[] = {
49 int num_execvp_errors = (int)(sizeof(execvp_errors)/sizeof(int));
54 #if !defined(HAVE_WIN32)
55 static void build_argc_argv(char *cmd, int *bargc, char *bargv[], int max_arg);
57 void build_sh_argc_argv(char *cmd, int *bargc, char *bargv[], int max_arg)
59 bargv[0] = (char *)"/bin/sh";
60 bargv[1] = (char *)"-c";
67 * Run an external program. Optionally wait a specified number
68 * of seconds. Program killed if wait exceeded. We open
69 * a bi-directional pipe so that the user can read from and
70 * write to the program.
72 BPIPE *open_bpipe(char *prog, int wait, const char *mode, char *envp[])
74 char *bargv[MAX_ARGV];
76 int readp[2], writep[2];
78 int mode_read, mode_write, mode_shell;
81 #if !defined(HAVE_FCNTL_F_CLOSEM) && !defined(HAVE_CLOSEFROM)
83 int64_t rlimitResult=0;
86 if (!prog || !*prog) {
87 /* execve(3) A component of the file does not name an existing file or file is an empty string. */
92 bpipe = (BPIPE *)malloc(sizeof(BPIPE));
93 memset(bpipe, 0, sizeof(BPIPE));
94 mode_read = (mode[0] == 'r');
95 mode_write = (mode[0] == 'w' || mode[1] == 'w');
96 /* mode is at least 2 bytes long, can be 3, rs, rws, ws */
97 mode_shell = (mode[1] == 's' || (mode[1] && mode[2] == 's'));
98 /* Build arguments for running program. */
99 tprog = get_pool_memory(PM_FNAME);
100 pm_strcpy(tprog, prog);
102 build_sh_argc_argv(tprog, &bargc, bargv, MAX_ARGV);
105 build_argc_argv(tprog, &bargc, bargv, MAX_ARGV);
108 /* Unable to parse the command, avoid segfault after the fork() */
109 if (bargc == 0 || bargv[0] == NULL) {
110 free_pool_memory(tprog);
112 /* execve(3) A component of the file does not name an existing file or file is an empty string. */
118 printf("argc=%d\n", bargc);
119 for (i=0; i<bargc; i++) {
120 printf("argc=%d argv=%s:\n", i, bargv[i]);
124 /* Each pipe is one way, write one end, read the other, so we need two */
125 if (mode_write && pipe(writep) == -1) {
128 free_pool_memory(tprog);
132 if (mode_read && pipe(readp) == -1) {
139 free_pool_memory(tprog);
144 /* Many systems doesn't have the correct system call
145 * to determine the FD list to close.
147 #if !defined(HAVE_FCNTL_F_CLOSEM) && !defined(HAVE_CLOSEFROM)
148 if (getrlimit(RLIMIT_NOFILE, &rl) == -1) {
149 rlimitResult = sysconf(_SC_OPEN_MAX);
151 rlimitResult = rl.rlim_max;
155 /* Start worker process */
156 switch (bpipe->worker_pid = fork()) {
168 free_pool_memory(tprog);
175 dup2(writep[0], 0); /* Dup our write to his stdin */
178 close(readp[0]); /* Close unused child fds */
179 dup2(readp[1], 1); /* dup our read to his stdout */
180 dup2(readp[1], 2); /* and his stderr */
183 #if HAVE_FCNTL_F_CLOSEM
188 for (i=rlimitResult; i >= 3; i--) {
193 /* Setup the environment if requested, we do not use execvpe()
194 * because it's not wildly available
195 * TODO: Implement envp to windows version of bpipe
199 execvp(bargv[0], bargv); /* call the program */
200 /* Convert errno into an exit code for later analysis */
201 for (i=0; i< num_execvp_errors; i++) {
202 if (execvp_errors[i] == errno) {
203 _exit(200 + i); /* exit code => errno */
206 /* Do not flush stdio */
207 _exit(255); /* unknown errno */
209 default: /* parent */
212 free_pool_memory(tprog);
214 close(readp[1]); /* close unused parent fds */
215 bpipe->rfd = fdopen(readp[0], "r"); /* open file descriptor */
219 bpipe->wfd = fdopen(writep[1], "w");
221 bpipe->worker_stime = time(NULL);
224 bpipe->timer_id = start_child_timer(NULL, bpipe->worker_pid, wait);
229 /* Close the write pipe only */
230 int close_wpipe(BPIPE *bpipe)
236 if (fclose(bpipe->wfd) != 0) {
245 * Close both pipes and free resources
247 * Returns: 0 on success
250 int close_bpipe(BPIPE *bpipe)
269 if (bpipe->wait == 0) {
270 wait_option = 0; /* wait indefinitely */
272 wait_option = WNOHANG; /* don't hang */
274 remaining_wait = bpipe->wait;
276 /* wait for worker child to exit */
278 Dmsg2(100, "Wait for %d opt=%d\n", bpipe->worker_pid, wait_option);
280 wpid = waitpid(bpipe->worker_pid, &chldstatus, wait_option);
281 } while (wpid == -1 && (errno == EINTR || errno == EAGAIN));
282 if (wpid == bpipe->worker_pid || wpid == -1) {
285 Dmsg3(100, "Got break wpid=%d status=%d ERR=%s\n", wpid, chldstatus,
286 wpid==-1?be.bstrerror():"none");
289 Dmsg3(100, "Got wpid=%d status=%d ERR=%s\n", wpid, chldstatus,
290 wpid==-1?strerror(errno):"none");
291 if (remaining_wait > 0) {
292 bmicrosleep(1, 0); /* wait one second */
295 stat = ETIME; /* set error status */
297 break; /* don't wait any longer */
301 if (WIFEXITED(chldstatus)) { /* process exit()ed */
302 stat = WEXITSTATUS(chldstatus);
304 Dmsg1(100, "Non-zero status %d returned from child.\n", stat);
305 stat |= b_errno_exit; /* exit status returned */
307 Dmsg1(100, "child status=%d\n", stat & ~b_errno_exit);
308 } else if (WIFSIGNALED(chldstatus)) { /* process died */
310 stat = WTERMSIG(chldstatus);
312 stat = 1; /* fake child status */
314 Dmsg1(100, "Child died from signal %d\n", stat);
315 stat |= b_errno_signal; /* exit signal returned */
318 if (bpipe->timer_id) {
319 stop_child_timer(bpipe->timer_id);
322 Dmsg2(100, "returning stat=%d,%d\n", stat & ~(b_errno_exit|b_errno_signal), stat);
327 * Build argc and argv from a string
329 static void build_argc_argv(char *cmd, int *bargc, char *bargv[], int max_argv)
336 for (i=0; i<max_argv; i++)
341 while (*p && (*p == ' ' || *p == '\t'))
343 if (*p == '\"' || *p == '\'') {
348 while (*p && argc < MAX_ARGV) {
351 while (*q && *q != quote)
355 while (*q && *q != ' ')
362 while (*p && (*p == ' ' || *p == '\t'))
364 if (*p == '\"' || *p == '\'') {
372 #endif /* HAVE_WIN32 */
375 * Run an external program. Optionally wait a specified number
376 * of seconds. Program killed if wait exceeded. Optionally
377 * return the output from the program (normally a single line).
379 * If the watchdog kills the program, fgets returns, and ferror is set
380 * to 1 (=>SUCCESS), so we check if the watchdog killed the program.
382 * Contrary to my normal calling conventions, this program
384 * Returns: 0 on success
385 * non-zero on error == berrno status
387 int run_program(char *prog, int wait, POOLMEM *&results)
394 bpipe = open_bpipe(prog, wait, mode);
399 int len = sizeof_pool_memory(results) - 1;
400 fgets(results, len, bpipe->rfd);
402 if (feof(bpipe->rfd)) {
405 stat1 = ferror(bpipe->rfd);
409 Dmsg2(100, "Run program fgets stat=%d ERR=%s\n", stat1, be.bstrerror(errno));
410 } else if (stat1 != 0) {
411 Dmsg1(100, "Run program fgets stat=%d\n", stat1);
412 if (bpipe->timer_id) {
413 Dmsg1(100, "Run program fgets killed=%d\n", bpipe->timer_id->killed);
414 /* NB: I'm not sure it is really useful for run_program. Without the
415 * following lines run_program would not detect if the program was killed
416 * by the watchdog. */
417 if (bpipe->timer_id->killed) {
419 pm_strcpy(results, _("Program killed by Bacula (timeout)\n"));
423 stat2 = close_bpipe(bpipe);
424 stat1 = stat2 != 0 ? stat2 : stat1;
425 Dmsg1(100, "Run program returning %d\n", stat1);
430 * Run an external program. Optionally wait a specified number
431 * of seconds. Program killed if wait exceeded (it is done by the
432 * watchdog, as fgets is a blocking function).
434 * If the watchdog kills the program, fgets returns, and ferror is set
435 * to 1 (=>SUCCESS), so we check if the watchdog killed the program.
437 * Return the full output from the program (not only the first line).
439 * Contrary to my normal calling conventions, this program
441 * Returns: 0 on success
442 * non-zero on error == berrno status
445 int run_program_full_output(char *prog, int wait, POOLMEM *&results, char *env[])
452 const int bufsize = 32000;
457 tmp = get_pool_memory(PM_MESSAGE);
458 buf = (char *)malloc(bufsize+1);
462 bpipe = open_bpipe(prog, wait, mode, env);
472 fgets(buf, bufsize, bpipe->rfd);
475 if (feof(bpipe->rfd)) {
477 Dmsg1(100, "Run program fgets stat=%d\n", stat1);
480 stat1 = ferror(bpipe->rfd);
484 Dmsg2(100, "Run program fgets stat=%d ERR=%s\n", stat1, be.bstrerror());
486 } else if (stat1 != 0) {
487 Dmsg1(200, "Run program fgets stat=%d\n", stat1);
488 if (bpipe->timer_id && bpipe->timer_id->killed) {
489 Dmsg1(100, "Run program saw fgets killed=%d\n", bpipe->timer_id->killed);
495 * We always check whether the timer killed the program. We would see
496 * an eof even when it does so we just have to trust the killed flag
497 * and set the timer values to avoid edge cases where the program ends
498 * just as the timer kills it.
500 if (bpipe->timer_id && bpipe->timer_id->killed) {
501 Dmsg1(100, "Run program fgets killed=%d\n", bpipe->timer_id->killed);
502 pm_strcpy(tmp, _("Program killed by Bacula (timeout)\n"));
505 pm_strcpy(results, tmp);
506 Dmsg3(200, "resadr=0x%x reslen=%d res=%s\n", results, strlen(results), results);
507 stat2 = close_bpipe(bpipe);
508 stat1 = stat2 != 0 ? stat2 : stat1;
510 Dmsg1(100, "Run program returning %d\n", stat1);
512 free_pool_memory(tmp);