• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6.36/tools/perf/util/
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#ifdef RUNTIME_PREFIX
15	static const char *prefix;
16#else
17	static const char *prefix = PREFIX;
18#endif
19	struct strbuf d = STRBUF_INIT;
20
21	if (is_absolute_path(path))
22		return path;
23
24#ifdef RUNTIME_PREFIX
25	assert(argv0_path);
26	assert(is_absolute_path(argv0_path));
27
28	if (!prefix &&
29	    !(prefix = strip_path_suffix(argv0_path, PERF_EXEC_PATH)) &&
30	    !(prefix = strip_path_suffix(argv0_path, BINDIR)) &&
31	    !(prefix = strip_path_suffix(argv0_path, "perf"))) {
32		prefix = PREFIX;
33		fprintf(stderr, "RUNTIME_PREFIX requested, "
34				"but prefix computation failed.  "
35				"Using static fallback '%s'.\n", prefix);
36	}
37#endif
38
39	strbuf_addf(&d, "%s/%s", prefix, path);
40	path = strbuf_detach(&d, NULL);
41	return path;
42}
43
44const char *perf_extract_argv0_path(const char *argv0)
45{
46	const char *slash;
47
48	if (!argv0 || !*argv0)
49		return NULL;
50	slash = argv0 + strlen(argv0);
51
52	while (argv0 <= slash && !is_dir_sep(*slash))
53		slash--;
54
55	if (slash >= argv0) {
56		argv0_path = strndup(argv0, slash - argv0);
57		return argv0_path ? slash + 1 : NULL;
58	}
59
60	return argv0;
61}
62
63void perf_set_argv_exec_path(const char *exec_path)
64{
65	argv_exec_path = exec_path;
66	/*
67	 * Propagate this setting to external programs.
68	 */
69	setenv(EXEC_PATH_ENVIRONMENT, exec_path, 1);
70}
71
72
73/* Returns the highest-priority, location to look for perf programs. */
74const char *perf_exec_path(void)
75{
76	const char *env;
77
78	if (argv_exec_path)
79		return argv_exec_path;
80
81	env = getenv(EXEC_PATH_ENVIRONMENT);
82	if (env && *env) {
83		return env;
84	}
85
86	return system_path(PERF_EXEC_PATH);
87}
88
89static void add_path(struct strbuf *out, const char *path)
90{
91	if (path && *path) {
92		if (is_absolute_path(path))
93			strbuf_addstr(out, path);
94		else
95			strbuf_addstr(out, make_nonrelative_path(path));
96
97		strbuf_addch(out, PATH_SEP);
98	}
99}
100
101void setup_path(void)
102{
103	const char *old_path = getenv("PATH");
104	struct strbuf new_path = STRBUF_INIT;
105
106	add_path(&new_path, perf_exec_path());
107	add_path(&new_path, argv0_path);
108
109	if (old_path)
110		strbuf_addstr(&new_path, old_path);
111	else
112		strbuf_addstr(&new_path, "/usr/local/bin:/usr/bin:/bin");
113
114	setenv("PATH", new_path.buf, 1);
115
116	strbuf_release(&new_path);
117}
118
119static const char **prepare_perf_cmd(const char **argv)
120{
121	int argc;
122	const char **nargv;
123
124	for (argc = 0; argv[argc]; argc++)
125		; /* just counting */
126	nargv = malloc(sizeof(*nargv) * (argc + 2));
127
128	nargv[0] = "perf";
129	for (argc = 0; argv[argc]; argc++)
130		nargv[argc + 1] = argv[argc];
131	nargv[argc + 1] = NULL;
132	return nargv;
133}
134
135int execv_perf_cmd(const char **argv) {
136	const char **nargv = prepare_perf_cmd(argv);
137
138	/* execvp() can only ever return if it fails */
139	execvp("perf", (char **)nargv);
140
141	free(nargv);
142	return -1;
143}
144
145
146int execl_perf_cmd(const char *cmd,...)
147{
148	int argc;
149	const char *argv[MAX_ARGS + 1];
150	const char *arg;
151	va_list param;
152
153	va_start(param, cmd);
154	argv[0] = cmd;
155	argc = 1;
156	while (argc < MAX_ARGS) {
157		arg = argv[argc++] = va_arg(param, char *);
158		if (!arg)
159			break;
160	}
161	va_end(param);
162	if (MAX_ARGS <= argc)
163		return error("too many args to run %s", cmd);
164
165	argv[argc] = NULL;
166	return execv_perf_cmd(argv);
167}
168