exec_cmd.con commit Documentation: mention ORIG_HEAD in am, merge, and rebase (9869099)
   1#include "cache.h"
   2#include "exec_cmd.h"
   3#include "quote.h"
   4#define MAX_ARGS        32
   5
   6extern char **environ;
   7static const char *argv_exec_path;
   8
   9static const char *builtin_exec_path(void)
  10{
  11#ifndef __MINGW32__
  12        return GIT_EXEC_PATH;
  13#else
  14        int len;
  15        char *p, *q, *sl;
  16        static char *ep;
  17        if (ep)
  18                return ep;
  19
  20        len = strlen(_pgmptr);
  21        if (len < 2)
  22                return ep = ".";
  23
  24        p = ep = xmalloc(len+1);
  25        q = _pgmptr;
  26        sl = NULL;
  27        /* copy program name, turn '\\' into '/', skip last part */
  28        while ((*p = *q)) {
  29                if (*q == '\\' || *q == '/') {
  30                        *p = '/';
  31                        sl = p;
  32                }
  33                p++, q++;
  34        }
  35        if (sl)
  36                *sl = '\0';
  37        else
  38                ep[0] = '.', ep[1] = '\0';
  39        return ep;
  40#endif
  41}
  42
  43void git_set_argv_exec_path(const char *exec_path)
  44{
  45        argv_exec_path = exec_path;
  46}
  47
  48
  49/* Returns the highest-priority, location to look for git programs. */
  50const char *git_exec_path(void)
  51{
  52        const char *env;
  53
  54        if (argv_exec_path)
  55                return argv_exec_path;
  56
  57        env = getenv(EXEC_PATH_ENVIRONMENT);
  58        if (env && *env) {
  59                return env;
  60        }
  61
  62        return builtin_exec_path();
  63}
  64
  65static void add_path(struct strbuf *out, const char *path)
  66{
  67        if (path && *path) {
  68                if (is_absolute_path(path))
  69                        strbuf_addstr(out, path);
  70                else
  71                        strbuf_addstr(out, make_absolute_path(path));
  72
  73                strbuf_addch(out, PATH_SEP);
  74        }
  75}
  76
  77void setup_path(const char *cmd_path)
  78{
  79        const char *old_path = getenv("PATH");
  80        struct strbuf new_path;
  81
  82        strbuf_init(&new_path, 0);
  83
  84        add_path(&new_path, argv_exec_path);
  85        add_path(&new_path, getenv(EXEC_PATH_ENVIRONMENT));
  86        add_path(&new_path, builtin_exec_path());
  87        add_path(&new_path, cmd_path);
  88
  89        if (old_path)
  90                strbuf_addstr(&new_path, old_path);
  91        else
  92                strbuf_addstr(&new_path, "/usr/local/bin:/usr/bin:/bin");
  93
  94        setenv("PATH", new_path.buf, 1);
  95
  96        strbuf_release(&new_path);
  97}
  98
  99int execv_git_cmd(const char **argv)
 100{
 101        int argc;
 102        const char **nargv;
 103
 104        for (argc = 0; argv[argc]; argc++)
 105                ; /* just counting */
 106        nargv = xmalloc(sizeof(*nargv) * (argc + 2));
 107
 108        nargv[0] = "git";
 109        for (argc = 0; argv[argc]; argc++)
 110                nargv[argc + 1] = argv[argc];
 111        nargv[argc + 1] = NULL;
 112        trace_argv_printf(nargv, "trace: exec:");
 113
 114        /* execvp() can only ever return if it fails */
 115        execvp("git", (char **)nargv);
 116
 117        trace_printf("trace: exec failed: %s\n", strerror(errno));
 118
 119        free(nargv);
 120        return -1;
 121}
 122
 123
 124int execl_git_cmd(const char *cmd,...)
 125{
 126        int argc;
 127        const char *argv[MAX_ARGS + 1];
 128        const char *arg;
 129        va_list param;
 130
 131        va_start(param, cmd);
 132        argv[0] = cmd;
 133        argc = 1;
 134        while (argc < MAX_ARGS) {
 135                arg = argv[argc++] = va_arg(param, char *);
 136                if (!arg)
 137                        break;
 138        }
 139        va_end(param);
 140        if (MAX_ARGS <= argc)
 141                return error("too many args to run %s", cmd);
 142
 143        argv[argc] = NULL;
 144        return execv_git_cmd(argv);
 145}