diff options
Diffstat (limited to 'trace2')
-rw-r--r-- | trace2/tr2_dst.c | 67 | ||||
-rw-r--r-- | trace2/tr2_tgt_event.c | 2 | ||||
-rw-r--r-- | trace2/tr2_tgt_normal.c | 2 | ||||
-rw-r--r-- | trace2/tr2_tgt_perf.c | 2 |
4 files changed, 63 insertions, 10 deletions
diff --git a/trace2/tr2_dst.c b/trace2/tr2_dst.c index 7d96f33420..5dda0ca1cd 100644 --- a/trace2/tr2_dst.c +++ b/trace2/tr2_dst.c @@ -1,14 +1,13 @@ #include "cache.h" #include "trace2/tr2_dst.h" +#include "trace2/tr2_sid.h" #include "trace2/tr2_sysenv.h" /* - * If a Trace2 target cannot be opened for writing, we should issue a - * warning to stderr, but this is very annoying if the target is a pipe - * or socket and beyond the user's control -- especially since every - * git command (and sub-command) will print the message. So we silently - * eat these warnings and just discard the trace data. + * How many attempts we will make at creating an automatically-named trace file. */ +#define MAX_AUTO_ATTEMPTS 10 + static int tr2_dst_want_warning(void) { static int tr2env_dst_debug = -1; @@ -33,6 +32,56 @@ void tr2_dst_trace_disable(struct tr2_dst *dst) dst->need_close = 0; } +static int tr2_dst_try_auto_path(struct tr2_dst *dst, const char *tgt_prefix) +{ + int fd; + const char *last_slash, *sid = tr2_sid_get(); + struct strbuf path = STRBUF_INIT; + size_t base_path_len; + unsigned attempt_count; + + last_slash = strrchr(sid, '/'); + if (last_slash) + sid = last_slash + 1; + + strbuf_addstr(&path, tgt_prefix); + if (!is_dir_sep(path.buf[path.len - 1])) + strbuf_addch(&path, '/'); + strbuf_addstr(&path, sid); + base_path_len = path.len; + + for (attempt_count = 0; attempt_count < MAX_AUTO_ATTEMPTS; attempt_count++) { + if (attempt_count > 0) { + strbuf_setlen(&path, base_path_len); + strbuf_addf(&path, ".%d", attempt_count); + } + + fd = open(path.buf, O_WRONLY | O_CREAT | O_EXCL, 0666); + if (fd != -1) + break; + } + + if (fd == -1) { + if (tr2_dst_want_warning()) + warning("trace2: could not open '%.*s' for '%s' tracing: %s", + (int) base_path_len, path.buf, + tr2_sysenv_display_name(dst->sysenv_var), + strerror(errno)); + + tr2_dst_trace_disable(dst); + strbuf_release(&path); + return 0; + } + + strbuf_release(&path); + + dst->fd = fd; + dst->need_close = 1; + dst->initialized = 1; + + return dst->fd; +} + static int tr2_dst_try_path(struct tr2_dst *dst, const char *tgt_value) { int fd = open(tgt_value, O_WRONLY | O_APPEND | O_CREAT, 0666); @@ -203,8 +252,12 @@ int tr2_dst_get_trace_fd(struct tr2_dst *dst) return dst->fd; } - if (is_absolute_path(tgt_value)) - return tr2_dst_try_path(dst, tgt_value); + if (is_absolute_path(tgt_value)) { + if (is_directory(tgt_value)) + return tr2_dst_try_auto_path(dst, tgt_value); + else + return tr2_dst_try_path(dst, tgt_value); + } #ifndef NO_UNIX_SOCKETS if (starts_with(tgt_value, PREFIX_AF_UNIX)) diff --git a/trace2/tr2_tgt_event.c b/trace2/tr2_tgt_event.c index 2c97cf54be..c2852d1bd2 100644 --- a/trace2/tr2_tgt_event.c +++ b/trace2/tr2_tgt_event.c @@ -193,7 +193,7 @@ static void fn_atexit(uint64_t us_elapsed_absolute, int code) static void maybe_add_string_va(struct json_writer *jw, const char *field_name, const char *fmt, va_list ap) { - if (fmt && *fmt && ap) { + if (fmt && *fmt) { va_list copy_ap; struct strbuf buf = STRBUF_INIT; diff --git a/trace2/tr2_tgt_normal.c b/trace2/tr2_tgt_normal.c index 1ce6f97863..00b116d797 100644 --- a/trace2/tr2_tgt_normal.c +++ b/trace2/tr2_tgt_normal.c @@ -127,7 +127,7 @@ static void fn_atexit(uint64_t us_elapsed_absolute, int code) static void maybe_append_string_va(struct strbuf *buf, const char *fmt, va_list ap) { - if (fmt && *fmt && ap) { + if (fmt && *fmt) { va_list copy_ap; va_copy(copy_ap, ap); diff --git a/trace2/tr2_tgt_perf.c b/trace2/tr2_tgt_perf.c index 328d2234bd..ea0cbbe13e 100644 --- a/trace2/tr2_tgt_perf.c +++ b/trace2/tr2_tgt_perf.c @@ -212,7 +212,7 @@ static void fn_atexit(uint64_t us_elapsed_absolute, int code) static void maybe_append_string_va(struct strbuf *buf, const char *fmt, va_list ap) { - if (fmt && *fmt && ap) { + if (fmt && *fmt) { va_list copy_ap; va_copy(copy_ap, ap); |