From: David Goulet Date: Thu, 5 Apr 2012 15:39:59 +0000 (-0400) Subject: Fix: make lttng expand path for trace output opt X-Git-Tag: v2.1.0-rc1~164 X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=commitdiff_plain;h=3badf2bf32930336a4902002d840402adb6859e1 Fix: make lttng expand path for trace output opt lttng create --output was passing the path string to the session daemon and thus, for relative path like './mytraces', it was created in the current directory of the session daemon. Now lttng command line uses the realpath(3) of the --output string and denies creation if multiple level of directory does not exist (Ex: /tmp/foo/bar/chap, if foo/ does not exist, it is refused). Directory creation still occurs on the session daemon side. Reported-by: Ettore Del Negro Signed-off-by: David Goulet --- diff --git a/src/bin/lttng/commands/create.c b/src/bin/lttng/commands/create.c index b1f3e8a77..2778ef553 100644 --- a/src/bin/lttng/commands/create.c +++ b/src/bin/lttng/commands/create.c @@ -115,7 +115,11 @@ static int create_session() goto error; } } else { - traces_path = opt_output_path; + traces_path = expand_full_path(opt_output_path); + if (traces_path == NULL) { + ret = CMD_ERROR; + goto error; + } } ret = lttng_create_session(session_name, traces_path); diff --git a/src/bin/lttng/utils.c b/src/bin/lttng/utils.c index b982bd593..8ae984836 100644 --- a/src/bin/lttng/utils.c +++ b/src/bin/lttng/utils.c @@ -18,12 +18,61 @@ #define _GNU_SOURCE #include #include +#include #include #include "conf.h" #include "utils.h" +/* + * Return the realpath(3) of the path even if the last directory token does not + * exist. For example, with /tmp/test1/test2, if test2/ does not exist but the + * /tmp/test1 does, the real path is returned. In normal time, realpath(3) + * fails if the end point directory does not exist. + */ +char *expand_full_path(const char *path) +{ + const char *end_path = path; + char *next, *cut_path, *expanded_path; + + /* Find last token delimited by '/' */ + while ((next = strpbrk(end_path + 1, "/"))) { + end_path = next; + } + + /* Cut last token from original path */ + cut_path = strndup(path, end_path - path); + + expanded_path = malloc(PATH_MAX); + if (expanded_path == NULL) { + goto error; + } + + expanded_path = realpath((char *)cut_path, expanded_path); + if (expanded_path == NULL) { + switch (errno) { + case ENOENT: + ERR("%s: No such file or directory", cut_path); + break; + default: + perror("realpath"); + break; + } + goto error; + } + + /* Add end part to expanded path */ + strcat(expanded_path, end_path); + + free(cut_path); + return expanded_path; + +error: + free(cut_path); + return NULL; +} + /* * get_session_name * diff --git a/src/bin/lttng/utils.h b/src/bin/lttng/utils.h index 9c51b67e3..a430b8bdf 100644 --- a/src/bin/lttng/utils.h +++ b/src/bin/lttng/utils.h @@ -20,6 +20,7 @@ #include +char *expand_full_path(const char *path); char *get_config_file_path(void); char *get_session_name(void); int set_session_name(char *name);