2 Bacula® - The Network Backup Solution
4 Copyright (C) 2002-2014 Free Software Foundation Europe e.V.
6 The main author of Bacula is Kern Sibbald, with contributions from many
7 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 Bacula® is a registered trademark of Kern Sibbald.
17 * bpipe.c bi-directional pipe
19 * Kern Sibbald, November MMII
27 int execvp_errors[] = {
40 int num_execvp_errors = (int)(sizeof(execvp_errors)/sizeof(int));
45 #if !defined(HAVE_WIN32)
46 static void build_argc_argv(char *cmd, int *bargc, char *bargv[], int max_arg);
48 void build_sh_argc_argv(char *cmd, int *bargc, char *bargv[], int max_arg)
50 bargv[0] = (char *)"/bin/sh";
51 bargv[1] = (char *)"-c";
58 * Run an external program. Optionally wait a specified number
59 * of seconds. Program killed if wait exceeded. We open
60 * a bi-directional pipe so that the user can read from and
61 * write to the program.
63 BPIPE *open_bpipe(char *prog, int wait, const char *mode)
65 char *bargv[MAX_ARGV];
67 int readp[2], writep[2];
69 int mode_read, mode_write, mode_shell;
73 bpipe = (BPIPE *)malloc(sizeof(BPIPE));
74 memset(bpipe, 0, sizeof(BPIPE));
75 mode_read = (mode[0] == 'r');
76 mode_write = (mode[0] == 'w' || mode[1] == 'w');
77 /* mode is at least 2 bytes long, can be 3, rs, rws, ws */
78 mode_shell = (mode[1] == 's' || (mode[1] && mode[2] == 's'));
79 /* Build arguments for running program. */
80 tprog = get_pool_memory(PM_FNAME);
81 pm_strcpy(tprog, prog);
83 build_sh_argc_argv(tprog, &bargc, bargv, MAX_ARGV);
86 build_argc_argv(tprog, &bargc, bargv, MAX_ARGV);
89 printf("argc=%d\n", bargc);
90 for (i=0; i<bargc; i++) {
91 printf("argc=%d argv=%s:\n", i, bargv[i]);
95 /* Each pipe is one way, write one end, read the other, so we need two */
96 if (mode_write && pipe(writep) == -1) {
99 free_pool_memory(tprog);
103 if (mode_read && pipe(readp) == -1) {
110 free_pool_memory(tprog);
114 /* Start worker process */
115 switch (bpipe->worker_pid = fork()) {
127 free_pool_memory(tprog);
134 dup2(writep[0], 0); /* Dup our write to his stdin */
137 close(readp[0]); /* Close unused child fds */
138 dup2(readp[1], 1); /* dup our read to his stdout */
139 dup2(readp[1], 2); /* and his stderr */
141 /* Note, the close log cause problems, see bug #1536 */
142 /* closelog(); close syslog if open */
143 for (i=3; i<=32; i++) { /* close any open file descriptors */
146 execvp(bargv[0], bargv); /* call the program */
147 /* Convert errno into an exit code for later analysis */
148 for (i=0; i< num_execvp_errors; i++) {
149 if (execvp_errors[i] == errno) {
150 exit(200 + i); /* exit code => errno */
153 exit(255); /* unknown errno */
155 default: /* parent */
158 free_pool_memory(tprog);
160 close(readp[1]); /* close unused parent fds */
161 bpipe->rfd = fdopen(readp[0], "r"); /* open file descriptor */
165 bpipe->wfd = fdopen(writep[1], "w");
167 bpipe->worker_stime = time(NULL);
170 bpipe->timer_id = start_child_timer(NULL, bpipe->worker_pid, wait);
175 /* Close the write pipe only */
176 int close_wpipe(BPIPE *bpipe)
182 if (fclose(bpipe->wfd) != 0) {
191 * Close both pipes and free resources
193 * Returns: 0 on success
196 int close_bpipe(BPIPE *bpipe)
215 if (bpipe->wait == 0) {
216 wait_option = 0; /* wait indefinitely */
218 wait_option = WNOHANG; /* don't hang */
220 remaining_wait = bpipe->wait;
222 /* wait for worker child to exit */
224 Dmsg2(800, "Wait for %d opt=%d\n", bpipe->worker_pid, wait_option);
226 wpid = waitpid(bpipe->worker_pid, &chldstatus, wait_option);
227 } while (wpid == -1 && (errno == EINTR || errno == EAGAIN));
228 if (wpid == bpipe->worker_pid || wpid == -1) {
231 Dmsg3(800, "Got break wpid=%d status=%d ERR=%s\n", wpid, chldstatus,
232 wpid==-1?be.bstrerror():"none");
235 Dmsg3(800, "Got wpid=%d status=%d ERR=%s\n", wpid, chldstatus,
236 wpid==-1?strerror(errno):"none");
237 if (remaining_wait > 0) {
238 bmicrosleep(1, 0); /* wait one second */
241 stat = ETIME; /* set error status */
243 break; /* don't wait any longer */
247 if (WIFEXITED(chldstatus)) { /* process exit()ed */
248 stat = WEXITSTATUS(chldstatus);
250 Dmsg1(800, "Non-zero status %d returned from child.\n", stat);
251 stat |= b_errno_exit; /* exit status returned */
253 Dmsg1(800, "child status=%d\n", stat & ~b_errno_exit);
254 } else if (WIFSIGNALED(chldstatus)) { /* process died */
256 stat = WTERMSIG(chldstatus);
258 stat = 1; /* fake child status */
260 Dmsg1(800, "Child died from signal %d\n", stat);
261 stat |= b_errno_signal; /* exit signal returned */
264 if (bpipe->timer_id) {
265 stop_child_timer(bpipe->timer_id);
268 Dmsg2(800, "returning stat=%d,%d\n", stat & ~(b_errno_exit|b_errno_signal), stat);
273 * Build argc and argv from a string
275 static void build_argc_argv(char *cmd, int *bargc, char *bargv[], int max_argv)
282 for (i=0; i<max_argv; i++)
287 while (*p && (*p == ' ' || *p == '\t'))
289 if (*p == '\"' || *p == '\'') {
294 while (*p && argc < MAX_ARGV) {
297 while (*q && *q != quote)
301 while (*q && *q != ' ')
308 while (*p && (*p == ' ' || *p == '\t'))
310 if (*p == '\"' || *p == '\'') {
318 #endif /* HAVE_WIN32 */
321 * Run an external program. Optionally wait a specified number
322 * of seconds. Program killed if wait exceeded. Optionally
323 * return the output from the program (normally a single line).
325 * If the watchdog kills the program, fgets returns, and ferror is set
326 * to 1 (=>SUCCESS), so we check if the watchdog killed the program.
328 * Contrary to my normal calling conventions, this program
330 * Returns: 0 on success
331 * non-zero on error == berrno status
333 int run_program(char *prog, int wait, POOLMEM *&results)
340 bpipe = open_bpipe(prog, wait, mode);
345 int len = sizeof_pool_memory(results) - 1;
346 fgets(results, len, bpipe->rfd);
348 if (feof(bpipe->rfd)) {
351 stat1 = ferror(bpipe->rfd);
355 Dmsg2(150, "Run program fgets stat=%d ERR=%s\n", stat1, be.bstrerror(errno));
356 } else if (stat1 != 0) {
357 Dmsg1(150, "Run program fgets stat=%d\n", stat1);
358 if (bpipe->timer_id) {
359 Dmsg1(150, "Run program fgets killed=%d\n", bpipe->timer_id->killed);
360 /* NB: I'm not sure it is really useful for run_program. Without the
361 * following lines run_program would not detect if the program was killed
362 * by the watchdog. */
363 if (bpipe->timer_id->killed) {
365 pm_strcpy(results, _("Program killed by Bacula (timeout)\n"));
369 stat2 = close_bpipe(bpipe);
370 stat1 = stat2 != 0 ? stat2 : stat1;
371 Dmsg1(150, "Run program returning %d\n", stat1);
376 * Run an external program. Optionally wait a specified number
377 * of seconds. Program killed if wait exceeded (it is done by the
378 * watchdog, as fgets is a blocking function).
380 * If the watchdog kills the program, fgets returns, and ferror is set
381 * to 1 (=>SUCCESS), so we check if the watchdog killed the program.
383 * Return the full output from the program (not only the first line).
385 * Contrary to my normal calling conventions, this program
387 * Returns: 0 on success
388 * non-zero on error == berrno status
391 int run_program_full_output(char *prog, int wait, POOLMEM *&results)
398 const int bufsize = 32000;
403 tmp = get_pool_memory(PM_MESSAGE);
404 buf = (char *)malloc(bufsize+1);
408 bpipe = open_bpipe(prog, wait, mode);
418 fgets(buf, bufsize, bpipe->rfd);
421 if (feof(bpipe->rfd)) {
423 Dmsg1(900, "Run program fgets stat=%d\n", stat1);
426 stat1 = ferror(bpipe->rfd);
430 Dmsg2(200, "Run program fgets stat=%d ERR=%s\n", stat1, be.bstrerror());
432 } else if (stat1 != 0) {
433 Dmsg1(900, "Run program fgets stat=%d\n", stat1);
434 if (bpipe->timer_id && bpipe->timer_id->killed) {
435 Dmsg1(250, "Run program saw fgets killed=%d\n", bpipe->timer_id->killed);
441 * We always check whether the timer killed the program. We would see
442 * an eof even when it does so we just have to trust the killed flag
443 * and set the timer values to avoid edge cases where the program ends
444 * just as the timer kills it.
446 if (bpipe->timer_id && bpipe->timer_id->killed) {
447 Dmsg1(150, "Run program fgets killed=%d\n", bpipe->timer_id->killed);
448 pm_strcpy(tmp, _("Program killed by Bacula (timeout)\n"));
451 pm_strcpy(results, tmp);
452 Dmsg3(1900, "resadr=0x%x reslen=%d res=%s\n", results, strlen(results), results);
453 stat2 = close_bpipe(bpipe);
454 stat1 = stat2 != 0 ? stat2 : stat1;
456 Dmsg1(900, "Run program returning %d\n", stat1);
458 free_pool_memory(tmp);