Coverage Report

Created: 2026-01-09 07:10

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