X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=bacula%2Fsrc%2Flib%2Fbpipe.c;h=0a00caf73cc53c2bc2799b16e2192239d24b6ec1;hb=28b98a207e5834c4066b6565c4210220957452e4;hp=dd3827edb64f55c06fb59299674ecb57bc6d4d1f;hpb=e0ccfdebe72875815e48f3588865fe5764ef0feb;p=bacula%2Fbacula diff --git a/bacula/src/lib/bpipe.c b/bacula/src/lib/bpipe.c index dd3827edb6..0a00caf73c 100644 --- a/bacula/src/lib/bpipe.c +++ b/bacula/src/lib/bpipe.c @@ -57,8 +57,8 @@ BPIPE *open_bpipe(char *prog, int wait, char *mode) /* Build arguments for running program. */ tprog = get_pool_memory(PM_FNAME); pm_strcpy(&tprog, prog); - build_argc_argv(tprog, &bargc, bargv, MAX_ARGV); -#ifdef xxxxxx + build_argc_argv(mp_chr(tprog), &bargc, bargv, MAX_ARGV); +#ifdef xxxxxx printf("argc=%d\n", bargc); int i; for (i=0; iworker_pid = fork()) { - case -1: + case -1: /* error */ free(bpipe); return NULL; @@ -120,6 +120,7 @@ int close_wpipe(BPIPE *bpipe) int stat = 1; if (bpipe->wfd) { + fflush(bpipe->wfd); if (fclose(bpipe->wfd) != 0) { stat = 0; } @@ -132,9 +133,11 @@ int close_wpipe(BPIPE *bpipe) int close_bpipe(BPIPE *bpipe) { int chldstatus = 0; - int stat = ETIME; + int stat = 0; int wait_option; int remaining_wait; + pid_t wpid = 0; + /* Close pipes */ if (bpipe->rfd) { @@ -155,25 +158,42 @@ int close_bpipe(BPIPE *bpipe) /* wait for worker child to exit */ for ( ;; ) { - pid_t wpid; + Dmsg2(200, "Wait for %d opt=%d\n", bpipe->worker_pid, wait_option); wpid = waitpid(bpipe->worker_pid, &chldstatus, wait_option); if (wpid == bpipe->worker_pid || (wpid == -1 && errno != EINTR)) { + Dmsg3(200, "Got break wpid=%d status=%d ERR=%s\n", wpid, chldstatus, + wpid==-1?strerror(errno):"none"); break; } + Dmsg3(200, "Got wpid=%d status=%d ERR=%s\n", wpid, chldstatus, + wpid==-1?strerror(errno):"none"); if (remaining_wait > 0) { - sleep(1); /* wait one second */ + bmicrosleep(1, 0); /* wait one second */ remaining_wait--; } else { + stat = 1; /* set error status */ + errno = ETIME; /* set timed out */ + wpid = -1; break; /* don't wait any longer */ } } - if (WIFEXITED(chldstatus)) { - stat = WEXITSTATUS(chldstatus); - } + if (wpid > 0) { + if (WIFEXITED(chldstatus)) { /* process exit()ed */ + stat = WEXITSTATUS(chldstatus); + Dmsg1(200, "status =%d\n", stat); + } else if (WIFSIGNALED(chldstatus)) { /* process died */ + stat = 1; + Dmsg0(200, "Signaled\n"); + } + if (stat != 0) { + errno = ECHILD; /* set child errno */ + } + } if (bpipe->timer_id) { stop_child_timer(bpipe->timer_id); } free(bpipe); + Dmsg1(200, "returning stat = %d\n", stat); return stat; } @@ -182,6 +202,11 @@ int close_bpipe(BPIPE *bpipe) * Run an external program. Optionally wait a specified number * of seconds. Program killed if wait exceeded. Optionally * return the output from the program (normally a single line). + * + * Contrary to my normal calling conventions, this program + * + * Returns: 0 on success + * non-zero on error */ int run_program(char *prog, int wait, POOLMEM *results) { @@ -195,13 +220,13 @@ int run_program(char *prog, int wait, POOLMEM *results) return 0; } if (results) { - results[0] = 0; - stat1 = fgets(results, sizeof_pool_memory(results), bpipe->rfd) != NULL; + mp_chr(results)[0] = 0; + stat1 = fgets(mp_chr(results), sizeof_pool_memory(results), bpipe->rfd) == NULL; } else { - stat1 = 1; + stat1 = 0; } stat2 = close_bpipe(bpipe); - return stat1 && stat2; + return stat2 != 0 ? stat2 : stat1; } @@ -210,8 +235,8 @@ int run_program(char *prog, int wait, POOLMEM *results) */ static void build_argc_argv(char *cmd, int *bargc, char *bargv[], int max_argv) { - int i, quote; - char *p, *q; + int i; + char *p, *q, quote; int argc = 0; argc = 0; @@ -222,15 +247,15 @@ static void build_argc_argv(char *cmd, int *bargc, char *bargv[], int max_argv) quote = 0; while (*p && (*p == ' ' || *p == '\t')) p++; - if (*p == '\"') { - quote = 1; + if (*p == '\"' || *p == '\'') { + quote = *p; p++; } if (*p) { while (*p && argc < MAX_ARGV) { q = p; if (quote) { - while (*q && *q != '\"') + while (*q && *q != quote) q++; quote = 0; } else { @@ -243,8 +268,8 @@ static void build_argc_argv(char *cmd, int *bargc, char *bargv[], int max_argv) p = q; while (*p && (*p == ' ' || *p == '\t')) p++; - if (*p == '\"') { - quote = 1; + if (*p == '\"' || *p == '\'') { + quote = *p; p++; } }