run-command.con commit Merge branch 'po/doc-status-markup' (f35a02b)
   1#include "cache.h"
   2#include "run-command.h"
   3#include "exec_cmd.h"
   4#include "sigchain.h"
   5#include "argv-array.h"
   6
   7#ifndef SHELL_PATH
   8# define SHELL_PATH "/bin/sh"
   9#endif
  10
  11void child_process_init(struct child_process *child)
  12{
  13        memset(child, 0, sizeof(*child));
  14        argv_array_init(&child->args);
  15}
  16
  17struct child_to_clean {
  18        pid_t pid;
  19        struct child_to_clean *next;
  20};
  21static struct child_to_clean *children_to_clean;
  22static int installed_child_cleanup_handler;
  23
  24static void cleanup_children(int sig)
  25{
  26        while (children_to_clean) {
  27                struct child_to_clean *p = children_to_clean;
  28                children_to_clean = p->next;
  29                kill(p->pid, sig);
  30                free(p);
  31        }
  32}
  33
  34static void cleanup_children_on_signal(int sig)
  35{
  36        cleanup_children(sig);
  37        sigchain_pop(sig);
  38        raise(sig);
  39}
  40
  41static void cleanup_children_on_exit(void)
  42{
  43        cleanup_children(SIGTERM);
  44}
  45
  46static void mark_child_for_cleanup(pid_t pid)
  47{
  48        struct child_to_clean *p = xmalloc(sizeof(*p));
  49        p->pid = pid;
  50        p->next = children_to_clean;
  51        children_to_clean = p;
  52
  53        if (!installed_child_cleanup_handler) {
  54                atexit(cleanup_children_on_exit);
  55                sigchain_push_common(cleanup_children_on_signal);
  56                installed_child_cleanup_handler = 1;
  57        }
  58}
  59
  60static void clear_child_for_cleanup(pid_t pid)
  61{
  62        struct child_to_clean **pp;
  63
  64        for (pp = &children_to_clean; *pp; pp = &(*pp)->next) {
  65                struct child_to_clean *clean_me = *pp;
  66
  67                if (clean_me->pid == pid) {
  68                        *pp = clean_me->next;
  69                        free(clean_me);
  70                        return;
  71                }
  72        }
  73}
  74
  75static inline void close_pair(int fd[2])
  76{
  77        close(fd[0]);
  78        close(fd[1]);
  79}
  80
  81#ifndef GIT_WINDOWS_NATIVE
  82static inline void dup_devnull(int to)
  83{
  84        int fd = open("/dev/null", O_RDWR);
  85        if (fd < 0)
  86                die_errno(_("open /dev/null failed"));
  87        if (dup2(fd, to) < 0)
  88                die_errno(_("dup2(%d,%d) failed"), fd, to);
  89        close(fd);
  90}
  91#endif
  92
  93static char *locate_in_PATH(const char *file)
  94{
  95        const char *p = getenv("PATH");
  96        struct strbuf buf = STRBUF_INIT;
  97
  98        if (!p || !*p)
  99                return NULL;
 100
 101        while (1) {
 102                const char *end = strchrnul(p, ':');
 103
 104                strbuf_reset(&buf);
 105
 106                /* POSIX specifies an empty entry as the current directory. */
 107                if (end != p) {
 108                        strbuf_add(&buf, p, end - p);
 109                        strbuf_addch(&buf, '/');
 110                }
 111                strbuf_addstr(&buf, file);
 112
 113                if (!access(buf.buf, F_OK))
 114                        return strbuf_detach(&buf, NULL);
 115
 116                if (!*end)
 117                        break;
 118                p = end + 1;
 119        }
 120
 121        strbuf_release(&buf);
 122        return NULL;
 123}
 124
 125static int exists_in_PATH(const char *file)
 126{
 127        char *r = locate_in_PATH(file);
 128        free(r);
 129        return r != NULL;
 130}
 131
 132int sane_execvp(const char *file, char * const argv[])
 133{
 134        if (!execvp(file, argv))
 135                return 0; /* cannot happen ;-) */
 136
 137        /*
 138         * When a command can't be found because one of the directories
 139         * listed in $PATH is unsearchable, execvp reports EACCES, but
 140         * careful usability testing (read: analysis of occasional bug
 141         * reports) reveals that "No such file or directory" is more
 142         * intuitive.
 143         *
 144         * We avoid commands with "/", because execvp will not do $PATH
 145         * lookups in that case.
 146         *
 147         * The reassignment of EACCES to errno looks like a no-op below,
 148         * but we need to protect against exists_in_PATH overwriting errno.
 149         */
 150        if (errno == EACCES && !strchr(file, '/'))
 151                errno = exists_in_PATH(file) ? EACCES : ENOENT;
 152        else if (errno == ENOTDIR && !strchr(file, '/'))
 153                errno = ENOENT;
 154        return -1;
 155}
 156
 157static const char **prepare_shell_cmd(const char **argv)
 158{
 159        int argc, nargc = 0;
 160        const char **nargv;
 161
 162        for (argc = 0; argv[argc]; argc++)
 163                ; /* just counting */
 164        /* +1 for NULL, +3 for "sh -c" plus extra $0 */
 165        nargv = xmalloc(sizeof(*nargv) * (argc + 1 + 3));
 166
 167        if (argc < 1)
 168                die("BUG: shell command is empty");
 169
 170        if (strcspn(argv[0], "|&;<>()$`\\\"' \t\n*?[#~=%") != strlen(argv[0])) {
 171#ifndef GIT_WINDOWS_NATIVE
 172                nargv[nargc++] = SHELL_PATH;
 173#else
 174                nargv[nargc++] = "sh";
 175#endif
 176                nargv[nargc++] = "-c";
 177
 178                if (argc < 2)
 179                        nargv[nargc++] = argv[0];
 180                else {
 181                        struct strbuf arg0 = STRBUF_INIT;
 182                        strbuf_addf(&arg0, "%s \"$@\"", argv[0]);
 183                        nargv[nargc++] = strbuf_detach(&arg0, NULL);
 184                }
 185        }
 186
 187        for (argc = 0; argv[argc]; argc++)
 188                nargv[nargc++] = argv[argc];
 189        nargv[nargc] = NULL;
 190
 191        return nargv;
 192}
 193
 194#ifndef GIT_WINDOWS_NATIVE
 195static int execv_shell_cmd(const char **argv)
 196{
 197        const char **nargv = prepare_shell_cmd(argv);
 198        trace_argv_printf(nargv, "trace: exec:");
 199        sane_execvp(nargv[0], (char **)nargv);
 200        free(nargv);
 201        return -1;
 202}
 203#endif
 204
 205#ifndef GIT_WINDOWS_NATIVE
 206static int child_err = 2;
 207static int child_notifier = -1;
 208
 209static void notify_parent(void)
 210{
 211        /*
 212         * execvp failed.  If possible, we'd like to let start_command
 213         * know, so failures like ENOENT can be handled right away; but
 214         * otherwise, finish_command will still report the error.
 215         */
 216        xwrite(child_notifier, "", 1);
 217}
 218
 219static NORETURN void die_child(const char *err, va_list params)
 220{
 221        vwritef(child_err, "fatal: ", err, params);
 222        exit(128);
 223}
 224
 225static void error_child(const char *err, va_list params)
 226{
 227        vwritef(child_err, "error: ", err, params);
 228}
 229#endif
 230
 231static inline void set_cloexec(int fd)
 232{
 233        int flags = fcntl(fd, F_GETFD);
 234        if (flags >= 0)
 235                fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
 236}
 237
 238static int wait_or_whine(pid_t pid, const char *argv0)
 239{
 240        int status, code = -1;
 241        pid_t waiting;
 242        int failed_errno = 0;
 243
 244        while ((waiting = waitpid(pid, &status, 0)) < 0 && errno == EINTR)
 245                ;       /* nothing */
 246
 247        if (waiting < 0) {
 248                failed_errno = errno;
 249                error("waitpid for %s failed: %s", argv0, strerror(errno));
 250        } else if (waiting != pid) {
 251                error("waitpid is confused (%s)", argv0);
 252        } else if (WIFSIGNALED(status)) {
 253                code = WTERMSIG(status);
 254                if (code != SIGINT && code != SIGQUIT)
 255                        error("%s died of signal %d", argv0, code);
 256                /*
 257                 * This return value is chosen so that code & 0xff
 258                 * mimics the exit code that a POSIX shell would report for
 259                 * a program that died from this signal.
 260                 */
 261                code += 128;
 262        } else if (WIFEXITED(status)) {
 263                code = WEXITSTATUS(status);
 264                /*
 265                 * Convert special exit code when execvp failed.
 266                 */
 267                if (code == 127) {
 268                        code = -1;
 269                        failed_errno = ENOENT;
 270                }
 271        } else {
 272                error("waitpid is confused (%s)", argv0);
 273        }
 274
 275        clear_child_for_cleanup(pid);
 276
 277        errno = failed_errno;
 278        return code;
 279}
 280
 281int start_command(struct child_process *cmd)
 282{
 283        int need_in, need_out, need_err;
 284        int fdin[2], fdout[2], fderr[2];
 285        int failed_errno;
 286        char *str;
 287
 288        if (!cmd->argv)
 289                cmd->argv = cmd->args.argv;
 290
 291        /*
 292         * In case of errors we must keep the promise to close FDs
 293         * that have been passed in via ->in and ->out.
 294         */
 295
 296        need_in = !cmd->no_stdin && cmd->in < 0;
 297        if (need_in) {
 298                if (pipe(fdin) < 0) {
 299                        failed_errno = errno;
 300                        if (cmd->out > 0)
 301                                close(cmd->out);
 302                        str = "standard input";
 303                        goto fail_pipe;
 304                }
 305                cmd->in = fdin[1];
 306        }
 307
 308        need_out = !cmd->no_stdout
 309                && !cmd->stdout_to_stderr
 310                && cmd->out < 0;
 311        if (need_out) {
 312                if (pipe(fdout) < 0) {
 313                        failed_errno = errno;
 314                        if (need_in)
 315                                close_pair(fdin);
 316                        else if (cmd->in)
 317                                close(cmd->in);
 318                        str = "standard output";
 319                        goto fail_pipe;
 320                }
 321                cmd->out = fdout[0];
 322        }
 323
 324        need_err = !cmd->no_stderr && cmd->err < 0;
 325        if (need_err) {
 326                if (pipe(fderr) < 0) {
 327                        failed_errno = errno;
 328                        if (need_in)
 329                                close_pair(fdin);
 330                        else if (cmd->in)
 331                                close(cmd->in);
 332                        if (need_out)
 333                                close_pair(fdout);
 334                        else if (cmd->out)
 335                                close(cmd->out);
 336                        str = "standard error";
 337fail_pipe:
 338                        error("cannot create %s pipe for %s: %s",
 339                                str, cmd->argv[0], strerror(failed_errno));
 340                        argv_array_clear(&cmd->args);
 341                        errno = failed_errno;
 342                        return -1;
 343                }
 344                cmd->err = fderr[0];
 345        }
 346
 347        trace_argv_printf(cmd->argv, "trace: run_command:");
 348        fflush(NULL);
 349
 350#ifndef GIT_WINDOWS_NATIVE
 351{
 352        int notify_pipe[2];
 353        if (pipe(notify_pipe))
 354                notify_pipe[0] = notify_pipe[1] = -1;
 355
 356        cmd->pid = fork();
 357        failed_errno = errno;
 358        if (!cmd->pid) {
 359                /*
 360                 * Redirect the channel to write syscall error messages to
 361                 * before redirecting the process's stderr so that all die()
 362                 * in subsequent call paths use the parent's stderr.
 363                 */
 364                if (cmd->no_stderr || need_err) {
 365                        child_err = dup(2);
 366                        set_cloexec(child_err);
 367                }
 368                set_die_routine(die_child);
 369                set_error_routine(error_child);
 370
 371                close(notify_pipe[0]);
 372                set_cloexec(notify_pipe[1]);
 373                child_notifier = notify_pipe[1];
 374                atexit(notify_parent);
 375
 376                if (cmd->no_stdin)
 377                        dup_devnull(0);
 378                else if (need_in) {
 379                        dup2(fdin[0], 0);
 380                        close_pair(fdin);
 381                } else if (cmd->in) {
 382                        dup2(cmd->in, 0);
 383                        close(cmd->in);
 384                }
 385
 386                if (cmd->no_stderr)
 387                        dup_devnull(2);
 388                else if (need_err) {
 389                        dup2(fderr[1], 2);
 390                        close_pair(fderr);
 391                } else if (cmd->err > 1) {
 392                        dup2(cmd->err, 2);
 393                        close(cmd->err);
 394                }
 395
 396                if (cmd->no_stdout)
 397                        dup_devnull(1);
 398                else if (cmd->stdout_to_stderr)
 399                        dup2(2, 1);
 400                else if (need_out) {
 401                        dup2(fdout[1], 1);
 402                        close_pair(fdout);
 403                } else if (cmd->out > 1) {
 404                        dup2(cmd->out, 1);
 405                        close(cmd->out);
 406                }
 407
 408                if (cmd->dir && chdir(cmd->dir))
 409                        die_errno("exec '%s': cd to '%s' failed", cmd->argv[0],
 410                            cmd->dir);
 411                if (cmd->env) {
 412                        for (; *cmd->env; cmd->env++) {
 413                                if (strchr(*cmd->env, '='))
 414                                        putenv((char *)*cmd->env);
 415                                else
 416                                        unsetenv(*cmd->env);
 417                        }
 418                }
 419                if (cmd->git_cmd)
 420                        execv_git_cmd(cmd->argv);
 421                else if (cmd->use_shell)
 422                        execv_shell_cmd(cmd->argv);
 423                else
 424                        sane_execvp(cmd->argv[0], (char *const*) cmd->argv);
 425                if (errno == ENOENT) {
 426                        if (!cmd->silent_exec_failure)
 427                                error("cannot run %s: %s", cmd->argv[0],
 428                                        strerror(ENOENT));
 429                        exit(127);
 430                } else {
 431                        die_errno("cannot exec '%s'", cmd->argv[0]);
 432                }
 433        }
 434        if (cmd->pid < 0)
 435                error("cannot fork() for %s: %s", cmd->argv[0],
 436                        strerror(errno));
 437        else if (cmd->clean_on_exit)
 438                mark_child_for_cleanup(cmd->pid);
 439
 440        /*
 441         * Wait for child's execvp. If the execvp succeeds (or if fork()
 442         * failed), EOF is seen immediately by the parent. Otherwise, the
 443         * child process sends a single byte.
 444         * Note that use of this infrastructure is completely advisory,
 445         * therefore, we keep error checks minimal.
 446         */
 447        close(notify_pipe[1]);
 448        if (read(notify_pipe[0], &notify_pipe[1], 1) == 1) {
 449                /*
 450                 * At this point we know that fork() succeeded, but execvp()
 451                 * failed. Errors have been reported to our stderr.
 452                 */
 453                wait_or_whine(cmd->pid, cmd->argv[0]);
 454                failed_errno = errno;
 455                cmd->pid = -1;
 456        }
 457        close(notify_pipe[0]);
 458}
 459#else
 460{
 461        int fhin = 0, fhout = 1, fherr = 2;
 462        const char **sargv = cmd->argv;
 463
 464        if (cmd->no_stdin)
 465                fhin = open("/dev/null", O_RDWR);
 466        else if (need_in)
 467                fhin = dup(fdin[0]);
 468        else if (cmd->in)
 469                fhin = dup(cmd->in);
 470
 471        if (cmd->no_stderr)
 472                fherr = open("/dev/null", O_RDWR);
 473        else if (need_err)
 474                fherr = dup(fderr[1]);
 475        else if (cmd->err > 2)
 476                fherr = dup(cmd->err);
 477
 478        if (cmd->no_stdout)
 479                fhout = open("/dev/null", O_RDWR);
 480        else if (cmd->stdout_to_stderr)
 481                fhout = dup(fherr);
 482        else if (need_out)
 483                fhout = dup(fdout[1]);
 484        else if (cmd->out > 1)
 485                fhout = dup(cmd->out);
 486
 487        if (cmd->git_cmd)
 488                cmd->argv = prepare_git_cmd(cmd->argv);
 489        else if (cmd->use_shell)
 490                cmd->argv = prepare_shell_cmd(cmd->argv);
 491
 492        cmd->pid = mingw_spawnvpe(cmd->argv[0], cmd->argv, (char**) cmd->env,
 493                        cmd->dir, fhin, fhout, fherr);
 494        failed_errno = errno;
 495        if (cmd->pid < 0 && (!cmd->silent_exec_failure || errno != ENOENT))
 496                error("cannot spawn %s: %s", cmd->argv[0], strerror(errno));
 497        if (cmd->clean_on_exit && cmd->pid >= 0)
 498                mark_child_for_cleanup(cmd->pid);
 499
 500        if (cmd->git_cmd)
 501                free(cmd->argv);
 502
 503        cmd->argv = sargv;
 504        if (fhin != 0)
 505                close(fhin);
 506        if (fhout != 1)
 507                close(fhout);
 508        if (fherr != 2)
 509                close(fherr);
 510}
 511#endif
 512
 513        if (cmd->pid < 0) {
 514                if (need_in)
 515                        close_pair(fdin);
 516                else if (cmd->in)
 517                        close(cmd->in);
 518                if (need_out)
 519                        close_pair(fdout);
 520                else if (cmd->out)
 521                        close(cmd->out);
 522                if (need_err)
 523                        close_pair(fderr);
 524                else if (cmd->err)
 525                        close(cmd->err);
 526                argv_array_clear(&cmd->args);
 527                errno = failed_errno;
 528                return -1;
 529        }
 530
 531        if (need_in)
 532                close(fdin[0]);
 533        else if (cmd->in)
 534                close(cmd->in);
 535
 536        if (need_out)
 537                close(fdout[1]);
 538        else if (cmd->out)
 539                close(cmd->out);
 540
 541        if (need_err)
 542                close(fderr[1]);
 543        else if (cmd->err)
 544                close(cmd->err);
 545
 546        return 0;
 547}
 548
 549int finish_command(struct child_process *cmd)
 550{
 551        int ret = wait_or_whine(cmd->pid, cmd->argv[0]);
 552        argv_array_clear(&cmd->args);
 553        return ret;
 554}
 555
 556int run_command(struct child_process *cmd)
 557{
 558        int code = start_command(cmd);
 559        if (code)
 560                return code;
 561        return finish_command(cmd);
 562}
 563
 564int run_command_v_opt(const char **argv, int opt)
 565{
 566        return run_command_v_opt_cd_env(argv, opt, NULL, NULL);
 567}
 568
 569int run_command_v_opt_cd_env(const char **argv, int opt, const char *dir, const char *const *env)
 570{
 571        struct child_process cmd = CHILD_PROCESS_INIT;
 572        cmd.argv = argv;
 573        cmd.no_stdin = opt & RUN_COMMAND_NO_STDIN ? 1 : 0;
 574        cmd.git_cmd = opt & RUN_GIT_CMD ? 1 : 0;
 575        cmd.stdout_to_stderr = opt & RUN_COMMAND_STDOUT_TO_STDERR ? 1 : 0;
 576        cmd.silent_exec_failure = opt & RUN_SILENT_EXEC_FAILURE ? 1 : 0;
 577        cmd.use_shell = opt & RUN_USING_SHELL ? 1 : 0;
 578        cmd.clean_on_exit = opt & RUN_CLEAN_ON_EXIT ? 1 : 0;
 579        cmd.dir = dir;
 580        cmd.env = env;
 581        return run_command(&cmd);
 582}
 583
 584#ifndef NO_PTHREADS
 585static pthread_t main_thread;
 586static int main_thread_set;
 587static pthread_key_t async_key;
 588static pthread_key_t async_die_counter;
 589
 590static void *run_thread(void *data)
 591{
 592        struct async *async = data;
 593        intptr_t ret;
 594
 595        pthread_setspecific(async_key, async);
 596        ret = async->proc(async->proc_in, async->proc_out, async->data);
 597        return (void *)ret;
 598}
 599
 600static NORETURN void die_async(const char *err, va_list params)
 601{
 602        vreportf("fatal: ", err, params);
 603
 604        if (!pthread_equal(main_thread, pthread_self())) {
 605                struct async *async = pthread_getspecific(async_key);
 606                if (async->proc_in >= 0)
 607                        close(async->proc_in);
 608                if (async->proc_out >= 0)
 609                        close(async->proc_out);
 610                pthread_exit((void *)128);
 611        }
 612
 613        exit(128);
 614}
 615
 616static int async_die_is_recursing(void)
 617{
 618        void *ret = pthread_getspecific(async_die_counter);
 619        pthread_setspecific(async_die_counter, (void *)1);
 620        return ret != NULL;
 621}
 622
 623#endif
 624
 625int start_async(struct async *async)
 626{
 627        int need_in, need_out;
 628        int fdin[2], fdout[2];
 629        int proc_in, proc_out;
 630
 631        need_in = async->in < 0;
 632        if (need_in) {
 633                if (pipe(fdin) < 0) {
 634                        if (async->out > 0)
 635                                close(async->out);
 636                        return error("cannot create pipe: %s", strerror(errno));
 637                }
 638                async->in = fdin[1];
 639        }
 640
 641        need_out = async->out < 0;
 642        if (need_out) {
 643                if (pipe(fdout) < 0) {
 644                        if (need_in)
 645                                close_pair(fdin);
 646                        else if (async->in)
 647                                close(async->in);
 648                        return error("cannot create pipe: %s", strerror(errno));
 649                }
 650                async->out = fdout[0];
 651        }
 652
 653        if (need_in)
 654                proc_in = fdin[0];
 655        else if (async->in)
 656                proc_in = async->in;
 657        else
 658                proc_in = -1;
 659
 660        if (need_out)
 661                proc_out = fdout[1];
 662        else if (async->out)
 663                proc_out = async->out;
 664        else
 665                proc_out = -1;
 666
 667#ifdef NO_PTHREADS
 668        /* Flush stdio before fork() to avoid cloning buffers */
 669        fflush(NULL);
 670
 671        async->pid = fork();
 672        if (async->pid < 0) {
 673                error("fork (async) failed: %s", strerror(errno));
 674                goto error;
 675        }
 676        if (!async->pid) {
 677                if (need_in)
 678                        close(fdin[1]);
 679                if (need_out)
 680                        close(fdout[0]);
 681                exit(!!async->proc(proc_in, proc_out, async->data));
 682        }
 683
 684        mark_child_for_cleanup(async->pid);
 685
 686        if (need_in)
 687                close(fdin[0]);
 688        else if (async->in)
 689                close(async->in);
 690
 691        if (need_out)
 692                close(fdout[1]);
 693        else if (async->out)
 694                close(async->out);
 695#else
 696        if (!main_thread_set) {
 697                /*
 698                 * We assume that the first time that start_async is called
 699                 * it is from the main thread.
 700                 */
 701                main_thread_set = 1;
 702                main_thread = pthread_self();
 703                pthread_key_create(&async_key, NULL);
 704                pthread_key_create(&async_die_counter, NULL);
 705                set_die_routine(die_async);
 706                set_die_is_recursing_routine(async_die_is_recursing);
 707        }
 708
 709        if (proc_in >= 0)
 710                set_cloexec(proc_in);
 711        if (proc_out >= 0)
 712                set_cloexec(proc_out);
 713        async->proc_in = proc_in;
 714        async->proc_out = proc_out;
 715        {
 716                int err = pthread_create(&async->tid, NULL, run_thread, async);
 717                if (err) {
 718                        error("cannot create thread: %s", strerror(err));
 719                        goto error;
 720                }
 721        }
 722#endif
 723        return 0;
 724
 725error:
 726        if (need_in)
 727                close_pair(fdin);
 728        else if (async->in)
 729                close(async->in);
 730
 731        if (need_out)
 732                close_pair(fdout);
 733        else if (async->out)
 734                close(async->out);
 735        return -1;
 736}
 737
 738int finish_async(struct async *async)
 739{
 740#ifdef NO_PTHREADS
 741        return wait_or_whine(async->pid, "child process");
 742#else
 743        void *ret = (void *)(intptr_t)(-1);
 744
 745        if (pthread_join(async->tid, &ret))
 746                error("pthread_join failed");
 747        return (int)(intptr_t)ret;
 748#endif
 749}
 750
 751char *find_hook(const char *name)
 752{
 753        char *path = git_path("hooks/%s", name);
 754        if (access(path, X_OK) < 0)
 755                path = NULL;
 756
 757        return path;
 758}
 759
 760int run_hook_ve(const char *const *env, const char *name, va_list args)
 761{
 762        struct child_process hook = CHILD_PROCESS_INIT;
 763        const char *p;
 764
 765        p = find_hook(name);
 766        if (!p)
 767                return 0;
 768
 769        argv_array_push(&hook.args, p);
 770        while ((p = va_arg(args, const char *)))
 771                argv_array_push(&hook.args, p);
 772        hook.env = env;
 773        hook.no_stdin = 1;
 774        hook.stdout_to_stderr = 1;
 775
 776        return run_command(&hook);
 777}
 778
 779int run_hook_le(const char *const *env, const char *name, ...)
 780{
 781        va_list args;
 782        int ret;
 783
 784        va_start(args, name);
 785        ret = run_hook_ve(env, name, args);
 786        va_end(args);
 787
 788        return ret;
 789}
 790
 791int run_hook_with_custom_index(const char *index_file, const char *name, ...)
 792{
 793        const char *hook_env[3] =  { NULL };
 794        char index[PATH_MAX];
 795        va_list args;
 796        int ret;
 797
 798        snprintf(index, sizeof(index), "GIT_INDEX_FILE=%s", index_file);
 799        hook_env[0] = index;
 800
 801        va_start(args, name);
 802        ret = run_hook_ve(hook_env, name, args);
 803        va_end(args);
 804
 805        return ret;
 806}