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
This commit is contained in:
parent
aea49d9fed
commit
cba446e2c2
@ -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 \
|
||||
|
@ -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.
|
||||
|
@ -941,6 +941,65 @@ getenv_quad(const char *name, quad_t *data)
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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.
|
||||
@ -1007,6 +1066,14 @@ tunable_quad_init(void *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
|
||||
tunable_str_init(void *data)
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -461,6 +461,9 @@ int getenv_string(const char *name, char *data, int size);
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user