1099e92f5ee1881c1519211a0ff3d98c39585c3c
[deliverable/linux.git] / tools / perf / util / exec_cmd.c
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
9 static const char *argv_exec_path;
10 static const char *argv0_path;
11
12 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 strdup(path);
19
20 strbuf_addf(&d, "%s/%s", prefix, path);
21 path = strbuf_detach(&d, NULL);
22 return (char *)path;
23 }
24
25 const 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
44 void 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. */
55 char *perf_exec_path(void)
56 {
57 char *env;
58
59 if (argv_exec_path)
60 return strdup(argv_exec_path);
61
62 env = getenv(EXEC_PATH_ENVIRONMENT);
63 if (env && *env)
64 return strdup(env);
65
66 return system_path(PERF_EXEC_PATH);
67 }
68
69 static void add_path(struct strbuf *out, const char *path)
70 {
71 if (path && *path) {
72 if (is_absolute_path(path))
73 strbuf_addstr(out, path);
74 else
75 strbuf_addstr(out, make_nonrelative_path(path));
76
77 strbuf_addch(out, PATH_SEP);
78 }
79 }
80
81 void setup_path(void)
82 {
83 const char *old_path = getenv("PATH");
84 struct strbuf new_path = STRBUF_INIT;
85 char *tmp = perf_exec_path();
86
87 add_path(&new_path, tmp);
88 add_path(&new_path, argv0_path);
89 free(tmp);
90
91 if (old_path)
92 strbuf_addstr(&new_path, old_path);
93 else
94 strbuf_addstr(&new_path, "/usr/local/bin:/usr/bin:/bin");
95
96 setenv("PATH", new_path.buf, 1);
97
98 strbuf_release(&new_path);
99 }
100
101 static const char **prepare_perf_cmd(const char **argv)
102 {
103 int argc;
104 const char **nargv;
105
106 for (argc = 0; argv[argc]; argc++)
107 ; /* just counting */
108 nargv = malloc(sizeof(*nargv) * (argc + 2));
109
110 nargv[0] = "perf";
111 for (argc = 0; argv[argc]; argc++)
112 nargv[argc + 1] = argv[argc];
113 nargv[argc + 1] = NULL;
114 return nargv;
115 }
116
117 int execv_perf_cmd(const char **argv) {
118 const char **nargv = prepare_perf_cmd(argv);
119
120 /* execvp() can only ever return if it fails */
121 execvp("perf", (char **)nargv);
122
123 free(nargv);
124 return -1;
125 }
126
127
128 int execl_perf_cmd(const char *cmd,...)
129 {
130 int argc;
131 const char *argv[MAX_ARGS + 1];
132 const char *arg;
133 va_list param;
134
135 va_start(param, cmd);
136 argv[0] = cmd;
137 argc = 1;
138 while (argc < MAX_ARGS) {
139 arg = argv[argc++] = va_arg(param, char *);
140 if (!arg)
141 break;
142 }
143 va_end(param);
144 if (MAX_ARGS <= argc)
145 return error("too many args to run %s", cmd);
146
147 argv[argc] = NULL;
148 return execv_perf_cmd(argv);
149 }
This page took 0.033244 seconds and 4 git commands to generate.