svn commit: r365945 - in head: share/man/man9 sys/kern sys/sys

Mitchell Horne mhorne at FreeBSD.org
Mon Sep 21 15:24:46 UTC 2020


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);


More information about the svn-src-head mailing list