11#include "cache.h"
22#include "trace2/tr2_dst.h"
3+ #include "trace2/tr2_sid.h"
34
45/*
56 * If a Trace2 target cannot be opened for writing, we should issue a
1213 */
1314#define TR2_ENVVAR_DST_DEBUG "GIT_TR2_DST_DEBUG"
1415
16+ /*
17+ * How many attempts we will make at creating an automatically-named trace file.
18+ */
19+ #define MAX_AUTO_ATTEMPTS 10
20+
1521static int tr2_dst_want_warning (void )
1622{
1723 static int tr2env_dst_debug = -1 ;
@@ -36,6 +42,55 @@ void tr2_dst_trace_disable(struct tr2_dst *dst)
3642 dst -> need_close = 0 ;
3743}
3844
45+ static int tr2_dst_try_auto_path (struct tr2_dst * dst , const char * tgt_prefix )
46+ {
47+ int fd ;
48+ const char * last_slash , * sid = tr2_sid_get ();
49+ struct strbuf path = STRBUF_INIT ;
50+ size_t base_path_len ;
51+ unsigned attempt_count ;
52+
53+ last_slash = strrchr (sid , '/' );
54+ if (last_slash )
55+ sid = last_slash + 1 ;
56+
57+ strbuf_addstr (& path , tgt_prefix );
58+ if (!is_dir_sep (path .buf [path .len - 1 ]))
59+ strbuf_addch (& path , '/' );
60+ strbuf_addstr (& path , sid );
61+ base_path_len = path .len ;
62+
63+ for (attempt_count = 0 ; attempt_count < MAX_AUTO_ATTEMPTS ; attempt_count ++ ) {
64+ if (attempt_count > 0 ) {
65+ strbuf_setlen (& path , base_path_len );
66+ strbuf_addf (& path , ".%d" , attempt_count );
67+ }
68+
69+ fd = open (path .buf , O_WRONLY | O_CREAT | O_EXCL , 0666 );
70+ if (fd != -1 )
71+ break ;
72+ }
73+
74+ if (fd == -1 ) {
75+ if (tr2_dst_want_warning ())
76+ warning ("trace2: could not open '%.*s' for '%s' tracing: %s" ,
77+ (int ) base_path_len , path .buf ,
78+ dst -> env_var_name , strerror (errno ));
79+
80+ tr2_dst_trace_disable (dst );
81+ strbuf_release (& path );
82+ return 0 ;
83+ }
84+
85+ strbuf_release (& path );
86+
87+ dst -> fd = fd ;
88+ dst -> need_close = 1 ;
89+ dst -> initialized = 1 ;
90+
91+ return dst -> fd ;
92+ }
93+
3994static int tr2_dst_try_path (struct tr2_dst * dst , const char * tgt_value )
4095{
4196 int fd = open (tgt_value , O_WRONLY | O_APPEND | O_CREAT , 0666 );
@@ -202,8 +257,12 @@ int tr2_dst_get_trace_fd(struct tr2_dst *dst)
202257 return dst -> fd ;
203258 }
204259
205- if (is_absolute_path (tgt_value ))
206- return tr2_dst_try_path (dst , tgt_value );
260+ if (is_absolute_path (tgt_value )) {
261+ if (is_directory (tgt_value ))
262+ return tr2_dst_try_auto_path (dst , tgt_value );
263+ else
264+ return tr2_dst_try_path (dst , tgt_value );
265+ }
207266
208267#ifndef NO_UNIX_SOCKETS
209268 if (starts_with (tgt_value , PREFIX_AF_UNIX ))
0 commit comments