2 Bacula® - The Network Backup Solution
4 Copyright (C) 2002-2010 Free Software Foundation Europe e.V.
6 The main author of Bacula is Kern Sibbald, with contributions from
7 many others, a complete list can be found in the file AUTHORS.
8 This program is Free Software; you can redistribute it and/or
9 modify it under the terms of version three of the GNU Affero General Public
10 License as published by the Free Software Foundation and included
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU Affero General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23 Bacula® is a registered trademark of Kern Sibbald.
24 The licensor of Bacula is the Free Software Foundation Europe
25 (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26 Switzerland, email:ftf@fsfeurope.org.
29 * bpipe.c bi-directional pipe
31 * Kern Sibbald, November MMII
39 int execvp_errors[] = {
52 int num_execvp_errors = (int)(sizeof(execvp_errors)/sizeof(int));
57 #if !defined(HAVE_WIN32)
58 static void build_argc_argv(char *cmd, int *bargc, char *bargv[], int max_arg);
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)
68 char *bargv[MAX_ARGV];
70 int readp[2], writep[2];
72 int mode_read, mode_write;
76 bpipe = (BPIPE *)malloc(sizeof(BPIPE));
77 memset(bpipe, 0, sizeof(BPIPE));
78 mode_read = (mode[0] == 'r');
79 mode_write = (mode[0] == 'w' || mode[1] == 'w');
80 /* Build arguments for running program. */
81 tprog = get_pool_memory(PM_FNAME);
82 pm_strcpy(tprog, prog);
83 build_argc_argv(tprog, &bargc, bargv, MAX_ARGV);
85 printf("argc=%d\n", bargc);
86 for (i=0; i<bargc; i++) {
87 printf("argc=%d argv=%s:\n", i, bargv[i]);
91 /* Each pipe is one way, write one end, read the other, so we need two */
92 if (mode_write && pipe(writep) == -1) {
95 free_pool_memory(tprog);
99 if (mode_read && pipe(readp) == -1) {
106 free_pool_memory(tprog);
110 /* Start worker process */
111 switch (bpipe->worker_pid = fork()) {
123 free_pool_memory(tprog);
130 dup2(writep[0], 0); /* Dup our write to his stdin */
133 close(readp[0]); /* Close unused child fds */
134 dup2(readp[1], 1); /* dup our read to his stdout */
135 dup2(readp[1], 2); /* and his stderr */
137 /* Note, the close log cause problems, see bug #1536 */
138 /* closelog(); close syslog if open */
139 for (i=3; i<=32; i++) { /* close any open file descriptors */
142 execvp(bargv[0], bargv); /* call the program */
143 /* Convert errno into an exit code for later analysis */
144 for (i=0; i< num_execvp_errors; i++) {
145 if (execvp_errors[i] == errno) {
146 exit(200 + i); /* exit code => errno */
149 exit(255); /* unknown errno */
151 default: /* parent */
154 free_pool_memory(tprog);
156 close(readp[1]); /* close unused parent fds */
157 bpipe->rfd = fdopen(readp[0], "r"); /* open file descriptor */
161 bpipe->wfd = fdopen(writep[1], "w");
163 bpipe->worker_stime = time(NULL);
166 bpipe->timer_id = start_child_timer(NULL, bpipe->worker_pid, wait);
171 /* Close the write pipe only */
172 int close_wpipe(BPIPE *bpipe)
178 if (fclose(bpipe->wfd) != 0) {
187 * Close both pipes and free resources
189 * Returns: 0 on success
192 int close_bpipe(BPIPE *bpipe)
211 if (bpipe->wait == 0) {
212 wait_option = 0; /* wait indefinitely */
214 wait_option = WNOHANG; /* don't hang */
216 remaining_wait = bpipe->wait;
218 /* wait for worker child to exit */
220 Dmsg2(800, "Wait for %d opt=%d\n", bpipe->worker_pid, wait_option);
222 wpid = waitpid(bpipe->worker_pid, &chldstatus, wait_option);
223 } while (wpid == -1 && (errno == EINTR || errno == EAGAIN));
224 if (wpid == bpipe->worker_pid || wpid == -1) {
227 Dmsg3(800, "Got break wpid=%d status=%d ERR=%s\n", wpid, chldstatus,
228 wpid==-1?be.bstrerror():"none");
231 Dmsg3(800, "Got wpid=%d status=%d ERR=%s\n", wpid, chldstatus,
232 wpid==-1?strerror(errno):"none");
233 if (remaining_wait > 0) {
234 bmicrosleep(1, 0); /* wait one second */
237 stat = ETIME; /* set error status */
239 break; /* don't wait any longer */
243 if (WIFEXITED(chldstatus)) { /* process exit()ed */
244 stat = WEXITSTATUS(chldstatus);
246 Dmsg1(800, "Non-zero status %d returned from child.\n", stat);
247 stat |= b_errno_exit; /* exit status returned */
249 Dmsg1(800, "child status=%d\n", stat & ~b_errno_exit);
250 } else if (WIFSIGNALED(chldstatus)) { /* process died */
252 stat = WTERMSIG(chldstatus);
254 stat = 1; /* fake child status */
256 Dmsg1(800, "Child died from signal %d\n", stat);
257 stat |= b_errno_signal; /* exit signal returned */
260 if (bpipe->timer_id) {
261 stop_child_timer(bpipe->timer_id);
264 Dmsg2(800, "returning stat=%d,%d\n", stat & ~(b_errno_exit|b_errno_signal), stat);
269 * Build argc and argv from a string
271 static void build_argc_argv(char *cmd, int *bargc, char *bargv[], int max_argv)
278 for (i=0; i<max_argv; i++)
283 while (*p && (*p == ' ' || *p == '\t'))
285 if (*p == '\"' || *p == '\'') {
290 while (*p && argc < MAX_ARGV) {
293 while (*q && *q != quote)
297 while (*q && *q != ' ')
304 while (*p && (*p == ' ' || *p == '\t'))
306 if (*p == '\"' || *p == '\'') {
314 #endif /* HAVE_WIN32 */
317 * Run an external program. Optionally wait a specified number
318 * of seconds. Program killed if wait exceeded. Optionally
319 * return the output from the program (normally a single line).
321 * If the watchdog kills the program, fgets returns, and ferror is set
322 * to 1 (=>SUCCESS), so we check if the watchdog killed the program.
324 * Contrary to my normal calling conventions, this program
326 * Returns: 0 on success
327 * non-zero on error == berrno status
329 int run_program(char *prog, int wait, POOLMEM *&results)
336 bpipe = open_bpipe(prog, wait, mode);
341 int len = sizeof_pool_memory(results) - 1;
342 fgets(results, len, bpipe->rfd);
344 if (feof(bpipe->rfd)) {
347 stat1 = ferror(bpipe->rfd);
351 Dmsg2(150, "Run program fgets stat=%d ERR=%s\n", stat1, be.bstrerror(errno));
352 } else if (stat1 != 0) {
353 Dmsg1(150, "Run program fgets stat=%d\n", stat1);
354 if (bpipe->timer_id) {
355 Dmsg1(150, "Run program fgets killed=%d\n", bpipe->timer_id->killed);
356 /* NB: I'm not sure it is really useful for run_program. Without the
357 * following lines run_program would not detect if the program was killed
358 * by the watchdog. */
359 if (bpipe->timer_id->killed) {
361 pm_strcpy(results, _("Program killed by Bacula (timeout)\n"));
365 stat2 = close_bpipe(bpipe);
366 stat1 = stat2 != 0 ? stat2 : stat1;
367 Dmsg1(150, "Run program returning %d\n", stat1);
372 * Run an external program. Optionally wait a specified number
373 * of seconds. Program killed if wait exceeded (it is done by the
374 * watchdog, as fgets is a blocking function).
376 * If the watchdog kills the program, fgets returns, and ferror is set
377 * to 1 (=>SUCCESS), so we check if the watchdog killed the program.
379 * Return the full output from the program (not only the first line).
381 * Contrary to my normal calling conventions, this program
383 * Returns: 0 on success
384 * non-zero on error == berrno status
387 int run_program_full_output(char *prog, int wait, POOLMEM *&results)
394 const int bufsize = 32000;
397 sm_check(__FILE__, __LINE__, false);
399 tmp = get_pool_memory(PM_MESSAGE);
400 buf = (char *)malloc(bufsize+1);
404 bpipe = open_bpipe(prog, wait, mode);
410 sm_check(__FILE__, __LINE__, false);
414 fgets(buf, bufsize, bpipe->rfd);
417 if (feof(bpipe->rfd)) {
419 Dmsg1(900, "Run program fgets stat=%d\n", stat1);
422 stat1 = ferror(bpipe->rfd);
426 Dmsg2(200, "Run program fgets stat=%d ERR=%s\n", stat1, be.bstrerror());
428 } else if (stat1 != 0) {
429 Dmsg1(900, "Run program fgets stat=%d\n", stat1);
430 if (bpipe->timer_id && bpipe->timer_id->killed) {
431 Dmsg1(250, "Run program saw fgets killed=%d\n", bpipe->timer_id->killed);
437 * We always check whether the timer killed the program. We would see
438 * an eof even when it does so we just have to trust the killed flag
439 * and set the timer values to avoid edge cases where the program ends
440 * just as the timer kills it.
442 if (bpipe->timer_id && bpipe->timer_id->killed) {
443 Dmsg1(150, "Run program fgets killed=%d\n", bpipe->timer_id->killed);
444 pm_strcpy(tmp, _("Program killed by Bacula (timeout)\n"));
447 pm_strcpy(results, tmp);
448 Dmsg3(1900, "resadr=0x%x reslen=%d res=%s\n", results, strlen(results), results);
449 stat2 = close_bpipe(bpipe);
450 stat1 = stat2 != 0 ? stat2 : stat1;
452 Dmsg1(900, "Run program returning %d\n", stat1);
454 free_pool_memory(tmp);