Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 26 May 2016 08:41:55 +0000 (UTC)
From:      Hans Petter Selasky <hselasky@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r300718 - in head/sys: kern sys
Message-ID:  <201605260841.u4Q8ft9r045564@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: hselasky
Date: Thu May 26 08:41:55 2016
New Revision: 300718
URL: https://svnweb.freebsd.org/changeset/base/300718

Log:
  Add support for boolean sysctl's.
  
  Because the size of bool can be implementation defined, make a bool
  sysctl handler which handle bools. Userspace sees the bools like
  unsigned 8-bit integers. Values are filtered to either 1 or 0 upon
  read and write, similar to what a compiler would do.
  
  Requested by:	kmacy @
  Sponsored by:	Mellanox Technologies

Modified:
  head/sys/kern/kern_sysctl.c
  head/sys/sys/sysctl.h

Modified: head/sys/kern/kern_sysctl.c
==============================================================================
--- head/sys/kern/kern_sysctl.c	Thu May 26 08:31:09 2016	(r300717)
+++ head/sys/kern/kern_sysctl.c	Thu May 26 08:41:55 2016	(r300718)
@@ -1181,6 +1181,41 @@ static SYSCTL_NODE(_sysctl, 5, oiddescr,
  */
 
 /*
+ * Handle a bool.
+ * Two cases:
+ *     a variable:  point arg1 at it.
+ *     a constant:  pass it in arg2.
+ */
+
+int
+sysctl_handle_bool(SYSCTL_HANDLER_ARGS)
+{
+	uint8_t temp;
+	int error;
+
+	/*
+	 * Attempt to get a coherent snapshot by making a copy of the data.
+	 */
+	if (arg1)
+		temp = *(bool *)arg1 ? 1 : 0;
+	else
+		temp = arg2 ? 1 : 0;
+
+	error = SYSCTL_OUT(req, &temp, sizeof(temp));
+	if (error || !req->newptr)
+		return (error);
+
+	if (!arg1)
+		error = EPERM;
+	else {
+		error = SYSCTL_IN(req, &temp, sizeof(temp));
+		if (!error)
+			*(bool *)arg1 = temp ? 1 : 0;
+	}
+	return (error);
+}
+
+/*
  * Handle an int8_t, signed or unsigned.
  * Two cases:
  *     a variable:  point arg1 at it.

Modified: head/sys/sys/sysctl.h
==============================================================================
--- head/sys/sys/sysctl.h	Thu May 26 08:31:09 2016	(r300717)
+++ head/sys/sys/sysctl.h	Thu May 26 08:41:55 2016	(r300718)
@@ -194,6 +194,7 @@ struct sysctl_oid {
 #define	SYSCTL_OUT(r, p, l)	(r->oldfunc)(r, p, l)
 #define	SYSCTL_OUT_STR(r, p)	(r->oldfunc)(r, p, strlen(p) + 1)
 
+int sysctl_handle_bool(SYSCTL_HANDLER_ARGS);
 int sysctl_handle_8(SYSCTL_HANDLER_ARGS);
 int sysctl_handle_16(SYSCTL_HANDLER_ARGS);
 int sysctl_handle_32(SYSCTL_HANDLER_ARGS);
@@ -329,6 +330,24 @@ TAILQ_HEAD(sysctl_ctx_list, sysctl_ctx_e
 	    __arg, len, sysctl_handle_string, "A", __DESCR(descr));	\
 })
 
+/* Oid for a bool.  If ptr is NULL, val is returned. */
+#define	SYSCTL_NULL_BOOL_PTR ((bool *)NULL)
+#define	SYSCTL_BOOL(parent, nbr, name, access, ptr, val, descr)	\
+	SYSCTL_OID(parent, nbr, name,				\
+	    CTLTYPE_U8 | CTLFLAG_MPSAFE | (access),		\
+	    ptr, val, sysctl_handle_bool, "CU", descr);		\
+	CTASSERT(((access) & CTLTYPE) == 0 &&			\
+	    sizeof(bool) == sizeof(*(ptr)))
+
+#define	SYSCTL_ADD_BOOL(ctx, parent, nbr, name, access, ptr, val, descr) \
+({									\
+	bool *__ptr = (ptr);						\
+	CTASSERT(((access) & CTLTYPE) == 0);				\
+	sysctl_add_oid(ctx, parent, nbr, name,				\
+	    CTLTYPE_U8 | CTLFLAG_MPSAFE | (access),			\
+	    __ptr, val, sysctl_handle_bool, "CU", __DESCR(descr));	\
+})
+
 /* Oid for a signed 8-bit int.  If ptr is NULL, val is returned. */
 #define	SYSCTL_NULL_S8_PTR ((int8_t *)NULL)
 #define	SYSCTL_S8(parent, nbr, name, access, ptr, val, descr)	\



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201605260841.u4Q8ft9r045564>