]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/lib/bpipe.c
This commit was manufactured by cvs2svn to create tag
[bacula/bacula] / bacula / src / lib / bpipe.c
index 1501e18d2c41fd4b8333e709ebaaf5591e2c69b7..6955aa650e0899838401f1d6b02be79fbec2687a 100644 (file)
@@ -7,7 +7,7 @@
  */
 
 /*
-   Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
+   Copyright (C) 2002-2004 Kern Sibbald and John Walker
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License as
@@ -41,10 +41,10 @@ static void build_argc_argv(char *cmd, int *bargc, char *bargv[], int max_arg);
  *   a bi-directional pipe so that the user can read from and
  *   write to the program. 
  */
-BPIPE *open_bpipe(char *prog, int wait, char *mode)
+BPIPE *open_bpipe(char *prog, int wait, const char *mode)
 {
    char *bargv[MAX_ARGV];
-   int bargc;
+   int bargc, i;
    int readp[2], writep[2];
    POOLMEM *tprog;
    int mode_read, mode_write;
@@ -60,7 +60,6 @@ BPIPE *open_bpipe(char *prog, int wait, char *mode)
    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++) {
       printf("argc=%d argv=%s:\n", i, bargv[i]);
    }
@@ -73,12 +72,24 @@ BPIPE *open_bpipe(char *prog, int wait, char *mode)
       return NULL;
    }
    if (mode_read && pipe(readp) == -1) {
+      if (mode_write) {
+        close(writep[0]);
+        close(writep[1]);
+      }
       free(bpipe);
       return NULL;
    }
    /* Start worker process */
    switch (bpipe->worker_pid = fork()) {
    case -1:                          /* error */
+      if (mode_write) {
+        close(writep[0]);
+        close(writep[1]);
+      }
+      if (mode_read) {
+        close(readp[0]);
+        close(readp[1]);
+      }
       free(bpipe);
       return NULL;
 
@@ -92,7 +103,8 @@ BPIPE *open_bpipe(char *prog, int wait, char *mode)
         dup2(readp[1], 1);           /* dup our read to his stdout */
         dup2(readp[1], 2);           /*   and his stderr */
       }
-      for (int i=3; i<=32; i++) {     /* close any open file descriptors */
+      closelog();                    /* close syslog if open */
+      for (i=3; i<=32; i++) {        /* close any open file descriptors */
         close(i);
       }
       execvp(bargv[0], bargv);       /* call the program */
@@ -132,7 +144,12 @@ int close_wpipe(BPIPE *bpipe)
    return stat;
 }
 
-/* Close both pipes and free resources */
+/* 
+ * Close both pipes and free resources  
+ *
+ *  Returns: 0 on success
+ *          errno on failure
+ */
 int close_bpipe(BPIPE *bpipe) 
 {
    int chldstatus = 0;
@@ -176,8 +193,7 @@ int close_bpipe(BPIPE *bpipe)
         bmicrosleep(1, 0);            /* wait one second */
         remaining_wait--;
       } else {
-        stat = 1;                    /* set error status */
-        errno = ETIME;               /* set timed out */
+        stat = ETIME;                /* set error status */
         wpid = -1;
          break;                       /* don't wait any longer */
       }
@@ -185,14 +201,15 @@ int close_bpipe(BPIPE *bpipe)
    if (wpid > 0) {
       if (WIFEXITED(chldstatus)) {          /* process exit()ed */
         stat = WEXITSTATUS(chldstatus);
-          Dmsg1(200, "status =%d\n", stat);
+        if (stat != 0) {
+            Dmsg1(100, "Non-zero status %s returned from child.\n", stat);
+           stat = ECHILD;
+        }
+         Dmsg1(200, "child status=%d\n", stat);
       } else if (WIFSIGNALED(chldstatus)) {  /* process died */
-        stat = 1;
+        stat = ECHILD;
          Dmsg0(200, "Signaled\n");
       }
-      if (stat != 0) {
-        errno = ECHILD;              /* set child errno */
-      }
    }  
    if (bpipe->timer_id) {
       stop_child_timer(bpipe->timer_id);
@@ -211,7 +228,7 @@ int close_bpipe(BPIPE *bpipe)
  * Contrary to my normal calling conventions, this program 
  *
  *  Returns: 0 on success
- *          non-zero on error
+ *          non-zero on error == errno
  */
 int run_program(char *prog, int wait, POOLMEM *results)
 {
@@ -222,16 +239,28 @@ int run_program(char *prog, int wait, POOLMEM *results)
    mode = (char *)(results != NULL ? "r" : "");
    bpipe = open_bpipe(prog, wait, mode);
    if (!bpipe) {
-      return 0;
+      return ENOENT;
    }
    if (results) {
       mp_chr(results)[0] = 0;
-      stat1 = fgets(mp_chr(results), sizeof_pool_memory(results), bpipe->rfd) == NULL;
+      fgets(mp_chr(results), sizeof_pool_memory(results), bpipe->rfd);       
+      if (feof(bpipe->rfd)) {
+        stat1 = 0;
+      } else {
+        stat1 = ferror(bpipe->rfd);
+      }
+      if (stat1 < 0) {
+         Dmsg2(100, "Run program fgets stat=%d ERR=%s\n", stat1, strerror(errno));
+      } else if (stat1 != 0) {
+         Dmsg1(100, "Run program fgets stat=%d\n", stat1);
+      }
    } else {
       stat1 = 0;
    }
    stat2 = close_bpipe(bpipe);
-   return stat2 != 0 ? stat2 : stat1; 
+   stat1 = stat2 != 0 ? stat2 : stat1;
+   Dmsg1(100, "Run program returning %d\n", stat1);
+   return stat1;
 }