Commit c4068f51 authored by Masami Hiramatsu's avatar Masami Hiramatsu Committed by Arnaldo Carvalho de Melo

perf tools: Make perf_exec_path() always return malloc'd string

Since system_path() returns malloc'd string if given path is not an
absolute path, perf_exec_path() sometimes returns a static string and
sometimes returns a malloc'd string depending on the environment
variables or command options.

This may cause a memory leak because the caller can not unconditionally
free the returned string.

This fixes perf_exec_path() and system_path() to always return a
malloc'd string, so the caller can always free it.
Signed-off-by: default avatarMasami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/20151119060453.14210.65666.stgit@localhost.localdomainSigned-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent ebe9729c
...@@ -9,17 +9,17 @@ ...@@ -9,17 +9,17 @@
static const char *argv_exec_path; static const char *argv_exec_path;
static const char *argv0_path; static const char *argv0_path;
const char *system_path(const char *path) char *system_path(const char *path)
{ {
static const char *prefix = PREFIX; static const char *prefix = PREFIX;
struct strbuf d = STRBUF_INIT; struct strbuf d = STRBUF_INIT;
if (is_absolute_path(path)) if (is_absolute_path(path))
return path; return strdup(path);
strbuf_addf(&d, "%s/%s", prefix, path); strbuf_addf(&d, "%s/%s", prefix, path);
path = strbuf_detach(&d, NULL); path = strbuf_detach(&d, NULL);
return path; return (char *)path;
} }
const char *perf_extract_argv0_path(const char *argv0) const char *perf_extract_argv0_path(const char *argv0)
...@@ -52,17 +52,16 @@ void perf_set_argv_exec_path(const char *exec_path) ...@@ -52,17 +52,16 @@ void perf_set_argv_exec_path(const char *exec_path)
/* Returns the highest-priority, location to look for perf programs. */ /* Returns the highest-priority, location to look for perf programs. */
const char *perf_exec_path(void) char *perf_exec_path(void)
{ {
const char *env; char *env;
if (argv_exec_path) if (argv_exec_path)
return argv_exec_path; return strdup(argv_exec_path);
env = getenv(EXEC_PATH_ENVIRONMENT); env = getenv(EXEC_PATH_ENVIRONMENT);
if (env && *env) { if (env && *env)
return env; return strdup(env);
}
return system_path(PERF_EXEC_PATH); return system_path(PERF_EXEC_PATH);
} }
...@@ -83,9 +82,11 @@ void setup_path(void) ...@@ -83,9 +82,11 @@ void setup_path(void)
{ {
const char *old_path = getenv("PATH"); const char *old_path = getenv("PATH");
struct strbuf new_path = STRBUF_INIT; struct strbuf new_path = STRBUF_INIT;
char *tmp = perf_exec_path();
add_path(&new_path, perf_exec_path()); add_path(&new_path, tmp);
add_path(&new_path, argv0_path); add_path(&new_path, argv0_path);
free(tmp);
if (old_path) if (old_path)
strbuf_addstr(&new_path, old_path); strbuf_addstr(&new_path, old_path);
......
...@@ -3,10 +3,11 @@ ...@@ -3,10 +3,11 @@
extern void perf_set_argv_exec_path(const char *exec_path); extern void perf_set_argv_exec_path(const char *exec_path);
extern const char *perf_extract_argv0_path(const char *path); extern const char *perf_extract_argv0_path(const char *path);
extern const char *perf_exec_path(void);
extern void setup_path(void); extern void setup_path(void);
extern int execv_perf_cmd(const char **argv); /* NULL terminated */ extern int execv_perf_cmd(const char **argv); /* NULL terminated */
extern int execl_perf_cmd(const char *cmd, ...); extern int execl_perf_cmd(const char *cmd, ...);
extern const char *system_path(const char *path); /* perf_exec_path and system_path return malloc'd string, caller must free it */
extern char *perf_exec_path(void);
extern char *system_path(const char *path);
#endif /* __PERF_EXEC_CMD_H */ #endif /* __PERF_EXEC_CMD_H */
...@@ -159,7 +159,7 @@ void load_command_list(const char *prefix, ...@@ -159,7 +159,7 @@ void load_command_list(const char *prefix,
struct cmdnames *other_cmds) struct cmdnames *other_cmds)
{ {
const char *env_path = getenv("PATH"); const char *env_path = getenv("PATH");
const char *exec_path = perf_exec_path(); char *exec_path = perf_exec_path();
if (exec_path) { if (exec_path) {
list_commands_in_dir(main_cmds, exec_path, prefix); list_commands_in_dir(main_cmds, exec_path, prefix);
...@@ -187,6 +187,7 @@ void load_command_list(const char *prefix, ...@@ -187,6 +187,7 @@ void load_command_list(const char *prefix,
sizeof(*other_cmds->names), cmdname_compare); sizeof(*other_cmds->names), cmdname_compare);
uniq(other_cmds); uniq(other_cmds);
} }
free(exec_path);
exclude_cmds(other_cmds, main_cmds); exclude_cmds(other_cmds, main_cmds);
} }
...@@ -203,13 +204,14 @@ void list_commands(const char *title, struct cmdnames *main_cmds, ...@@ -203,13 +204,14 @@ void list_commands(const char *title, struct cmdnames *main_cmds,
longest = other_cmds->names[i]->len; longest = other_cmds->names[i]->len;
if (main_cmds->cnt) { if (main_cmds->cnt) {
const char *exec_path = perf_exec_path(); char *exec_path = perf_exec_path();
printf("available %s in '%s'\n", title, exec_path); printf("available %s in '%s'\n", title, exec_path);
printf("----------------"); printf("----------------");
mput_char('-', strlen(title) + strlen(exec_path)); mput_char('-', strlen(title) + strlen(exec_path));
putchar('\n'); putchar('\n');
pretty_print_string_list(main_cmds, longest); pretty_print_string_list(main_cmds, longest);
putchar('\n'); putchar('\n');
free(exec_path);
} }
if (other_cmds->cnt) { if (other_cmds->cnt) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment