exec_cmd.con commit stash save: fix parameter handling (47629dc)
   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
  43const char *system_path(const char *path)
  44{
  45        if (!is_absolute_path(path)) {
  46                struct strbuf d = STRBUF_INIT;
  47                strbuf_addf(&d, "%s/%s", git_exec_path(), path);
  48                path = strbuf_detach(&d, NULL);
  49        }
  50        return path;
  51}
  52
  53void git_set_argv_exec_path(const char *exec_path)
  54{
  55        argv_exec_path = exec_path;
  56}
  57
  58
  59/* Returns the highest-priority, location to look for git programs. */
  60const char *git_exec_path(void)
  61{
  62        const char *env;
  63
  64        if (argv_exec_path)
  65                return argv_exec_path;
  66
  67        env = getenv(EXEC_PATH_ENVIRONMENT);
  68        if (env && *env) {
  69                return env;
  70        }
  71
  72        return builtin_exec_path();
  73}
  74
  75static void add_path(struct strbuf *out, const char *path)
  76{
  77        if (path && *path) {
  78                if (is_absolute_path(path))
  79                        strbuf_addstr(out, path);
  80                else
  81                        strbuf_addstr(out, make_absolute_path(path));
  82
  83                strbuf_addch(out, PATH_SEP);
  84        }
  85}
  86
  87void setup_path(const char *cmd_path)
  88{
  89        const char *old_path = getenv("PATH");
  90        struct strbuf new_path;
  91
  92        strbuf_init(&new_path, 0);
  93
  94        add_path(&new_path, argv_exec_path);
  95        add_path(&new_path, getenv(EXEC_PATH_ENVIRONMENT));
  96        add_path(&new_path, builtin_exec_path());
  97        add_path(&new_path, cmd_path);
  98
  99        if (old_path)
 100                strbuf_addstr(&new_path, old_path);
 101        else
 102                strbuf_addstr(&new_path, "/usr/local/bin:/usr/bin:/bin");
 103
 104        setenv("PATH", new_path.buf, 1);
 105
 106        strbuf_release(&new_path);
 107}
 108
 109int execv_git_cmd(const char **argv)
 110{
 111        int argc;
 112        const char **nargv;
 113
 114        for (argc = 0; argv[argc]; argc++)
 115                ; /* just counting */
 116        nargv = xmalloc(sizeof(*nargv) * (argc + 2));
 117
 118        nargv[0] = "git";
 119        for (argc = 0; argv[argc]; argc++)
 120                nargv[argc + 1] = argv[argc];
 121        nargv[argc + 1] = NULL;
 122        trace_argv_printf(nargv, "trace: exec:");
 123
 124        /* execvp() can only ever return if it fails */
 125        execvp("git", (char **)nargv);
 126
 127        trace_printf("trace: exec failed: %s\n", strerror(errno));
 128
 129        free(nargv);
 130        return -1;
 131}
 132
 133
 134int execl_git_cmd(const char *cmd,...)
 135{
 136        int argc;
 137        const char *argv[MAX_ARGS + 1];
 138        const char *arg;
 139        va_list param;
 140
 141        va_start(param, cmd);
 142        argv[0] = cmd;
 143        argc = 1;
 144        while (argc < MAX_ARGS) {
 145                arg = argv[argc++] = va_arg(param, char *);
 146                if (!arg)
 147                        break;
 148        }
 149        va_end(param);
 150        if (MAX_ARGS <= argc)
 151                return error("too many args to run %s", cmd);
 152
 153        argv[argc] = NULL;
 154        return execv_git_cmd(argv);
 155}