Skip site navigation (1)Skip section navigation (2)
Date:      09 Jan 1999 12:05:20 +0100
From:      Dag-Erling Smorgrav <des@flood.ping.uio.no>
To:        committers@FreeBSD.ORG
Subject:   sysctl descriptions
Message-ID:  <86u2y0btan.fsf@niobe.ewox.org>

next in thread | raw e-mail | index | archive | help
The attached patches implement a mechanism for retrieving a sysctl's
description. I haven't tested the patches yet, but they compile
cleanly against a fairly recent (couple of hours old) -current.

There are four patches in this patchkit: two for the kernel (sysctl.h
and kern_sysctl.c) and two for userland (sysctl.c and sysctl.8). The
changes are:

 sysctl.h: bring the description into the sysctl structure (it was
  previously ignored)

 kern_sysctl.c: add sysctl_sysctl_descr, which returns the description
  of a given sysctl. Register it as sysctl 0.5.

 sysctl.c: some cleanup (usage() and option handling), add a -d option
  which makes sysctl(8) display the description instead of the value.

 sysctl.8: document it.

So what do you think? Go or no go?

OBTW, while I'm at it I'm game to redesign the meta-sysctl API if
you'll let me :) I won't mind too much if somebody tells me what those
"conflicting requirements" are so I don't jump in and repeat an old
mistake instead of making up my own.

DES
-- 
Dag-Erling Smørgrav - des@flood.ping.uio.no

Index: sys/sys/sysctl.h
===================================================================
RCS file: /home/ncvs/src/sys/sys/sysctl.h,v
retrieving revision 1.68
diff -u -r1.68 sysctl.h
--- sysctl.h	1998/12/27 18:03:29	1.68
+++ sysctl.h	1999/01/09 09:59:06
@@ -122,6 +122,7 @@
 	const char	*oid_name;
 	int 		(*oid_handler) SYSCTL_HANDLER_ARGS;
 	const char	*oid_fmt;
+	const char	*oid_descr;
 };
 
 #define SYSCTL_IN(r, p, l) (r->newfunc)(r, p, l)
@@ -136,7 +137,7 @@
 /* This constructs a "raw" MIB oid. */
 #define SYSCTL_OID(parent, nbr, name, kind, a1, a2, handler, fmt, descr) \
 	static struct sysctl_oid sysctl__##parent##_##name = { \
