config(8): Make 'env' files consistent with other file-accepting options
Previously, only one 'env' file could be specified. Later 'env' directives would overwrite earlier 'env' directives. This is inconsistent with every other file-accepting directives which process files in order, including hints. A caveat applies to both hints and env that isn't mentioned: they're concatenated in the order of appearance, so they're not actually applied in the way one might think by supplying: hints x hints y Hints in x will take precedence over same-name hints in y due to how the kernel processes them, stopping at the first line that matches the hint we're searching for. Future work will flip the order of concatenation so that later files may still properly override earlier files. In practice, this likely doesn't matter at all due to the nature of the beast.
This commit is contained in:
parent
120832ac31
commit
b77bd81b37
@ -23,7 +23,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd June 22, 2018
|
||||
.Dd June 26, 2018
|
||||
.Dt CONFIG 5
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -124,6 +124,18 @@ the compiled-in environment instead, unless the boot environment contains
|
||||
This directive is useful for setting kernel tunables in
|
||||
embedded environments that do not start from
|
||||
.Xr loader 8 .
|
||||
.Pp
|
||||
All
|
||||
.Ic env
|
||||
and
|
||||
.Ic envvar
|
||||
directives will be processed and added to the staitc environment in the order of
|
||||
appearance.
|
||||
Note that within
|
||||
.Ar filename ,
|
||||
the first appearance of a given variable will be the first one seen by the
|
||||
kernel, effectively shadowing any later appearances of the same variable within
|
||||
.Ar filename .
|
||||
.\" -------- ENVVAR --------
|
||||
.Pp
|
||||
.It Ic envvar Ar setting
|
||||
@ -133,11 +145,13 @@ compiled-in environment.
|
||||
must be of the form
|
||||
.Dq Va name=value .
|
||||
Optional quotes are supported in both name and value.
|
||||
All environment variables specified with
|
||||
.Ic envvar
|
||||
will be set after any
|
||||
.Pp
|
||||
All
|
||||
.Ic env
|
||||
files are included.
|
||||
and
|
||||
.Ic envvar
|
||||
directives will be processed and added to the staitc environment in the order of
|
||||
appearance.
|
||||
.\" -------- FILES --------
|
||||
.Pp
|
||||
.It Ic files Ar filename
|
||||
|
@ -37,6 +37,7 @@
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
#include <sys/queue.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
@ -142,6 +143,7 @@ SLIST_HEAD(, opt_list) otab;
|
||||
|
||||
struct envvar {
|
||||
char *env_str;
|
||||
bool env_is_file;
|
||||
STAILQ_ENTRY(envvar) envvar_next;
|
||||
};
|
||||
|
||||
@ -175,7 +177,6 @@ SLIST_HEAD(, includepath) includepath;
|
||||
#define OPT_AUTOGEN "CONFIG_AUTOGENERATED"
|
||||
|
||||
extern char *ident;
|
||||
extern char *env;
|
||||
extern char kernconfstr[];
|
||||
extern int do_trace;
|
||||
extern int envmode;
|
||||
|
@ -82,7 +82,6 @@
|
||||
|
||||
struct device_head dtab;
|
||||
char *ident;
|
||||
char *env;
|
||||
int envmode;
|
||||
int hintmode;
|
||||
int yyline;
|
||||
@ -99,6 +98,7 @@ int yywrap(void);
|
||||
|
||||
static void newdev(char *name);
|
||||
static void newfile(char *name);
|
||||
static void newenvvar(char *name, bool is_file);
|
||||
static void rmdev_schedule(struct device_head *dh, char *name);
|
||||
static void newopt(struct opt_head *list, char *name, char *value, int append);
|
||||
static void rmopt_schedule(struct opt_head *list, char *name);
|
||||
@ -191,20 +191,8 @@ Config_spec:
|
||||
|
|
||||
MAXUSERS NUMBER { maxusers = $2; } |
|
||||
PROFILE NUMBER { profiling = $2; } |
|
||||
ENV ID {
|
||||
env = $2;
|
||||
envmode = 1;
|
||||
} |
|
||||
ENVVAR ENVLINE {
|
||||
struct envvar *envvar;
|
||||
|
||||
envvar = (struct envvar *)calloc(1, sizeof (struct envvar));
|
||||
if (envvar == NULL)
|
||||
err(EXIT_FAILURE, "calloc");
|
||||
envvar->env_str = $2;
|
||||
STAILQ_INSERT_TAIL(&envvars, envvar, envvar_next);
|
||||
envmode = 1;
|
||||
} |
|
||||
ENV ID { newenvvar($2, true); } |
|
||||
ENVVAR ENVLINE { newenvvar($2, false); } |
|
||||
HINTS ID {
|
||||
struct hint *hint;
|
||||
|
||||
@ -361,7 +349,21 @@ newfile(char *name)
|
||||
nl->f_name = name;
|
||||
STAILQ_INSERT_TAIL(&fntab, nl, f_next);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
newenvvar(char *name, bool is_file)
|
||||
{
|
||||
struct envvar *envvar;
|
||||
|
||||
envvar = (struct envvar *)calloc(1, sizeof (struct envvar));
|
||||
if (envvar == NULL)
|
||||
err(EXIT_FAILURE, "calloc");
|
||||
envvar->env_str = name;
|
||||
envvar->env_is_file = is_file;
|
||||
STAILQ_INSERT_TAIL(&envvars, envvar, envvar_next);
|
||||
envmode = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Find a device in the list of devices.
|
||||
*/
|
||||
|
@ -306,13 +306,6 @@ makeenv(void)
|
||||
char line[BUFSIZ], result[BUFSIZ], *linep;
|
||||
struct envvar *envvar;
|
||||
|
||||
if (env) {
|
||||
ifp = fopen(env, "r");
|
||||
if (ifp == NULL)
|
||||
err(1, "%s", env);
|
||||
} else {
|
||||
ifp = NULL;
|
||||
}
|
||||
ofp = fopen(path("env.c.new"), "w");
|
||||
if (ofp == NULL)
|
||||
err(1, "%s", path("env.c.new"));
|
||||
@ -321,22 +314,27 @@ makeenv(void)
|
||||
fprintf(ofp, "\n");
|
||||
fprintf(ofp, "int envmode = %d;\n", envmode);
|
||||
fprintf(ofp, "char static_env[] = {\n");
|
||||
if (ifp) {
|
||||
while (fgets(line, BUFSIZ, ifp) != NULL) {
|
||||
sanitize_envline(result, line);
|
||||
/* anything left? */
|
||||
STAILQ_FOREACH(envvar, &envvars, envvar_next) {
|
||||
if (envvar->env_is_file) {
|
||||
ifp = fopen(envvar->env_str, "r");
|
||||
if (ifp == NULL)
|
||||
err(1, "%s", envvar->env_str);
|
||||
while (fgets(line, BUFSIZ, ifp) != NULL) {
|
||||
sanitize_envline(result, line);
|
||||
/* anything left? */
|
||||
if (*result == '\0')
|
||||
continue;
|
||||
fprintf(ofp, "\"%s\\0\"\n", result);
|
||||
}
|
||||
fclose(ifp);
|
||||
} else {
|
||||
linep = envvar->env_str;
|
||||
sanitize_envline(result, linep);
|
||||
if (*result == '\0')
|
||||
continue;
|
||||
fprintf(ofp, "\"%s\\0\"\n", result);
|
||||
}
|
||||
}
|
||||
STAILQ_FOREACH(envvar, &envvars, envvar_next) {
|
||||
linep = envvar->env_str;
|
||||
sanitize_envline(result, linep);
|
||||
if (*result == '\0')
|
||||
continue;
|
||||
fprintf(ofp, "\"%s\\0\"\n", result);
|
||||
}
|
||||
fprintf(ofp, "\"\\0\"\n};\n");
|
||||
if (ifp)
|
||||
fclose(ifp);
|
||||
|
Loading…
x
Reference in New Issue
Block a user