Page MenuHomeFreeBSD

D27029.id78995.diff
No OneTemporary

D27029.id78995.diff

Index: sys/kern/kern_sysctl.c
===================================================================
--- sys/kern/kern_sysctl.c
+++ sys/kern/kern_sysctl.c
@@ -126,7 +126,11 @@
int recurse);
static int sysctl_old_kernel(struct sysctl_req *, const void *, size_t);
static int sysctl_new_kernel(struct sysctl_req *, void *, size_t);
+static int sysctl_sysctl_next_ls(struct sysctl_oid_list *lsp, int *name,
+ u_int namelen, int *next, int *len, int level,
+ bool honor_skip);
+
static struct sysctl_oid *
sysctl_find_oidname(const char *name, struct sysctl_oid_list *list)
{
@@ -1101,106 +1105,126 @@
CTLFLAG_MPSAFE | CTLFLAG_CAPRD, sysctl_sysctl_name, "");
/*
- * Walk the sysctl subtree at lsp until we find the given name,
- * and return the next name in order by oid_number.
+ * Recursively tries to find the next node for @name and @namelen.
+ *
+ * Returns true if the desired next node was found, filling
+ * @next and @len.
*/
-static int
-sysctl_sysctl_next_ls(struct sysctl_oid_list *lsp, int *name, u_int namelen,
+static bool
+sysctl_sysctl_next_node(struct sysctl_oid *oidp, int *name, u_int *namelen,
int *next, int *len, int level, bool honor_skip)
{
- struct sysctl_oid *oidp;
+ struct sysctl_oid_list *lsp;
- SYSCTL_ASSERT_LOCKED();
- *len = level;
- SLIST_FOREACH(oidp, lsp, oid_link) {
- *next = oidp->oid_number;
+ *next = oidp->oid_number;
- if ((oidp->oid_kind & CTLFLAG_DORMANT) != 0)
- continue;
+ if ((oidp->oid_kind & CTLFLAG_DORMANT) != 0)
+ return (false);
- if (honor_skip && (oidp->oid_kind & CTLFLAG_SKIP) != 0)
- continue;
+ if (honor_skip && (oidp->oid_kind & CTLFLAG_SKIP) != 0)
+ return (false);
- if (namelen == 0) {
- /*
- * We have reached a node with a full name match and are
- * looking for the next oid in its children.
- *
- * For CTL_SYSCTL_NEXTNOSKIP we are done.
- *
- * For CTL_SYSCTL_NEXT we skip CTLTYPE_NODE (unless it
- * has a handler) and move on to the children.
- */
- if (!honor_skip)
- return (0);
- if ((oidp->oid_kind & CTLTYPE) != CTLTYPE_NODE)
- return (0);
- if (oidp->oid_handler)
- return (0);
- lsp = SYSCTL_CHILDREN(oidp);
- if (!sysctl_sysctl_next_ls(lsp, NULL, 0, next + 1, len,
- level + 1, honor_skip))
- return (0);
- /*
- * There were no useable children in this node.
- * Continue searching for the next oid at this level.
- */
- goto emptynode;
- }
-
+ if (*namelen == 0) {
/*
- * No match yet. Continue seeking the given name.
+ * We have reached a node with a full name match and are
+ * looking for the next oid in its children.
*
- * We are iterating in order by oid_number, so skip oids lower
- * than the one we are looking for.
+ * For CTL_SYSCTL_NEXTNOSKIP we are done.
*
- * When the current oid_number is higher than the one we seek,
- * that means we have reached the next oid in the sequence and
- * should return it.
+ * For CTL_SYSCTL_NEXT we skip CTLTYPE_NODE (unless it
+ * has a handler) and move on to the children.
+ */
+ if (!honor_skip)
+ return (true);
+ if ((oidp->oid_kind & CTLTYPE) != CTLTYPE_NODE)
+ return (true);
+ if (oidp->oid_handler)
+ return (true);
+ lsp = SYSCTL_CHILDREN(oidp);
+ if (!sysctl_sysctl_next_ls(lsp, NULL, 0, next + 1, len,
+ level + 1, honor_skip))
+ return (true);
+ /*
+ * There were no useable children in this node.
+ * Continue searching for the next oid at this level.
+ */
+ goto emptynode;
+ }
+
+ /*
+ * No match yet. Continue seeking the given name.
+ *
+ * We are iterating in order by oid_number, so skip oids lower
+ * than the one we are looking for.
+ *
+ * When the current oid_number is higher than the one we seek,
+ * that means we have reached the next oid in the sequence and
+ * should return it.
+ *
+ * If the oid_number matches the name at this level then we
+ * have to find a node to return (false) searching at the next level.
+ */
+ if (oidp->oid_number < *name)
+ return (false);
+ if (oidp->oid_number > *name) {
+ /*
+ * We have reached the next oid.
*
- * If the oid_number matches the name at this level then we
- * have to find a node to continue searching at the next level.
+ * For CTL_SYSCTL_NEXTNOSKIP we are done.
+ *
+ * For CTL_SYSCTL_NEXT we skip CTLTYPE_NODE (unless it
+ * has a handler) and move on to the children.
*/
- if (oidp->oid_number < *name)
- continue;
- if (oidp->oid_number > *name) {
- /*
- * We have reached the next oid.
- *
- * For CTL_SYSCTL_NEXTNOSKIP we are done.
- *
- * For CTL_SYSCTL_NEXT we skip CTLTYPE_NODE (unless it
- * has a handler) and move on to the children.
- */
- if (!honor_skip)
- return (0);
- if ((oidp->oid_kind & CTLTYPE) != CTLTYPE_NODE)
- return (0);
- if (oidp->oid_handler)
- return (0);
- lsp = SYSCTL_CHILDREN(oidp);
- if (!sysctl_sysctl_next_ls(lsp, name + 1, namelen - 1,
- next + 1, len, level + 1, honor_skip))
- return (0);
- goto next;
- }
+ if (!honor_skip)
+ return (true);
if ((oidp->oid_kind & CTLTYPE) != CTLTYPE_NODE)
- continue;
+ return (true);
if (oidp->oid_handler)
- continue;
+ return (true);
lsp = SYSCTL_CHILDREN(oidp);
- if (!sysctl_sysctl_next_ls(lsp, name + 1, namelen - 1,
+ if (!sysctl_sysctl_next_ls(lsp, name + 1, *namelen - 1,
next + 1, len, level + 1, honor_skip))
- return (0);
- next:
- /*
- * There were no useable children in this node.
- * Continue searching for the next oid at the root level.
- */
- namelen = 1;
- emptynode:
- /* Reset len in case a failed recursive call changed it. */
- *len = level;
+ return (true);
+ goto next;
+ }
+ if ((oidp->oid_kind & CTLTYPE) != CTLTYPE_NODE)
+ return (false);
+ if (oidp->oid_handler)
+ return (false);
+ lsp = SYSCTL_CHILDREN(oidp);
+ if (!sysctl_sysctl_next_ls(lsp, name + 1, *namelen - 1,
+ next + 1, len, level + 1, honor_skip))
+ return (true);
+next:
+ /*
+ * There were no useable children in this node.
+ * Continue searching for the next oid at the root level.
+ */
+ *namelen = 1;
+emptynode:
+ /* Reset len in case a failed recursive call changed it. */
+ *len = level;
+
+ return (false);
+}
+
+/*
+ * Walk the sysctl subtree at lsp until we find the given name,
+ * and return the next name in order by oid_number.
+ */
+static int
+sysctl_sysctl_next_ls(struct sysctl_oid_list *lsp, int *name, u_int namelen,
+ int *next, int *len, int level, bool honor_skip)
+{
+ struct sysctl_oid *oidp;
+
+ SYSCTL_ASSERT_LOCKED();
+ *len = level;
+ SLIST_FOREACH(oidp, lsp, oid_link) {
+ if (!sysctl_sysctl_next_node(oidp, name, &namelen,
+ next, len, level, honor_skip))
+ continue;
+ return (0);
}
return (ENOENT);
}

File Metadata

Mime Type
text/plain
Expires
Fri, Apr 24, 4:03 PM (6 h, 17 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
32082489
Default Alt Text
D27029.id78995.diff (6 KB)

Event Timeline