1
1
#include "cache.h"
2
2
#include "trace2/tr2_dst.h"
3
+ #include "trace2/tr2_sid.h"
3
4
4
5
/*
5
6
* If a Trace2 target cannot be opened for writing, we should issue a
12
13
*/
13
14
#define TR2_ENVVAR_DST_DEBUG "GIT_TR2_DST_DEBUG"
14
15
16
+ /*
17
+ * How many attempts we will make at creating an automatically-named trace file.
18
+ */
19
+ #define MAX_AUTO_ATTEMPTS 10
20
+
15
21
static int tr2_dst_want_warning (void )
16
22
{
17
23
static int tr2env_dst_debug = -1 ;
@@ -36,6 +42,55 @@ void tr2_dst_trace_disable(struct tr2_dst *dst)
36
42
dst -> need_close = 0 ;
37
43
}
38
44
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
+
39
94
static int tr2_dst_try_path (struct tr2_dst * dst , const char * tgt_value )
40
95
{
41
96
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)
202
257
return dst -> fd ;
203
258
}
204
259
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
+ }
207
266
208
267
#ifndef NO_UNIX_SOCKETS
209
268
if (starts_with (tgt_value , PREFIX_AF_UNIX ))
0 commit comments