26
#include "quote.h"
27
28
/* Get a trace file descriptor from "key" env variable. */
29
-static int get_trace_fd(const char *key, int *need_close)
29
+static int get_trace_fd(struct trace_key *key)
30
{
31
- char *trace = getenv(key);
31
+ static struct trace_key trace_default = { "GIT_TRACE" };
32
+ const char *trace;
33
+
34
+ /* use default "GIT_TRACE" if NULL */
35
+ if (!key)
36
+ key = &trace_default;
37
+
38
+ /* don't open twice */
39
+ if (key->initialized)
40
+ return key->fd;
41
+
42
+ trace = getenv(key->key);
43
44
if (!trace || !strcmp(trace, "") ||
45
!strcmp(trace, "0") || !strcasecmp(trace, "false"))
35
- return 0;
36
- if (!strcmp(trace, "1") || !strcasecmp(trace, "true"))
37
- return STDERR_FILENO;
38
- if (strlen(trace) == 1 && isdigit(*trace))
39
- return atoi(trace);
40
- if (is_absolute_path(trace)) {
46
+ key->fd = 0;
47
+ else if (!strcmp(trace, "1") || !strcasecmp(trace, "true"))
48
+ key->fd = STDERR_FILENO;
49
+ else if (strlen(trace) == 1 && isdigit(*trace))
50
+ key->fd = atoi(trace);
51
+ else if (is_absolute_path(trace)) {
52
int fd = open(trace, O_WRONLY | O_APPEND | O_CREAT, 0666);
53
if (fd == -1) {
54
fprintf(stderr,
55
"Could not open '%s' for tracing: %s\n"
56
"Defaulting to tracing on stderr...\n",
57
trace, strerror(errno));
47
- return STDERR_FILENO;
58
+ key->fd = STDERR_FILENO;
59
+ } else {
60
+ key->fd = fd;
61
+ key->need_close = 1;
62
}
49
- *need_close = 1;
50
- return fd;
63
+ } else {
64
+ fprintf(stderr, "What does '%s' for %s mean?\n"
65
+ "If you want to trace into a file, then please set "
66
+ "%s to an absolute pathname (starting with /).\n"
67
+ "Defaulting to tracing on stderr...\n",
68
+ trace, key->key, key->key);
69
+ key->fd = STDERR_FILENO;
70
}
71
53
- fprintf(stderr, "What does '%s' for %s mean?\n", trace, key);
54
- fprintf(stderr, "If you want to trace into a file, "
55
- "then please set %s to an absolute pathname "
56
- "(starting with /).\n", key);
57
- fprintf(stderr, "Defaulting to tracing on stderr...\n");
72
+ key->initialized = 1;
73
+ return key->fd;
74
+}
75
59
- return STDERR_FILENO;
76
+void trace_disable(struct trace_key *key)
77
+{
78
+ if (key->need_close)
79
+ close(key->fd);
80
+ key->fd = 0;
81
+ key->initialized = 1;
82
+ key->need_close = 0;
83
}
84
85
static const char err_msg[] = "Could not trace into fd given by "
86
"GIT_TRACE environment variable";
87
65
-static void trace_vprintf(const char *key, const char *format, va_list ap)
88
+static void trace_vprintf(struct trace_key *key, const char *format, va_list ap)
89
{
90
struct strbuf buf = STRBUF_INIT;
91
98
strbuf_release(&buf);
99
}
100
78
-void trace_printf_key(const char *key, const char *format, ...)
101
+void trace_printf_key(struct trace_key *key, const char *format, ...)
102
{
103
va_list ap;
104
va_start(ap, format);
110
{
111
va_list ap;
112
va_start(ap, format);
90
- trace_vprintf("GIT_TRACE", format, ap);
113
+ trace_vprintf(NULL, format, ap);
114
va_end(ap);
115
}
116
94
-void trace_strbuf(const char *key, const struct strbuf *buf)
117
+void trace_strbuf(struct trace_key *key, const struct strbuf *buf)
118
{
96
- int fd, need_close = 0;
97
-
98
- fd = get_trace_fd(key, &need_close);
119
+ int fd = get_trace_fd(key);
120
if (!fd)
121
return;
122
123
write_or_whine_pipe(fd, buf->buf, buf->len, err_msg);
103
-
104
- if (need_close)
105
- close(fd);
124
}
125
126
void trace_argv_printf(const char **argv, const char *format, ...)
127
{
128
struct strbuf buf = STRBUF_INIT;
129
va_list ap;
112
- int fd, need_close = 0;
113
-
114
- fd = get_trace_fd("GIT_TRACE", &need_close);
130
+ int fd = get_trace_fd(NULL);
131
if (!fd)
132
return;
133
140
strbuf_addch(&buf, '\n');
141
write_or_whine_pipe(fd, buf.buf, buf.len, err_msg);
142
strbuf_release(&buf);
127
-
128
- if (need_close)
129
- close(fd);
143
}
144
145
static const char *quote_crnl(const char *path)
168
/* FIXME: move prefix to startup_info struct and get rid of this arg */
169
void trace_repo_setup(const char *prefix)
170
{
158
- static const char *key = "GIT_TRACE_SETUP";
171
+ static struct trace_key key = TRACE_KEY_INIT(SETUP);
172
const char *git_work_tree;
173
char cwd[PATH_MAX];
174
162
- if (!trace_want(key))
175
+ if (!trace_want(&key))
176
return;
177
178
if (!getcwd(cwd, PATH_MAX))
184
if (!prefix)
185
prefix = "(null)";
186
174
- trace_printf_key(key, "setup: git_dir: %s\n", quote_crnl(get_git_dir()));
175
- trace_printf_key(key, "setup: worktree: %s\n", quote_crnl(git_work_tree));
176
- trace_printf_key(key, "setup: cwd: %s\n", quote_crnl(cwd));
177
- trace_printf_key(key, "setup: prefix: %s\n", quote_crnl(prefix));
187
+ trace_printf_key(&key, "setup: git_dir: %s\n", quote_crnl(get_git_dir()));
188
+ trace_printf_key(&key, "setup: worktree: %s\n", quote_crnl(git_work_tree));
189
+ trace_printf_key(&key, "setup: cwd: %s\n", quote_crnl(cwd));
190
+ trace_printf_key(&key, "setup: prefix: %s\n", quote_crnl(prefix));
191
}
192
180
-int trace_want(const char *key)
193
+int trace_want(struct trace_key *key)
194
{
182
- const char *trace = getenv(key);
183
-
184
- if (!trace || !strcmp(trace, "") ||
185
- !strcmp(trace, "0") || !strcasecmp(trace, "false"))
186
- return 0;
187
- return 1;
195
+ return !!get_trace_fd(key);
196
}