2 Bacula® - The Network Backup Solution
4 Copyright (C) 2002-2008 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 two of the GNU 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 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
40 int execvp_errors[] = {
53 int num_execvp_errors = (int)(sizeof(execvp_errors)/sizeof(int));
58 #if !defined(HAVE_WIN32)
59 static void build_argc_argv(char *cmd, int *bargc, char *bargv[], int max_arg);
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)
69 char *bargv[MAX_ARGV];
71 int readp[2], writep[2];
73 int mode_read, mode_write;
77 bpipe = (BPIPE *)malloc(sizeof(BPIPE));
78 memset(bpipe, 0, sizeof(BPIPE));
79 mode_read = (mode[0] == 'r');
80 mode_write = (mode[0] == 'w' || mode[1] == 'w');
81 /* Build arguments for running program. */
82 tprog = get_pool_memory(PM_FNAME);
83 pm_strcpy(tprog, prog);
84 build_argc_argv(tprog, &bargc, bargv, MAX_ARGV);
86 printf("argc=%d\n", bargc);
87 for (i=0; i<bargc; i++) {
88 printf("argc=%d argv=%s:\n", i, bargv[i]);
92 /* Each pipe is one way, write one end, read the other, so we need two */
93 if (mode_write && pipe(writep) == -1) {
96 free_pool_memory(tprog);
100 if (mode_read && pipe(readp) == -1) {
107 free_pool_memory(tprog);
111 /* Start worker process */
112 switch (bpipe->worker_pid = fork()) {
124 free_pool_memory(tprog);
131 dup2(writep[0], 0); /* Dup our write to his stdin */
134 close(readp[0]); /* Close unused child fds */
135 dup2(readp[1], 1); /* dup our read to his stdout */
136 dup2(readp[1], 2); /* and his stderr */
138 /* Note, the close log cause problems, see bug #1536 */
139 /* closelog(); close syslog if open */
140 for (i=3; i<=32; i++) { /* close any open file descriptors */
143 execvp(bargv[0], bargv); /* call the program */
144 /* Convert errno into an exit code for later analysis */
145 for (i=0; i< num_execvp_errors; i++) {
146 if (execvp_errors[i] == errno) {
147 exit(200 + i); /* exit code => errno */
150 exit(255); /* unknown errno */
152 default: /* parent */
155 free_pool_memory(tprog);
157 close(readp[1]); /* close unused parent fds */
158 bpipe->rfd = fdopen(readp[0], "r"); /* open file descriptor */
162 bpipe->wfd = fdopen(writep[1], "w");
164 bpipe->worker_stime = time(NULL);
167 bpipe->timer_id = start_child_timer(NULL, bpipe->worker_pid, wait);
172 /* Close the write pipe only */
173 int close_wpipe(BPIPE *bpipe)
179 if (fclose(bpipe->wfd) != 0) {
188 * Close both pipes and free resources
190 * Returns: 0 on success
193 int close_bpipe(BPIPE *bpipe)
212 if (bpipe->wait == 0) {
213 wait_option = 0; /* wait indefinitely */
215 wait_option = WNOHANG; /* don't hang */
217 remaining_wait = bpipe->wait;
219 /* wait for worker child to exit */
221 Dmsg2(800, "Wait for %d opt=%d\n", bpipe->worker_pid, wait_option);
223 wpid = waitpid(bpipe->worker_pid, &chldstatus, wait_option);
224 } while (wpid == -1 && (errno == EINTR || errno == EAGAIN));
225 if (wpid == bpipe->worker_pid || wpid == -1) {
228 Dmsg3(800, "Got break wpid=%d status=%d ERR=%s\n", wpid, chldstatus,
229 wpid==-1?be.bstrerror():"none");
232 Dmsg3(800, "Got wpid=%d status=%d ERR=%s\n", wpid, chldstatus,
233 wpid==-1?strerror(errno):"none");
234 if (remaining_wait > 0) {
235 bmicrosleep(1, 0); /* wait one second */
238 stat = ETIME; /* set error status */
240 break; /* don't wait any longer */
244 if (WIFEXITED(chldstatus)) { /* process exit()ed */
245 stat = WEXITSTATUS(chldstatus);
247 Dmsg1(800, "Non-zero status %d returned from child.\n", stat);
248 stat |= b_errno_exit; /* exit status returned */
250 Dmsg1(800, "child status=%d\n", stat & ~b_errno_exit);
251 } else if (WIFSIGNALED(chldstatus)) { /* process died */
253 stat = WTERMSIG(chldstatus);
255 stat = 1; /* fake child status */
257 Dmsg1(800, "Child died from signal %d\n", stat);
258 stat |= b_errno_signal; /* exit signal returned */
261 if (bpipe->timer_id) {
262 stop_child_timer(bpipe->timer_id);
265 Dmsg2(800, "returning stat=%d,%d\n", stat & ~(b_errno_exit|b_errno_signal), stat);
270 * Build argc and argv from a string
272 static void build_argc_argv(char *cmd, int *bargc, char *bargv[], int max_argv)
279 for (i=0; i<max_argv; i++)
284 while (*p && (*p == ' ' || *p == '\t'))
286 if (*p == '\"' || *p == '\'') {
291 while (*p && argc < MAX_ARGV) {
294 while (*q && *q != quote)
298 while (*q && *q != ' ')
305 while (*p && (*p == ' ' || *p == '\t'))
307 if (*p == '\"' || *p == '\'') {
315 #endif /* HAVE_WIN32 */
318 * Run an external program. Optionally wait a specified number
319 * of seconds. Program killed if wait exceeded. Optionally
320 * return the output from the program (normally a single line).
322 * If the watchdog kills the program, fgets returns, and ferror is set
323 * to 1 (=>SUCCESS), so we check if the watchdog killed the program.
325 * Contrary to my normal calling conventions, this program
327 * Returns: 0 on success
328 * non-zero on error == berrno status
330 int run_program(char *prog, int wait, POOLMEM *&results)
337 bpipe = open_bpipe(prog, wait, mode);
342 int len = sizeof_pool_memory(results) - 1;
343 fgets(results, len, bpipe->rfd);
345 if (feof(bpipe->rfd)) {
348 stat1 = ferror(bpipe->rfd);
352 Dmsg2(150, "Run program fgets stat=%d ERR=%s\n", stat1, be.bstrerror(errno));
353 } else if (stat1 != 0) {
354 Dmsg1(150, "Run program fgets stat=%d\n", stat1);
355 if (bpipe->timer_id) {
356 Dmsg1(150, "Run program fgets killed=%d\n", bpipe->timer_id->killed);
357 /* NB: I'm not sure it is really useful for run_program. Without the
358 * following lines run_program would not detect if the program was killed
359 * by the watchdog. */
360 if (bpipe->timer_id->killed) {
362 pm_strcpy(results, _("Program killed by Bacula (timeout)\n"));
366 stat2 = close_bpipe(bpipe);
367 stat1 = stat2 != 0 ? stat2 : stat1;
368 Dmsg1(150, "Run program returning %d\n", stat1);
373 * Run an external program. Optionally wait a specified number
374 * of seconds. Program killed if wait exceeded (it is done by the
375 * watchdog, as fgets is a blocking function).
377 * If the watchdog kills the program, fgets returns, and ferror is set
378 * to 1 (=>SUCCESS), so we check if the watchdog killed the program.
380 * Return the full output from the program (not only the first line).
382 * Contrary to my normal calling conventions, this program
384 * Returns: 0 on success
385 * non-zero on error == berrno status
388 int run_program_full_output(char *prog, int wait, POOLMEM *&results)
395 const int bufsize = 32000;
398 sm_check(__FILE__, __LINE__, false);
400 tmp = get_pool_memory(PM_MESSAGE);
401 buf = (char *)malloc(bufsize+1);
405 bpipe = open_bpipe(prog, wait, mode);
411 sm_check(__FILE__, __LINE__, false);
415 fgets(buf, bufsize, bpipe->rfd);
418 if (feof(bpipe->rfd)) {
420 Dmsg1(900, "Run program fgets stat=%d\n", stat1);
423 stat1 = ferror(bpipe->rfd);
427 Dmsg2(200, "Run program fgets stat=%d ERR=%s\n", stat1, be.bstrerror());
429 } else if (stat1 != 0) {
430 Dmsg1(900, "Run program fgets stat=%d\n", stat1);
431 if (bpipe->timer_id && bpipe->timer_id->killed) {
432 Dmsg1(250, "Run program saw fgets killed=%d\n", bpipe->timer_id->killed);
438 * We always check whether the timer killed the program. We would see
439 * an eof even when it does so we just have to trust the killed flag
440 * and set the timer values to avoid edge cases where the program ends
441 * just as the timer kills it.
443 if (bpipe->timer_id && bpipe->timer_id->killed) {
444 Dmsg1(150, "Run program fgets killed=%d\n", bpipe->timer_id->killed);
445 pm_strcpy(tmp, _("Program killed by Bacula (timeout)\n"));
448 pm_strcpy(results, tmp);
449 Dmsg3(1900, "resadr=0x%x reslen=%d res=%s\n", results, strlen(results), results);
450 stat2 = close_bpipe(bpipe);
451 stat1 = stat2 != 0 ? stat2 : stat1;
453 Dmsg1(900, "Run program returning %d\n", stat1);
455 free_pool_memory(tmp);