-		nbr, kind, a1, a2, #name, handler, fmt }; \
+		nbr, kind, a1, a2, #name, handler, fmt, descr }; \
 	DATA_SET(sysctl_##parent, sysctl__##parent##_##name)
 
 /* This constructs a node from which other oids can hang. */
Index: sys/kern/kern_sysctl.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/kern_sysctl.c,v
retrieving revision 1.81
diff -u -r1.81 kern_sysctl.c
--- kern_sysctl.c	1998/12/27 18:03:29	1.81
+++ kern_sysctl.c	1999/01/09 10:49:48
@@ -155,9 +155,10 @@
  *
  * {0,0}	printf the entire MIB-tree.
  * {0,1,...}	return the name of the "..." OID.
- * {0,2,...}	return the next OID.
+ * {0,2}	return the next OID.
  * {0,3}	return the OID of the name in "new"
  * {0,4,...}	return the kind & format info for the "..." OID.
+ * {0,5,...}	return the description for the "..." OID.
  */
 
 static void
@@ -491,6 +492,47 @@
 
 
 SYSCTL_NODE(_sysctl, 4, oidfmt, CTLFLAG_RD, sysctl_sysctl_oidfmt, "");
+
+static int
+sysctl_sysctl_descr SYSCTL_HANDLER_ARGS
+{
+	int *name = (int *) arg1;
+	u_int namelen = arg2;
+	int i, j, error = 0;
+	struct sysctl_oid **oidpp;
+	struct linker_set *lsp = &sysctl_;
+
+	if (!lsp || !namelen)
+		return (SYSCTL_OUT(req, "", 1));
+	
+	while (namelen) {
+		oidpp = (struct sysctl_oid **) lsp->ls_items;
+		j = lsp->ls_length;
+		lsp = 0;
+		for (i = 0; i < j; i++, oidpp++) {
+			if (*oidpp && ((*oidpp)->oid_number != *name))
+				continue;
+
+			namelen--;
+			name++;
+
+			if (((*oidpp)->oid_kind & CTLTYPE) != CTLTYPE_NODE)
+				break;
+
+			if ((*oidpp)->oid_handler)
+				break;
+
+			lsp = (struct linker_set*)(*oidpp)->oid_arg1;
+			break;
+		}
+	}
+	
+	error = SYSCTL_OUT(req, (*oidpp)->oid_descr,
+			   strlen((*oidpp)->oid_descr + 1));
+	return (error);
+}
+
+SYSCTL_NODE(_sysctl, 5, descr, CTLFLAG_RD, sysctl_sysctl_descr, "");
 
 /*
  * Default "handler" functions.
Index: sysctl/sysctl.c
===================================================================
RCS file: /home/ncvs/src/usr.sbin/sysctl/sysctl.c,v
retrieving revision 1.19
diff -u -r1.19 sysctl.c
--- sysctl.c	1998/11/08 19:27:43	1.19
+++ sysctl.c	1999/01/09 10:22:21
@@ -58,7 +58,7 @@
 #include <string.h>
 #include <unistd.h>
 
-static int	Aflag, aflag, nflag, wflag, Xflag, bflag;
+static int	Aflag, aflag, bflag, dflag, nflag, wflag, Xflag;
 
 static int	oidfmt(int *, int, char *, u_int *);
 static void	parse(char *);
@@ -70,11 +70,12 @@
 usage(void)
 {
 
-	(void)fprintf(stderr, "%s\n%s\n%s\n%s\n",
-		"usage: sysctl [-bnX] variable ...",
-		"       sysctl [-bnX] -w variable=value ...",
-		"       sysctl [-bnX] -a",
-		"       sysctl [-bnX] -A");
+	(void)fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n",
+		"usage: sysctl [-bdn] variable ...",
+		"       sysctl [-bn] -w variable=value ...",
+		"       sysctl [-bdn] -a",
+		"       sysctl [-bdn] -A",
+		"       sysctl [-bdn] -X");
 	exit(1);
 }
 
@@ -85,11 +86,12 @@
 	setbuf(stdout,0);
 	setbuf(stderr,0);
 
-	while ((ch = getopt(argc, argv, "AabnwX")) != -1) {
+	while ((ch = getopt(argc, argv, "AabdnwX")) != -1) {
 		switch (ch) {
 		case 'A': Aflag = 1; break;
 		case 'a': aflag = 1; break;
 		case 'b': bflag = 1; break;
+		case 'd': dflag = 1; break;
 		case 'n': nflag = 1; break;
 		case 'w': wflag = 1; break;
 		case 'X': Xflag = Aflag = 1; break;
@@ -99,6 +101,8 @@
 	argc -= optind;
 	argv += optind;
 
+	if (wflag && (Aflag || aflag || dflag))
+		usage();
 	if (Aflag || aflag)
 		exit (sysctl_all(0, 0));
 	if (argc == 0)
@@ -336,7 +340,7 @@
 show_var(int *oid, int nlen)
 {
 	u_char buf[BUFSIZ], *val, *p;
-	char name[BUFSIZ], *fmt;
+	char name[BUFSIZ], descr[BUFSIZ], *fmt;
 	int qoid[CTL_MAXNAME+2];
 	int i;
 	size_t j, len;
@@ -378,6 +382,19 @@
 	if (i || !j)
 		err(1, "sysctl name %d %d %d", i, j, errno);
 
+	qoid[1] = 5;
+	j = sizeof descr;
+	i = sysctl(qoid, nlen + 2, descr, &j, 0, 0);
+	if (i || !j)
+		err(1, "sysctl name %d %d %d", i, j, errno);
+
+	if (dflag) {
+		if (!nflag)
+			printf("%s: ", name);
+		printf("%s", descr[0] ? descr : "[no description]");
+		return (0);
+	}
+	
 	p = val;
 	switch (*fmt) {
 	case 'A':
Index: sysctl/sysctl.8
===================================================================
RCS file: /home/ncvs/src/usr.sbin/sysctl/sysctl.8,v
retrieving revision 1.17
diff -u -r1.17 sysctl.8
--- sysctl.8	1998/09/29 02:01:06	1.17
+++ sysctl.8	1999/01/09 10:17:06
@@ -40,14 +40,14 @@
 .Nd get or set kernel state
 .Sh SYNOPSIS
 .Nm sysctl
-.Op Fl bn
+.Op Fl bdn
 .Ar name ...
 .Nm sysctl
 .Op Fl bn
 .Fl w
 .Ar name=value ...
 .Nm sysctl
-.Op Fl bn
+.Op Fl bdn
 .Fl aAX
 .Sh DESCRIPTION
 The
@@ -85,6 +85,9 @@
 Force the value of the variable(s) to be output in raw, binary
 format.  No names are printed and no terminating newlines are output.
 This is mostly useful with a single variable.
+.It Fl d
+Display the description rather than the value of the requested
+variable(s).
 .It Fl w Ar name=value ...
 Set the MIB
 .Ar name

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe cvs-all" in the body of the message



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