blob: 048cdd543830418bfe53957b278ab654ecfdcb66 [file] [log] [blame]
Elijah Newrenac48adf2023-02-24 00:09:31 +00001#include "git-compat-util.h"
Jeff Hostetlerbce9db62019-04-15 13:39:47 -07002#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 */
10struct 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 *
SZEDER Gábore4b75d62019-05-19 16:43:08 +020024 * We do not define entries for the GIT_TRACE2_PARENT_* environment
Jeff Hostetlerbce9db62019-04-15 13:39:47 -070025 * 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 */
29static struct tr2_sysenv_entry tr2_sysenv_settings[] = {
SZEDER Gábore4b75d62019-05-19 16:43:08 +020030 [TR2_SYSENV_CFG_PARAM] = { "GIT_TRACE2_CONFIG_PARAMS",
Jeff Hostetlerbce9db62019-04-15 13:39:47 -070031 "trace2.configparams" },
Josh Steadmon3d3adaa2020-03-20 14:06:15 -070032 [TR2_SYSENV_ENV_VARS] = { "GIT_TRACE2_ENV_VARS",
33 "trace2.envvars" },
Jeff Hostetlerbce9db62019-04-15 13:39:47 -070034
SZEDER Gábore4b75d62019-05-19 16:43:08 +020035 [TR2_SYSENV_DST_DEBUG] = { "GIT_TRACE2_DST_DEBUG",
Jeff Hostetlerbce9db62019-04-15 13:39:47 -070036 "trace2.destinationdebug" },
37
SZEDER Gábore4b75d62019-05-19 16:43:08 +020038 [TR2_SYSENV_NORMAL] = { "GIT_TRACE2",
Jeff Hostetlerbce9db62019-04-15 13:39:47 -070039 "trace2.normaltarget" },
SZEDER Gábore4b75d62019-05-19 16:43:08 +020040 [TR2_SYSENV_NORMAL_BRIEF] = { "GIT_TRACE2_BRIEF",
Jeff Hostetlerbce9db62019-04-15 13:39:47 -070041 "trace2.normalbrief" },
42
SZEDER Gábore4b75d62019-05-19 16:43:08 +020043 [TR2_SYSENV_EVENT] = { "GIT_TRACE2_EVENT",
Jeff Hostetlerbce9db62019-04-15 13:39:47 -070044 "trace2.eventtarget" },
SZEDER Gábore4b75d62019-05-19 16:43:08 +020045 [TR2_SYSENV_EVENT_BRIEF] = { "GIT_TRACE2_EVENT_BRIEF",
Jeff Hostetlerbce9db62019-04-15 13:39:47 -070046 "trace2.eventbrief" },
SZEDER Gábore4b75d62019-05-19 16:43:08 +020047 [TR2_SYSENV_EVENT_NESTING] = { "GIT_TRACE2_EVENT_NESTING",
Jeff Hostetlerbce9db62019-04-15 13:39:47 -070048 "trace2.eventnesting" },
49
SZEDER Gábore4b75d62019-05-19 16:43:08 +020050 [TR2_SYSENV_PERF] = { "GIT_TRACE2_PERF",
Jeff Hostetlerbce9db62019-04-15 13:39:47 -070051 "trace2.perftarget" },
SZEDER Gábore4b75d62019-05-19 16:43:08 +020052 [TR2_SYSENV_PERF_BRIEF] = { "GIT_TRACE2_PERF_BRIEF",
Jeff Hostetlerbce9db62019-04-15 13:39:47 -070053 "trace2.perfbrief" },
Josh Steadmon83e57b02019-10-04 15:08:20 -070054
55 [TR2_SYSENV_MAX_FILES] = { "GIT_TRACE2_MAX_FILES",
56 "trace2.maxfiles" },
Jeff Hostetlerbce9db62019-04-15 13:39:47 -070057};
58/* clang-format on */
59
Glen Chooa4e7e312023-06-28 19:26:22 +000060static int tr2_sysenv_cb(const char *key, const char *value,
Jeff King4b8dd422023-08-29 19:45:23 -040061 const struct config_context *ctx UNUSED,
62 void *d UNUSED)
Jeff Hostetlerbce9db62019-04-15 13:39:47 -070063{
64 int k;
65
66 if (!starts_with(key, "trace2."))
67 return 0;
68
69 for (k = 0; k < ARRAY_SIZE(tr2_sysenv_settings); k++) {
70 if (!strcmp(key, tr2_sysenv_settings[k].git_config_name)) {
Jeff King24942ef2023-12-07 02:11:24 -050071 if (!value)
72 return config_error_nonbool(key);
Jeff Hostetlerbce9db62019-04-15 13:39:47 -070073 free(tr2_sysenv_settings[k].value);
74 tr2_sysenv_settings[k].value = xstrdup(value);
75 return 0;
76 }
77 }
78
79 return 0;
80}
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 */
89void tr2_sysenv_load(void)
90{
91 if (ARRAY_SIZE(tr2_sysenv_settings) != TR2_SYSENV_MUST_BE_LAST)
92 BUG("tr2_sysenv_settings size is wrong");
93
94 read_very_early_config(tr2_sysenv_cb, NULL);
95}
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 */
101const char *tr2_sysenv_get(enum tr2_sysenv_variable var)
102{
103 if (var >= TR2_SYSENV_MUST_BE_LAST)
104 BUG("tr2_sysenv_get invalid var '%d'", var);
105
106 if (!tr2_sysenv_settings[var].getenv_called) {
107 const char *v = getenv(tr2_sysenv_settings[var].env_var_name);
108 if (v && *v) {
109 free(tr2_sysenv_settings[var].value);
110 tr2_sysenv_settings[var].value = xstrdup(v);
111 }
112 tr2_sysenv_settings[var].getenv_called = 1;
113 }
114
115 return tr2_sysenv_settings[var].value;
116}
117
118/*
119 * Return a friendly name for this setting that is suitable for printing
120 * in an error messages.
121 */
122const char *tr2_sysenv_display_name(enum tr2_sysenv_variable var)
123{
124 if (var >= TR2_SYSENV_MUST_BE_LAST)
125 BUG("tr2_sysenv_get invalid var '%d'", var);
126
127 return tr2_sysenv_settings[var].env_var_name;
128}
129
130void tr2_sysenv_release(void)
131{
132 int k;
133
134 for (k = 0; k < ARRAY_SIZE(tr2_sysenv_settings); k++)
135 free(tr2_sysenv_settings[k].value);
136}