Index: usr.sbin/config/config.h =================================================================== --- usr.sbin/config/config.h +++ usr.sbin/config/config.h @@ -140,6 +140,13 @@ SLIST_HEAD(, opt_list) otab; +struct envvar { + char *env_str; + STAILQ_ENTRY(envvar) envvar_next; +}; + +STAILQ_HEAD(envvar_head, envvar) envvars; + struct hint { char *hint_name; STAILQ_ENTRY(hint) hint_next; Index: usr.sbin/config/config.5 =================================================================== --- usr.sbin/config/config.5 +++ usr.sbin/config/config.5 @@ -23,7 +23,7 @@ .\" .\" $FreeBSD$ .\" -.Dd February 21, 2016 +.Dd June 22, 2018 .Dt CONFIG 5 .Os .Sh NAME @@ -124,6 +124,20 @@ This directive is useful for setting kernel tunables in embedded environments that do not start from .Xr loader 8 . +.\" -------- ENVVAR -------- +.Pp +.It Ic envvar Ar setting +Specifies an individual environment setting to be added to the kernel's +compiled-in environment. +.Ar setting +must be of the form +.Dq Va name=value +without any quotes included in the value or the right hand side of the setting. +All environment variables specified with +.Ic envvar +will be set after any +.Ic env +files are included. .\" -------- FILES -------- .Pp .It Ic files Ar filename Index: usr.sbin/config/config.y =================================================================== --- usr.sbin/config/config.y +++ usr.sbin/config/config.y @@ -12,6 +12,7 @@ %token DEVICE %token NODEVICE %token ENV +%token ENVVAR %token EQUALS %token PLUSEQUALS %token HINTS @@ -193,6 +194,15 @@ env = $2; envmode = 1; } | + ENVVAR ID { + 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); + } | HINTS ID { struct hint *hint; Index: usr.sbin/config/lang.l =================================================================== --- usr.sbin/config/lang.l +++ usr.sbin/config/lang.l @@ -70,6 +70,7 @@ { "nodevice", NODEVICE }, { "nodevices", NODEVICE }, { "env", ENV }, + { "envvar", ENVVAR }, { "hints", HINTS }, { "ident", IDENT }, { "machine", ARCH }, /* MACHINE is defined in /sys/param.h */ Index: usr.sbin/config/main.c =================================================================== --- usr.sbin/config/main.c +++ usr.sbin/config/main.c @@ -204,6 +204,7 @@ STAILQ_INIT(&fntab); STAILQ_INIT(&ftab); STAILQ_INIT(&hints); + STAILQ_INIT(&envvars); if (yyparse()) exit(3); Index: usr.sbin/config/mkmakefile.c =================================================================== --- usr.sbin/config/mkmakefile.c +++ usr.sbin/config/mkmakefile.c @@ -238,6 +238,36 @@ moveifchanged(path("hints.c.new"), path("hints.c")); } +static void +sanitize_envline(char *line) +{ + char *s; + + /* zap trailing CR and/or LF */ + while ((s = strrchr(line, '\n')) != NULL) + *s = '\0'; + while ((s = strrchr(line, '\r')) != NULL) + *s = '\0'; + /* remove # comments */ + s = strchr(line, '#'); + if (s) + *s = '\0'; + /* remove any whitespace and " characters */ + s = line; + while (*s) { + if (*s == ' ' || *s == '\t' || *s == '"') { + while (*s) { + s[0] = s[1]; + s++; + } + /* start over */ + s = line; + continue; + } + s++; + } +} + /* * Build env.c from the skeleton */ @@ -245,8 +275,8 @@ makeenv(void) { FILE *ifp, *ofp; - char line[BUFSIZ]; - char *s; + char line[BUFSIZ], *linep; + struct envvar *envvar; if (env) { ifp = fopen(env, "r"); @@ -265,35 +295,20 @@ fprintf(ofp, "char static_env[] = {\n"); if (ifp) { while (fgets(line, BUFSIZ, ifp) != NULL) { - /* zap trailing CR and/or LF */ - while ((s = strrchr(line, '\n')) != NULL) - *s = '\0'; - while ((s = strrchr(line, '\r')) != NULL) - *s = '\0'; - /* remove # comments */ - s = strchr(line, '#'); - if (s) - *s = '\0'; - /* remove any whitespace and " characters */ - s = line; - while (*s) { - if (*s == ' ' || *s == '\t' || *s == '"') { - while (*s) { - s[0] = s[1]; - s++; - } - /* start over */ - s = line; - continue; - } - s++; - } + sanitize_envline(line); /* anything left? */ if (*line == '\0') continue; fprintf(ofp, "\"%s\\0\"\n", line); } } + STAILQ_FOREACH(envvar, &envvars, envvar_next) { + linep = envvar->env_str; + sanitize_envline(linep); + if (*linep == '\0') + continue; + fprintf(ofp, "\"%s\\0\"\n", linep); + } fprintf(ofp, "\"\\0\"\n};\n"); if (ifp) fclose(ifp);