[BACK]Return to cmd_exec.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / make

Diff for /src/usr.bin/make/cmd_exec.c between version 1.5 and 1.6

version 1.5, 2004/04/07 13:11:35 version 1.6, 2007/07/24 21:09:07
Line 40 
Line 40 
 char *  char *
 Cmd_Exec(const char *cmd, char **err)  Cmd_Exec(const char *cmd, char **err)
 {  {
     char        *args[4];       /* Args for invoking the shell */          char    *args[4];       /* Args for invoking the shell */
     int         fds[2];         /* Pipe streams */          int     fds[2];         /* Pipe streams */
     pid_t       cpid;           /* Child PID */          pid_t   cpid;           /* Child PID */
     pid_t       pid;            /* PID from wait() */          pid_t   pid;            /* PID from wait() */
     char        *result;        /* Result */          char    *result;        /* Result */
     int         status;         /* Command exit status */          int     status;         /* Command exit status */
     BUFFER      buf;            /* Buffer to store the result. */          BUFFER  buf;            /* Buffer to store the result. */
     char        *cp;            /* Pointer into result. */          char    *cp;            /* Pointer into result. */
     ssize_t     cc;             /* Characters read from pipe. */          ssize_t cc;             /* Characters read from pipe. */
     size_t      length;         /* Total length of result. */          size_t  length;         /* Total length of result. */
   
   
     *err = NULL;          *err = NULL;
   
     /* Set up arguments for the shell. */          /* Set up arguments for the shell. */
     args[0] = "sh";          args[0] = "sh";
     args[1] = "-c";          args[1] = "-c";
     args[2] = (char *)cmd;          args[2] = (char *)cmd;
     args[3] = NULL;          args[3] = NULL;
   
     /* Open a pipe for retrieving shell's output. */          /* Open a pipe for retrieving shell's output. */
     if (pipe(fds) == -1) {          if (pipe(fds) == -1) {
         *err = "Couldn't create pipe for \"%s\"";                  *err = "Couldn't create pipe for \"%s\"";
         goto bad;                  goto bad;
     }          }
   
     /* Fork */          /* Fork */
     switch (cpid = fork()) {          switch (cpid = fork()) {
     case 0:          case 0:
         /* Close input side of pipe */                  /* Close input side of pipe */
         (void)close(fds[0]);                  (void)close(fds[0]);
   
         /* Duplicate the output stream to the shell's output, then                  /* Duplicate the output stream to the shell's output, then
          * shut the extra thing down. Note we don't fetch the error                   * shut the extra thing down. Note we don't fetch the error
          * stream: user can use redirection to grab it as this goes                   * stream: user can use redirection to grab it as this goes
          * through /bin/sh.                   * through /bin/sh.
          */                   */
         if (fds[1] != 1) {                  if (fds[1] != 1) {
             (void)dup2(fds[1], 1);                          (void)dup2(fds[1], 1);
             (void)close(fds[1]);                          (void)close(fds[1]);
         }                  }
   
         (void)execv(_PATH_BSHELL, args);                  (void)execv(_PATH_BSHELL, args);
         _exit(1);                  _exit(1);
         /*NOTREACHED*/                  /*NOTREACHED*/
   
     case -1:          case -1:
         *err = "Couldn't exec \"%s\"";                  *err = "Couldn't exec \"%s\"";
         goto bad;                  goto bad;
   
     default:          default:
         /* No need for the writing half. */                  /* No need for the writing half. */
         (void)close(fds[1]);                  (void)close(fds[1]);
   
         Buf_Init(&buf, MAKE_BSIZE);                  Buf_Init(&buf, MAKE_BSIZE);
   
         do {                  do {
             char   grab[BUFSIZ];                          char   grab[BUFSIZ];
   
             cc = read(fds[0], grab, sizeof(grab));                          cc = read(fds[0], grab, sizeof(grab));
             if (cc > 0)                          if (cc > 0)
                 Buf_AddChars(&buf, cc, grab);                                  Buf_AddChars(&buf, cc, grab);
         }                  } while (cc > 0 || (cc == -1 && errno == EINTR));
         while (cc > 0 || (cc == -1 && errno == EINTR));  
   
         /* Close the input side of the pipe.  */                  /* Close the input side of the pipe.  */
         (void)close(fds[0]);                  (void)close(fds[0]);
   
         /* Wait for the child to exit.  */                  /* Wait for the child to exit.  */
         while ((pid = wait(&status)) != cpid && pid >= 0)                  while ((pid = wait(&status)) != cpid && pid >= 0)
             continue;                          continue;
   
         if (cc == -1)                  if (cc == -1)
             *err = "Couldn't read shell's output for \"%s\"";                          *err = "Couldn't read shell's output for \"%s\"";
   
         if (status)                  if (status)
             *err = "\"%s\" returned non-zero status";                          *err = "\"%s\" returned non-zero status";
   
         length = Buf_Size(&buf);                  length = Buf_Size(&buf);
         result = Buf_Retrieve(&buf);                  result = Buf_Retrieve(&buf);
   
         /* The result is null terminated, Convert newlines to spaces. */                  /* The result is null terminated, Convert newlines to spaces. */
         cp = result + length - 1;                  cp = result + length - 1;
   
         if (cp >= result && *cp == '\n')                  if (cp >= result && *cp == '\n')
             /* A final newline is just stripped.  */                          /* A final newline is just stripped.  */
             *cp-- = '\0';                          *cp-- = '\0';
   
         while (cp >= result) {                  while (cp >= result) {
             if (*cp == '\n')                          if (*cp == '\n')
                 *cp = ' ';                                  *cp = ' ';
             cp--;                          cp--;
                   }
                   break;
         }          }
         break;          return result;
     }      bad:
     return result;          return estrdup("");
 bad:  
     return estrdup("");  
 }  }
   

Legend:
Removed from v.1.5  
changed lines
  Added in v.1.6