2 Bacula(R) - The Network Backup Solution
4 Copyright (C) 2000-2016 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 int execvp_errors[] = {
43 int num_execvp_errors = (int)(sizeof(execvp_errors)/sizeof(int));
48 #if !defined(HAVE_WIN32)
49 static void build_argc_argv(char *cmd, int *bargc, char *bargv[], int max_arg);
51 void build_sh_argc_argv(char *cmd, int *bargc, char *bargv[], int max_arg)
53 bargv[0] = (char *)"/bin/sh";
54 bargv[1] = (char *)"-c";
61 * Run an external program. Optionally wait a specified number
62 * of seconds. Program killed if wait exceeded. We open
63 * a bi-directional pipe so that the user can read from and
64 * write to the program.
66 BPIPE *open_bpipe(char *prog, int wait, const char *mode, char *envp[])
68 char *bargv[MAX_ARGV];
70 int readp[2], writep[2];
72 int mode_read, mode_write, mode_shell;
76 if (!prog || !*prog) {
77 /* execve(3) A component of the file does not name an existing file or file is an empty string. */
82 bpipe = (BPIPE *)malloc(sizeof(BPIPE));
83 memset(bpipe, 0, sizeof(BPIPE));
84 mode_read = (mode[0] == 'r');
85 mode_write = (mode[0] == 'w' || mode[1] == 'w');
86 /* mode is at least 2 bytes long, can be 3, rs, rws, ws */
87 mode_shell = (mode[1] == 's' || (mode[1] && mode[2] == 's'));
88 /* Build arguments for running program. */
89 tprog = get_pool_memory(PM_FNAME);
90 pm_strcpy(tprog, prog);
92 build_sh_argc_argv(tprog, &bargc, bargv, MAX_ARGV);
95 build_argc_argv(tprog, &bargc, bargv, MAX_ARGV);
98 printf("argc=%d\n", bargc);
99 for (i=0; i<bargc; i++) {
100 printf("argc=%d argv=%s:\n", i, bargv[i]);
104 /* Each pipe is one way, write one end, read the other, so we need two */
105 if (mode_write && pipe(writep) == -1) {
108 free_pool_memory(tprog);
112 if (mode_read && pipe(readp) == -1) {
119 free_pool_memory(tprog);
123 /* Start worker process */
124 switch (bpipe->worker_pid = fork()) {
136 free_pool_memory(tprog);
143 dup2(writep[0], 0); /* Dup our write to his stdin */
146 close(readp[0]); /* Close unused child fds */
147 dup2(readp[1], 1); /* dup our read to his stdout */
148 dup2(readp[1], 2); /* and his stderr */
150 /* Note, the close log cause problems, see bug #1536 */
151 /* closelog(); close syslog if open */
152 for (i=3; i<=32; i++) { /* close any open file descriptors */
156 /* Setup the environment if requested, we do not use execvpe()
157 * because it's not wildly available
158 * TODO: Implement envp to windows version of bpipe
162 execvp(bargv[0], bargv); /* call the program */
163 /* Convert errno into an exit code for later analysis */
164 for (i=0; i< num_execvp_errors; i++) {
165 if (execvp_errors[i] == errno) {
166 exit(200 + i); /* exit code => errno */
169 exit(255); /* unknown errno */
171 default: /* parent */
174 free_pool_memory(tprog);
176 close(readp[1]); /* close unused parent fds */
177 bpipe->rfd = fdopen(readp[0], "r"); /* open file descriptor */
181 bpipe->wfd = fdopen(writep[1], "w");
183 bpipe->worker_stime = time(NULL);
186 bpipe->timer_id = start_child_timer(NULL, bpipe->worker_pid, wait);
191 /* Close the write pipe only */
192 int close_wpipe(BPIPE *bpipe)
198 if (fclose(bpipe->wfd) != 0) {
207 * Close both pipes and free resources
209 * Returns: 0 on success
212 int close_bpipe(BPIPE *bpipe)
231 if (bpipe->wait == 0) {
232 wait_option = 0; /* wait indefinitely */
234 wait_option = WNOHANG; /* don't hang */
236 remaining_wait = bpipe->wait;
238 /* wait for worker child to exit */
240 Dmsg2(800, "Wait for %d opt=%d\n", bpipe->worker_pid, wait_option);
242 wpid = waitpid(bpipe->worker_pid, &chldstatus, wait_option);
243 } while (wpid == -1 && (errno == EINTR || errno == EAGAIN));
244 if (wpid == bpipe->worker_pid || wpid == -1) {
247 Dmsg3(800, "Got break wpid=%d status=%d ERR=%s\n", wpid, chldstatus,
248 wpid==-1?be.bstrerror():"none");
251 Dmsg3(800, "Got wpid=%d status=%d ERR=%s\n", wpid, chldstatus,
252 wpid==-1?strerror(errno):"none");
253 if (remaining_wait > 0) {
254 bmicrosleep(1, 0); /* wait one second */
257 stat = ETIME; /* set error status */
259 break; /* don't wait any longer */
263 if (WIFEXITED(chldstatus)) { /* process exit()ed */
264 stat = WEXITSTATUS(chldstatus);
266 Dmsg1(800, "Non-zero status %d returned from child.\n", stat);
267 stat |= b_errno_exit; /* exit status returned */
269 Dmsg1(800, "child status=%d\n", stat & ~b_errno_exit);
270 } else if (WIFSIGNALED(chldstatus)) { /* process died */
272 stat = WTERMSIG(chldstatus);
274 stat = 1; /* fake child status */
276 Dmsg1(800, "Child died from signal %d\n", stat);
277 stat |= b_errno_signal; /* exit signal returned */
280 if (bpipe->timer_id) {
281 stop_child_timer(bpipe->timer_id);
284 Dmsg2(800, "returning stat=%d,%d\n", stat & ~(b_errno_exit|b_errno_signal), stat);
289 * Build argc and argv from a string
291 static void build_argc_argv(char *cmd, int *bargc, char *bargv[], int max_argv)
298 for (i=0; i<max_argv; i++)
303 while (*p && (*p == ' ' || *p == '\t'))
305 if (*p == '\"' || *p == '\'') {
310 while (*p && argc < MAX_ARGV) {
313 while (*q && *q != quote)
317 while (*q && *q != ' ')
324 while (*p && (*p == ' ' || *p == '\t'))
326 if (*p == '\"' || *p == '\'') {
334 #endif /* HAVE_WIN32 */
337 * Run an external program. Optionally wait a specified number
338 * of seconds. Program killed if wait exceeded. Optionally
339 * return the output from the program (normally a single line).
341 * If the watchdog kills the program, fgets returns, and ferror is set
342 * to 1 (=>SUCCESS), so we check if the watchdog killed the program.
344 * Contrary to my normal calling conventions, this program
346 * Returns: 0 on success
347 * non-zero on error == berrno status
349 int run_program(char *prog, int wait, POOLMEM *&results)
356 bpipe = open_bpipe(prog, wait, mode);
361 int len = sizeof_pool_memory(results) - 1;
362 fgets(results, len, bpipe->rfd);
364 if (feof(bpipe->rfd)) {
367 stat1 = ferror(bpipe->rfd);
371 Dmsg2(150, "Run program fgets stat=%d ERR=%s\n", stat1, be.bstrerror(errno));
372 } else if (stat1 != 0) {
373 Dmsg1(150, "Run program fgets stat=%d\n", stat1);
374 if (bpipe->timer_id) {
375 Dmsg1(150, "Run program fgets killed=%d\n", bpipe->timer_id->killed);
376 /* NB: I'm not sure it is really useful for run_program. Without the
377 * following lines run_program would not detect if the program was killed
378 * by the watchdog. */
379 if (bpipe->timer_id->killed) {
381 pm_strcpy(results, _("Program killed by Bacula (timeout)\n"));
385 stat2 = close_bpipe(bpipe);
386 stat1 = stat2 != 0 ? stat2 : stat1;
387 Dmsg1(150, "Run program returning %d\n", stat1);
392 * Run an external program. Optionally wait a specified number
393 * of seconds. Program killed if wait exceeded (it is done by the
394 * watchdog, as fgets is a blocking function).
396 * If the watchdog kills the program, fgets returns, and ferror is set
397 * to 1 (=>SUCCESS), so we check if the watchdog killed the program.
399 * Return the full output from the program (not only the first line).
401 * Contrary to my normal calling conventions, this program
403 * Returns: 0 on success
404 * non-zero on error == berrno status
407 int run_program_full_output(char *prog, int wait, POOLMEM *&results, char *env[])
414 const int bufsize = 32000;
419 tmp = get_pool_memory(PM_MESSAGE);
420 buf = (char *)malloc(bufsize+1);
424 bpipe = open_bpipe(prog, wait, mode, env);
434 fgets(buf, bufsize, bpipe->rfd);
437 if (feof(bpipe->rfd)) {
439 Dmsg1(900, "Run program fgets stat=%d\n", stat1);
442 stat1 = ferror(bpipe->rfd);
446 Dmsg2(200, "Run program fgets stat=%d ERR=%s\n", stat1, be.bstrerror());
448 } else if (stat1 != 0) {
449 Dmsg1(900, "Run program fgets stat=%d\n", stat1);
450 if (bpipe->timer_id && bpipe->timer_id->killed) {
451 Dmsg1(250, "Run program saw fgets killed=%d\n", bpipe->timer_id->killed);
457 * We always check whether the timer killed the program. We would see
458 * an eof even when it does so we just have to trust the killed flag
459 * and set the timer values to avoid edge cases where the program ends
460 * just as the timer kills it.
462 if (bpipe->timer_id && bpipe->timer_id->killed) {
463 Dmsg1(150, "Run program fgets killed=%d\n", bpipe->timer_id->killed);
464 pm_strcpy(tmp, _("Program killed by Bacula (timeout)\n"));
467 pm_strcpy(results, tmp);
468 Dmsg3(1900, "resadr=0x%x reslen=%d res=%s\n", results, strlen(results), results);
469 stat2 = close_bpipe(bpipe);
470 stat1 = stat2 != 0 ? stat2 : stat1;
472 Dmsg1(900, "Run program returning %d\n", stat1);
474 free_pool_memory(tmp);