Merge branch 'sb/run-command-fd-error-reporting'
authorJunio C Hamano <gitster@pobox.com>
Thu, 7 Feb 2013 22:41:42 +0000 (14:41 -0800)
committerJunio C Hamano <gitster@pobox.com>
Thu, 7 Feb 2013 22:41:42 +0000 (14:41 -0800)
* sb/run-command-fd-error-reporting:
run-command: be more informative about what failed

1  2 
run-command.c
diff --combined run-command.c
index 12d4ddb552204ba010ac90f24429d81a74e78a4e,ec1a664755bb70e049259ced0917ee0ce2082d71..07e27ff4c829bf4e5dffbc61ac4f86f757e121c4
@@@ -226,7 -226,7 +226,7 @@@ static inline void set_cloexec(int fd
                fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
  }
  
 -static int wait_or_whine(pid_t pid, const char *argv0, int silent_exec_failure)
 +static int wait_or_whine(pid_t pid, const char *argv0)
  {
        int status, code = -1;
        pid_t waiting;
                error("waitpid is confused (%s)", argv0);
        } else if (WIFSIGNALED(status)) {
                code = WTERMSIG(status);
 -              error("%s died of signal %d", argv0, code);
 +              if (code != SIGINT && code != SIGQUIT)
 +                      error("%s died of signal %d", argv0, code);
                /*
                 * This return value is chosen so that code & 0xff
                 * mimics the exit code that a POSIX shell would report for
                 * a program that died from this signal.
                 */
 -              code -= 128;
 +              code += 128;
        } else if (WIFEXITED(status)) {
                code = WEXITSTATUS(status);
                /*
@@@ -274,6 -273,7 +274,7 @@@ int start_command(struct child_process 
        int need_in, need_out, need_err;
        int fdin[2], fdout[2], fderr[2];
        int failed_errno = failed_errno;
+       char *str;
  
        /*
         * In case of errors we must keep the promise to close FDs
                        failed_errno = errno;
                        if (cmd->out > 0)
                                close(cmd->out);
+                       str = "standard input";
                        goto fail_pipe;
                }
                cmd->in = fdin[1];
                                close_pair(fdin);
                        else if (cmd->in)
                                close(cmd->in);
+                       str = "standard output";
                        goto fail_pipe;
                }
                cmd->out = fdout[0];
                                close_pair(fdout);
                        else if (cmd->out)
                                close(cmd->out);
+                       str = "standard error";
  fail_pipe:
-                       error("cannot create pipe for %s: %s",
-                               cmd->argv[0], strerror(failed_errno));
+                       error("cannot create %s pipe for %s: %s",
+                               str, cmd->argv[0], strerror(failed_errno));
                        errno = failed_errno;
                        return -1;
                }
                                        unsetenv(*cmd->env);
                        }
                }
 -              if (cmd->preexec_cb) {
 -                      /*
 -                       * We cannot predict what the pre-exec callback does.
 -                       * Forgo parent notification.
 -                       */
 -                      close(child_notifier);
 -                      child_notifier = -1;
 -
 -                      cmd->preexec_cb();
 -              }
                if (cmd->git_cmd) {
                        execv_git_cmd(cmd->argv);
                } else if (cmd->use_shell) {
                 * At this point we know that fork() succeeded, but execvp()
                 * failed. Errors have been reported to our stderr.
                 */
 -              wait_or_whine(cmd->pid, cmd->argv[0],
 -                            cmd->silent_exec_failure);
 +              wait_or_whine(cmd->pid, cmd->argv[0]);
                failed_errno = errno;
                cmd->pid = -1;
        }
  
  int finish_command(struct child_process *cmd)
  {
 -      return wait_or_whine(cmd->pid, cmd->argv[0], cmd->silent_exec_failure);
 +      return wait_or_whine(cmd->pid, cmd->argv[0]);
  }
  
  int run_command(struct child_process *cmd)
@@@ -725,7 -739,7 +729,7 @@@ error
  int finish_async(struct async *async)
  {
  #ifdef NO_PTHREADS
 -      return wait_or_whine(async->pid, "child process", 0);
 +      return wait_or_whine(async->pid, "child process");
  #else
        void *ret = (void *)(intptr_t)(-1);
  
  #endif
  }
  
 +char *find_hook(const char *name)
 +{
 +      char *path = git_path("hooks/%s", name);
 +      if (access(path, X_OK) < 0)
 +              path = NULL;
 +
 +      return path;
 +}
 +
  int run_hook(const char *index_file, const char *name, ...)
  {
        struct child_process hook;
        va_list args;
        int ret;
  
 -      if (access(git_path("hooks/%s", name), X_OK) < 0)
 +      p = find_hook(name);
 +      if (!p)
                return 0;
  
 +      argv_array_push(&argv, p);
 +
        va_start(args, name);
 -      argv_array_push(&argv, git_path("hooks/%s", name));
        while ((p = va_arg(args, const char *)))
                argv_array_push(&argv, p);
        va_end(args);