]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/lib/bpipe.c
Add new hash table class
[bacula/bacula] / bacula / src / lib / bpipe.c
index dd3827edb64f55c06fb59299674ecb57bc6d4d1f..0a00caf73cc53c2bc2799b16e2192239d24b6ec1 100644 (file)
@@ -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; i<bargc; i++) {
@@ -78,7 +78,7 @@ BPIPE *open_bpipe(char *prog, int wait, char *mode)
    }
    /* Start worker process */
    switch (bpipe->worker_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++;
         }
       }