/src/git/trace2/tr2_sysenv.c
Line | Count | Source (jump to first uncovered line) |
1 | | #include "git-compat-util.h" |
2 | | #include "config.h" |
3 | | #include "dir.h" |
4 | | #include "tr2_sysenv.h" |
5 | | |
6 | | /* |
7 | | * Each entry represents a trace2 setting. |
8 | | * See Documentation/technical/api-trace2.txt |
9 | | */ |
10 | | struct tr2_sysenv_entry { |
11 | | const char *env_var_name; |
12 | | const char *git_config_name; |
13 | | |
14 | | char *value; |
15 | | unsigned int getenv_called : 1; |
16 | | }; |
17 | | |
18 | | /* |
19 | | * This table must match "enum tr2_sysenv_variable" in tr2_sysenv.h. |
20 | | * |
21 | | * The strings in this table are constant and must match the published |
22 | | * config and environment variable names as described in the documentation. |
23 | | * |
24 | | * We do not define entries for the GIT_TRACE2_PARENT_* environment |
25 | | * variables because they are transient and used to pass information |
26 | | * from parent to child git processes, rather than settings. |
27 | | */ |
28 | | /* clang-format off */ |
29 | | static struct tr2_sysenv_entry tr2_sysenv_settings[] = { |
30 | | [TR2_SYSENV_CFG_PARAM] = { "GIT_TRACE2_CONFIG_PARAMS", |
31 | | "trace2.configparams" }, |
32 | | [TR2_SYSENV_ENV_VARS] = { "GIT_TRACE2_ENV_VARS", |
33 | | "trace2.envvars" }, |
34 | | |
35 | | [TR2_SYSENV_DST_DEBUG] = { "GIT_TRACE2_DST_DEBUG", |
36 | | "trace2.destinationdebug" }, |
37 | | |
38 | | [TR2_SYSENV_NORMAL] = { "GIT_TRACE2", |
39 | | "trace2.normaltarget" }, |
40 | | [TR2_SYSENV_NORMAL_BRIEF] = { "GIT_TRACE2_BRIEF", |
41 | | "trace2.normalbrief" }, |
42 | | |
43 | | [TR2_SYSENV_EVENT] = { "GIT_TRACE2_EVENT", |
44 | | "trace2.eventtarget" }, |
45 | | [TR2_SYSENV_EVENT_BRIEF] = { "GIT_TRACE2_EVENT_BRIEF", |
46 | | "trace2.eventbrief" }, |
47 | | [TR2_SYSENV_EVENT_NESTING] = { "GIT_TRACE2_EVENT_NESTING", |
48 | | "trace2.eventnesting" }, |
49 | | |
50 | | [TR2_SYSENV_PERF] = { "GIT_TRACE2_PERF", |
51 | | "trace2.perftarget" }, |
52 | | [TR2_SYSENV_PERF_BRIEF] = { "GIT_TRACE2_PERF_BRIEF", |
53 | | "trace2.perfbrief" }, |
54 | | |
55 | | [TR2_SYSENV_MAX_FILES] = { "GIT_TRACE2_MAX_FILES", |
56 | | "trace2.maxfiles" }, |
57 | | }; |
58 | | /* clang-format on */ |
59 | | |
60 | | static int tr2_sysenv_cb(const char *key, const char *value, |
61 | | const struct config_context *ctx UNUSED, |
62 | | void *d UNUSED) |
63 | 0 | { |
64 | 0 | int k; |
65 | |
|
66 | 0 | if (!starts_with(key, "trace2.")) |
67 | 0 | return 0; |
68 | | |
69 | 0 | for (k = 0; k < ARRAY_SIZE(tr2_sysenv_settings); k++) { |
70 | 0 | if (!strcmp(key, tr2_sysenv_settings[k].git_config_name)) { |
71 | 0 | if (!value) |
72 | 0 | return config_error_nonbool(key); |
73 | 0 | free(tr2_sysenv_settings[k].value); |
74 | 0 | tr2_sysenv_settings[k].value = xstrdup(value); |
75 | 0 | return 0; |
76 | 0 | } |
77 | 0 | } |
78 | | |
79 | 0 | return 0; |
80 | 0 | } |
81 | | |
82 | | /* |
83 | | * Load Trace2 settings from the system config (usually "/etc/gitconfig" |
84 | | * unless we were built with a runtime-prefix). These are intended to |
85 | | * define the default values for Trace2 as requested by the administrator. |
86 | | * |
87 | | * Then override with the Trace2 settings from the global config. |
88 | | */ |
89 | | void tr2_sysenv_load(void) |
90 | 0 | { |
91 | 0 | if (ARRAY_SIZE(tr2_sysenv_settings) != TR2_SYSENV_MUST_BE_LAST) |
92 | 0 | BUG("tr2_sysenv_settings size is wrong"); |
93 | | |
94 | 0 | read_very_early_config(tr2_sysenv_cb, NULL); |
95 | 0 | } |
96 | | |
97 | | /* |
98 | | * Return the value for the requested Trace2 setting from these sources: |
99 | | * the system config, the global config, and the environment. |
100 | | */ |
101 | | const char *tr2_sysenv_get(enum tr2_sysenv_variable var) |
102 | 0 | { |
103 | 0 | if (var >= TR2_SYSENV_MUST_BE_LAST) |
104 | 0 | BUG("tr2_sysenv_get invalid var '%d'", var); |
105 | | |
106 | 0 | if (!tr2_sysenv_settings[var].getenv_called) { |
107 | 0 | const char *v = getenv(tr2_sysenv_settings[var].env_var_name); |
108 | 0 | if (v && *v) { |
109 | 0 | free(tr2_sysenv_settings[var].value); |
110 | 0 | tr2_sysenv_settings[var].value = xstrdup(v); |
111 | 0 | } |
112 | 0 | tr2_sysenv_settings[var].getenv_called = 1; |
113 | 0 | } |
114 | |
|
115 | 0 | return tr2_sysenv_settings[var].value; |
116 | 0 | } |
117 | | |
118 | | /* |
119 | | * Return a friendly name for this setting that is suitable for printing |
120 | | * in an error messages. |
121 | | */ |
122 | | const char *tr2_sysenv_display_name(enum tr2_sysenv_variable var) |
123 | 0 | { |
124 | 0 | if (var >= TR2_SYSENV_MUST_BE_LAST) |
125 | 0 | BUG("tr2_sysenv_get invalid var '%d'", var); |
126 | | |
127 | 0 | return tr2_sysenv_settings[var].env_var_name; |
128 | 0 | } |
129 | | |
130 | | void tr2_sysenv_release(void) |
131 | 0 | { |
132 | 0 | int k; |
133 | |
|
134 | 0 | for (k = 0; k < ARRAY_SIZE(tr2_sysenv_settings); k++) |
135 | 0 | free(tr2_sysenv_settings[k].value); |
136 | 0 | } |