exec_cmd.con commit Windows: TMP and TEMP environment variables specify a temporary directory. (6fd6aec)
   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        struct strbuf cmd;
 102        const char *tmp;
 103
 104        strbuf_init(&cmd, 0);
 105        strbuf_addf(&cmd, "git-%s", argv[0]);
 106
 107        /*
 108         * argv[0] must be the git command, but the argv array
 109         * belongs to the caller, and may be reused in
 110         * subsequent loop iterations. Save argv[0] and
 111         * restore it on error.
 112         */
 113        tmp = argv[0];
 114        argv[0] = cmd.buf;
 115
 116        trace_argv_printf(argv, "trace: exec:");
 117
 118        /* execvp() can only ever return if it fails */
 119        execvp(cmd.buf, (char **)argv);
 120
 121        trace_printf("trace: exec failed: %s\n", strerror(errno));
 122
 123        argv[0] = tmp;
 124
 125        strbuf_release(&cmd);
 126
 127        return -1;
 128}
 129
 130
 131int execl_git_cmd(const char *cmd,...)
 132{
 133        int argc;
 134        const char *argv[MAX_ARGS + 1];
 135        const char *arg;
 136        va_list param;
 137
 138        va_start(param, cmd);
 139        argv[0] = cmd;
 140        argc = 1;
 141        while (argc < MAX_ARGS) {
 142                arg = argv[argc++] = va_arg(param, char *);
 143                if (!arg)
 144                        break;
 145        }
 146        va_end(param);
 147        if (MAX_ARGS <= argc)
 148                return error("too many args to run %s", cmd);
 149
 150        argv[argc] = NULL;
 151        return execv_git_cmd(argv);
 152}