Commit | Line | Data |
---|---|---|
07800601 IM |
1 | #include "cache.h" |
2 | #include "exec_cmd.h" | |
3 | #include "quote.h" | |
f37a291c IM |
4 | |
5 | #include <string.h> | |
6 | ||
07800601 IM |
7 | #define MAX_ARGS 32 |
8 | ||
07800601 IM |
9 | static const char *argv_exec_path; |
10 | static const char *argv0_path; | |
11 | ||
12 | const char *system_path(const char *path) | |
13 | { | |
07800601 | 14 | static const char *prefix = PREFIX; |
07800601 IM |
15 | struct strbuf d = STRBUF_INIT; |
16 | ||
17 | if (is_absolute_path(path)) | |
18 | return path; | |
19 | ||
07800601 IM |
20 | strbuf_addf(&d, "%s/%s", prefix, path); |
21 | path = strbuf_detach(&d, NULL); | |
22 | return 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) { | |
151f85a4 ACM |
37 | argv0_path = strndup(argv0, slash - argv0); |
38 | return argv0_path ? slash + 1 : NULL; | |
07800601 IM |
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 | const 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 | ||
70 | static 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 | ||
82 | void 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 | ||
a41794cd | 100 | static const char **prepare_perf_cmd(const char **argv) |
07800601 IM |
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 | ||
116 | int 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 | ||
127 | int 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 | } |