Date: Mon, 21 Sep 2020 15:24:44 +0000 (UTC) From: Mitchell Horne <mhorne@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r365945 - in head: share/man/man9 sys/kern sys/sys Message-ID: <202009211524.08LFOiCh091108@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: mhorne Date: Mon Sep 21 15:24:44 2020 New Revision: 365945 URL: https://svnweb.freebsd.org/changeset/base/365945 Log: Add getenv(9) boolean parsing functions This adds the getenv_bool() function, to parse a boolean value from a kernel environment variable or tunable. This works for traditional boolean values like "0" and "1", and also "true" and "false" (case-insensitive). These semantics do not yet apply to sysctls declared using SYSCTL_BOOL with CTLFLAG_TUN (they still only parse 1 and 0). Also added are two wrapper functions, getenv_is_true() and getenv_is_false(). These are slightly simpler for callers wishing to perform a single check of a configuration variable. Reviewed by: jhb (slightly earlier version) Sponsored by: NetApp, Inc. Sponsored by: Klara, Inc. Differential Revision: https://reviews.freebsd.org/D26270 Modified: head/share/man/man9/Makefile head/share/man/man9/getenv.9 head/sys/kern/kern_environment.c head/sys/sys/kernel.h head/sys/sys/systm.h Modified: head/share/man/man9/Makefile ============================================================================== --- head/share/man/man9/Makefile Mon Sep 21 12:37:41 2020 (r365944) +++ head/share/man/man9/Makefile Mon Sep 21 15:24:44 2020 (r365945) @@ -1092,6 +1092,9 @@ MLINKS+=getenv.9 freeenv.9 \ getenv.9 getenv_quad.9 \ getenv.9 getenv_uint.9 \ getenv.9 getenv_ulong.9 \ + getenv.9 getenv_bool.9 \ + getenv.9 getenv_is_true.9 \ + getenv.9 getenv_is_false.9 \ getenv.9 kern_getenv.9 \ getenv.9 kern_setenv.9 \ getenv.9 kern_unsetenv.9 \ Modified: head/share/man/man9/getenv.9 ============================================================================== --- head/share/man/man9/getenv.9 Mon Sep 21 12:37:41 2020 (r365944) +++ head/share/man/man9/getenv.9 Mon Sep 21 15:24:44 2020 (r365945) @@ -27,7 +27,7 @@ .\" .\" $FreeBSD$ .\" -.Dd June 1, 2017 +.Dd September 21, 2020 .Dt GETENV 9 .Os .Sh NAME @@ -39,6 +39,9 @@ .Nm getenv_quad , .Nm getenv_uint , .Nm getenv_ulong , +.Nm getenv_bool , +.Nm getenv_is_true , +.Nm getenv_is_false , .Nm kern_setenv , .Nm testenv , .Nm kern_unsetenv @@ -63,6 +66,12 @@ .Ft int .Fn getenv_ulong "const char *name" "unsigned long *data" .Ft int +.Fn getenv_bool "const char *name" "bool *data" +.Ft bool +.Fn getenv_is_true "const char *name" +.Ft bool +.Fn getenv_is_false "const char *name" +.Ft int .Fn kern_setenv "const char *name" "const char *value" .Ft int .Fn testenv "const char *name" @@ -194,6 +203,28 @@ up to characters of its value are copied to the buffer pointed to by .Fa data followed by a null character and a non-zero value is returned. +.Pp +The +.Fn getenv_bool +function interprets the value of the kernel environment variable +.Fa name +as a boolean value by performing a case-insensitive comparison against the +strings "1", +"0", +"true", +and "false". +If the environment variable exists and has a valid boolean value, then that +value will be copied to the variable pointed to by +.Fa data . +If the environment variable exists but is not a boolean value, then a warning +will be printed to the kernel message buffer. +The +.Fn getenv_is_true +and +.Fn getenv_is_false +functions are wrappers around +.Fn getenv_bool +that simplify testing for a desired boolean value. .Sh RETURN VALUES The .Fn kern_getenv @@ -211,12 +242,25 @@ The .Fn testenv function returns zero if the specified environment variable does not exist and a non-zero value if it does exist. +.Pp The .Fn getenv_int , .Fn getenv_long , .Fn getenv_string , .Fn getenv_quad , .Fn getenv_uint , +.Fn getenv_ulong , and -.Fn getenv_ulong +.Fn getenv_bool functions return a non-zero value on success and zero on failure. +.Pp +The +.Fn getenv_is_true +and +.Fn getenv_is_false +functions return +.Dv true +if the specified environment variable exists and its value matches the desired +boolean condition, and +.Dv false +otherwise. Modified: head/sys/kern/kern_environment.c ============================================================================== --- head/sys/kern/kern_environment.c Mon Sep 21 12:37:41 2020 (r365944) +++ head/sys/kern/kern_environment.c Mon Sep 21 15:24:44 2020 (r365945) @@ -942,6 +942,65 @@ error: } /* + * Return a boolean value from an environment variable. This can be in + * numerical or string form, i.e. "1" or "true". + */ +int +getenv_bool(const char *name, bool *data) +{ + char *val; + int ret = 0; + + if (name == NULL) + return (0); + + val = kern_getenv(name); + if (val == NULL) + return (0); + + if ((strcmp(val, "1") == 0) || (strcasecmp(val, "true") == 0)) { + *data = true; + ret = 1; + } else if ((strcmp(val, "0") == 0) || (strcasecmp(val, "false") == 0)) { + *data = false; + ret = 1; + } else { + /* Spit out a warning for malformed boolean variables. */ + printf("Environment variable %s has non-boolean value \"%s\"\n", + name, val); + } + freeenv(val); + + return (ret); +} + +/* + * Wrapper around getenv_bool to easily check for true. + */ +bool +getenv_is_true(const char *name) +{ + bool val; + + if (getenv_bool(name, &val) != 0) + return (val); + return (false); +} + +/* + * Wrapper around getenv_bool to easily check for false. + */ +bool +getenv_is_false(const char *name) +{ + bool val; + + if (getenv_bool(name, &val) != 0) + return (!val); + return (false); +} + +/* * Find the next entry after the one which (cp) falls within, return a * pointer to its start or NULL if there are no more. */ @@ -1005,6 +1064,14 @@ tunable_quad_init(void *data) struct tunable_quad *d = (struct tunable_quad *)data; TUNABLE_QUAD_FETCH(d->path, d->var); +} + +void +tunable_bool_init(void *data) +{ + struct tunable_bool *d = (struct tunable_bool *)data; + + TUNABLE_BOOL_FETCH(d->path, d->var); } void Modified: head/sys/sys/kernel.h ============================================================================== --- head/sys/sys/kernel.h Mon Sep 21 12:37:41 2020 (r365944) +++ head/sys/sys/kernel.h Mon Sep 21 15:24:44 2020 (r365945) @@ -421,6 +421,25 @@ struct tunable_quad { #define TUNABLE_QUAD_FETCH(path, var) getenv_quad((path), (var)) +/* + * bool + */ +extern void tunable_bool_init(void *); +struct tunable_bool { + const char *path; + bool *var; +}; +#define TUNABLE_BOOL(path, var) \ + static struct tunable_bool __CONCAT(__tunable_bool_, __LINE__) = { \ + (path), \ + (var), \ + }; \ + SYSINIT(__CONCAT(__Tunable_init_, __LINE__), \ + SI_SUB_TUNABLES, SI_ORDER_MIDDLE, tunable_bool_init, \ + &__CONCAT(__tunable_bool_, __LINE__)) + +#define TUNABLE_BOOL_FETCH(path, var) getenv_bool((path), (var)) + extern void tunable_str_init(void *); struct tunable_str { const char *path; Modified: head/sys/sys/systm.h ============================================================================== --- head/sys/sys/systm.h Mon Sep 21 12:37:41 2020 (r365944) +++ head/sys/sys/systm.h Mon Sep 21 15:24:44 2020 (r365945) @@ -461,6 +461,9 @@ int getenv_string(const char *name, char *data, int si int getenv_int64(const char *name, int64_t *data); int getenv_uint64(const char *name, uint64_t *data); int getenv_quad(const char *name, quad_t *data); +int getenv_bool(const char *name, bool *data); +bool getenv_is_true(const char *name); +bool getenv_is_false(const char *name); int kern_setenv(const char *name, const char *value); int kern_unsetenv(const char *name); int testenv(const char *name);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202009211524.08LFOiCh091108>