Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
exec_cmd.c
Go to the documentation of this file.
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 const 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 
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 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 
100 static 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 
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 }