linux/tools/perf/util/exec_cmd.c
<<
>>
Prefs
   1#include "cache.h"
   2#include "exec_cmd.h"
   3#include "quote.h"
   4
   5#include <string.h>
   6
   7#define MAX_ARGS        32
   8
   9static const char *argv_exec_path;
  10static const char *argv0_path;
  11
  12const char *system_path(const char *path)
  13{
  14        static const char *prefix = PREFIX;
  15        struct strbuf d = STRBUF_INIT;
  16
  17        if (is_absolute_path(path))
  18                return path;
  19
  20        strbuf_addf(&d, "%s/%s", prefix, path);
  21        path = strbuf_detach(&d, NULL);
  22        return path;
  23}
  24
  25const char *perf_extract_argv0_path(const char *argv0)
  26{
  27        const char *slash;
  28
  29        if (!argv0 || !*argv0)
  30                return NULL;
  31        slash = argv0 + strlen(argv0);
  32
  33        while (argv0 <= slash && !is_dir_sep(*slash))
  34                slash--;
  35
  36        if (slash >= argv0) {
  37                argv0_path = strndup(argv0, slash - argv0);
  38                return argv0_path ? slash + 1 : NULL;
  39        }
  40
  41        return argv0;
  42}
  43
  44void perf_set_argv_exec_path(const char *exec_path)
  45{
  46        argv_exec_path = exec_path;
  47        /*
  48         * Propagate this setting to external programs.
  49         */
  50        setenv(EXEC_PATH_ENVIRONMENT, exec_path, 1);
  51}
  52
  53
  54/* Returns the highest-priority, location to look for perf programs. */
  55const char *perf_exec_path(void)
  56{
  57        const char *env;
  58
  59        if (argv_exec_path)
  60                return argv_exec_path;
  61
  62        env = getenv(EXEC_PATH_ENVIRONMENT);
  63        if (env && *env) {
  64                return env;
  65        }
  66
  67        return system_path(PERF_EXEC_PATH);
  68}
  69
  70static void add_path(struct strbuf *out, const char *path)
  71{
  72        if (path && *path) {
  73                if (is_absolute_path(path))
  74                        strbuf_addstr(out, path);
  75                else
  76                        strbuf_addstr(out, make_nonrelative_path(path));
  77
  78                strbuf_addch(out, PATH_SEP);
  79        }
  80}
  81
  82void setup_path(void)
  83{
  84        const char *old_path = getenv("PATH");
  85        struct strbuf new_path = STRBUF_INIT;
  86
  87        add_path(&new_path, perf_exec_path());
  88        add_path(&new_path, argv0_path);
  89
  90        if (old_path)
  91                strbuf_addstr(&new_path, old_path);
  92        else
  93                strbuf_addstr(&new_path, "/usr/local/bin:/usr/bin:/bin");
  94
  95        setenv("PATH", new_path.buf, 1);
  96
  97        strbuf_release(&new_path);
  98}
  99
 100static const char **prepare_perf_cmd(const char **argv)
 101{
 102        int argc;
 103        const char **nargv;
 104
 105        for (argc = 0; argv[argc]; argc++)
 106                ; /* just counting */
 107        nargv = malloc(sizeof(*nargv) * (argc + 2));
 108
 109        nargv[0] = "perf";
 110        for (argc = 0; argv[argc]; argc++)
 111                nargv[argc + 1] = argv[argc];
 112        nargv[argc + 1] = NULL;
 113        return nargv;
 114}
 115
 116int execv_perf_cmd(const char **argv) {
 117        const char **nargv = prepare_perf_cmd(argv);
 118
 119        /* execvp() can only ever return if it fails */
 120        execvp("perf", (char **)nargv);
 121
 122        free(nargv);
 123        return -1;
 124}
 125
 126
 127int execl_perf_cmd(const char *cmd,...)
 128{
 129        int argc;
 130        const char *argv[MAX_ARGS + 1];
 131        const char *arg;
 132        va_list param;
 133
 134        va_start(param, cmd);
 135        argv[0] = cmd;
 136        argc = 1;
 137        while (argc < MAX_ARGS) {
 138                arg = argv[argc++] = va_arg(param, char *);
 139                if (!arg)
 140                        break;
 141        }
 142        va_end(param);
 143        if (MAX_ARGS <= argc)
 144                return error("too many args to run %s", cmd);
 145
 146        argv[argc] = NULL;
 147        return execv_perf_cmd(argv);
 148}
 149