X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fbin%2Flttng-crash%2Flttng-crash.c;h=06b3f8a25fa72a0c32f6c64df8cc7a4711ef44f7;hp=c3a8b778925d1de9bed8d191b1eec1324f982d2b;hb=5f98d630e06cc5c89e8601b12be6d70fb7f8093d;hpb=8726a0458b9798953279448c13d8bd60d9907be3 diff --git a/src/bin/lttng-crash/lttng-crash.c b/src/bin/lttng-crash/lttng-crash.c index c3a8b7789..06b3f8a25 100644 --- a/src/bin/lttng-crash/lttng-crash.c +++ b/src/bin/lttng-crash/lttng-crash.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -183,8 +184,8 @@ struct lttng_crash_layout { /* Variables */ static char *progname, - *opt_viewer_path = DEFAULT_VIEWER, - *opt_output_path; + *opt_viewer_path = NULL, + *opt_output_path = NULL; static char *input_path; @@ -274,7 +275,7 @@ static int parse_args(int argc, char **argv) exit(EXIT_FAILURE); } - while ((opt = getopt_long(argc, argv, "+Vhvex:", long_options, NULL)) != -1) { + while ((opt = getopt_long(argc, argv, "+Vhve:x:", long_options, NULL)) != -1) { switch (opt) { case 'V': version(stdout); @@ -291,9 +292,11 @@ static int parse_args(int argc, char **argv) } break; case 'e': + free(opt_viewer_path); opt_viewer_path = strdup(optarg); break; case 'x': + free(opt_output_path); opt_output_path = strdup(optarg); break; case OPT_DUMP_OPTIONS: @@ -306,6 +309,10 @@ static int parse_args(int argc, char **argv) } } + if (!opt_viewer_path) { + opt_viewer_path = DEFAULT_VIEWER; + } + /* No leftovers, or more than one input path, print usage and quit */ if ((argc - optind) == 0 || (argc - optind) > 1) { usage(stderr); @@ -661,7 +668,7 @@ int copy_crash_subbuf(const struct lttng_crash_layout *layout, return -EINVAL; } - DBG("Copy crash subbuffer at offset %lu", offset); + DBG("Copy crash subbuffer at offset %" PRIu64, offset); sbidx = subbuf_index(offset, buf_size, subbuf_size); /* @@ -1027,6 +1034,7 @@ int extract_trace_recursive(const char *output_path, break; } case DT_REG: + case DT_LNK: if (!strcmp(entry->d_name, "metadata")) { ret = extract_one_trace(output_path, input_path); @@ -1052,35 +1060,62 @@ end: } static -int delete_trace(const char *trace_path) +int delete_dir_recursive(const char *path) { - DIR *trace_dir; - int trace_dir_fd, ret = 0, closeret; + DIR *dir; + int dir_fd, ret = 0, closeret; struct dirent *entry; /* Open trace directory */ - trace_dir = opendir(trace_path); - if (!trace_dir) { - PERROR("Cannot open '%s' path", trace_path); - return -1; + dir = opendir(path); + if (!dir) { + PERROR("Cannot open '%s' path", path); + ret = -errno; + goto end; } - trace_dir_fd = dirfd(trace_dir); - if (trace_dir_fd < 0) { + dir_fd = dirfd(dir); + if (dir_fd < 0) { PERROR("dirfd"); - return -1; + ret = -errno; + goto end; } - while ((entry = readdir(trace_dir))) { + while ((entry = readdir(dir))) { if (!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, "..")) { continue; } switch (entry->d_type) { case DT_DIR: - unlinkat(trace_dir_fd, entry->d_name, AT_REMOVEDIR); + { + char *subpath = zmalloc(PATH_MAX); + + if (!subpath) { + PERROR("zmalloc path"); + ret = -1; + goto end; + } + strncpy(subpath, path, PATH_MAX); + subpath[PATH_MAX - 1] = '\0'; + strncat(subpath, "/", + PATH_MAX - strlen(subpath) - 1); + strncat(subpath, entry->d_name, + PATH_MAX - strlen(subpath) - 1); + + ret = delete_dir_recursive(subpath); + free(subpath); + if (ret) { + /* Error occured, abort traversal. */ + goto end; + } break; + } case DT_REG: - unlinkat(trace_dir_fd, entry->d_name, 0); + ret = unlinkat(dir_fd, entry->d_name, 0); + if (ret) { + PERROR("Unlinking '%s'", entry->d_name); + goto end; + } break; default: ret = -EINVAL; @@ -1088,13 +1123,16 @@ int delete_trace(const char *trace_path) } } end: - closeret = closedir(trace_dir); + if (!ret) { + ret = rmdir(path); + if (ret) { + PERROR("rmdir '%s'", path); + } + } + closeret = closedir(dir); if (closeret) { PERROR("closedir"); } - if (!ret) { - ret = rmdir(trace_path); - } return ret; } @@ -1136,7 +1174,8 @@ int view_trace(const char *viewer_path, const char *trace_path) */ int main(int argc, char *argv[]) { - int ret, has_warning = 0; + int ret; + bool has_warning = false; const char *output_path = NULL; char tmppath[] = "/tmp/lttng-crash-XXXXXX"; @@ -1144,9 +1183,10 @@ int main(int argc, char *argv[]) ret = parse_args(argc, argv); if (ret > 0) { - exit(EXIT_SUCCESS); + goto end; } else if (ret < 0) { - exit(EXIT_FAILURE); + has_warning = true; + goto end; } if (opt_output_path) { @@ -1154,34 +1194,38 @@ int main(int argc, char *argv[]) ret = mkdir(output_path, S_IRWXU | S_IRWXG); if (ret) { PERROR("mkdir"); - exit(EXIT_FAILURE); + has_warning = true; + goto end; } } else { output_path = mkdtemp(tmppath); if (!output_path) { PERROR("mkdtemp"); - exit(EXIT_FAILURE); + has_warning = true; + goto end; } } ret = extract_trace_recursive(output_path, input_path); if (ret < 0) { - exit(EXIT_FAILURE); + has_warning = true; + goto end; } else if (ret > 0) { - has_warning = 1; + /* extract_trace_recursive reported a warning. */ + has_warning = true; } if (!opt_output_path) { /* View trace */ ret = view_trace(opt_viewer_path, output_path); - if (ret) - has_warning = 1; - + if (ret) { + has_warning = true; + } /* unlink temporary trace */ - ret = delete_trace(output_path); - if (ret) - has_warning = 1; + ret = delete_dir_recursive(output_path); + if (ret) { + has_warning = true; + } } - if (has_warning) - exit(EXIT_FAILURE); - exit(EXIT_SUCCESS); +end: + exit(has_warning ? EXIT_FAILURE : EXIT_SUCCESS); }