Coverage Report

Created: 2024-09-08 06:23

/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
}