aboutsummaryrefslogtreecommitdiff
path: root/sys/kern/subr_bus.c
diff options
context:
space:
mode:
authorWarner Losh <imp@FreeBSD.org>2020-08-29 04:30:12 +0000
committerWarner Losh <imp@FreeBSD.org>2020-08-29 04:30:12 +0000
commit17c219fd6f018b21d39de2623c533be2f507008e (patch)
tree6e1ebd409cbf26dd96cab560fe80277ffb2ef4c0 /sys/kern/subr_bus.c
parent887611b1227c95b8d5588f920822435a7021fd2a (diff)
downloadsrc-17c219fd6f018b21d39de2623c533be2f507008e.tar.gz
src-17c219fd6f018b21d39de2623c533be2f507008e.zip
Move to using sbuf for some sysctl in newbus
Convert two different sysctl to using sbuf. First, for all the default sysctls we implement for each device driver that's attached. This is a pure sbuf conversion. Second, convert sysctl_devices to fill its buffer with sbuf rather than a hand-rolled crappy thing I wrote years ago. Reviewed by: cem, markj Differential Revision: https://reviews.freebsd.org/D26206
Notes
Notes: svn path=/head/; revision=364946
Diffstat (limited to 'sys/kern/subr_bus.c')
-rw-r--r--sys/kern/subr_bus.c68
1 files changed, 26 insertions, 42 deletions
diff --git a/sys/kern/subr_bus.c b/sys/kern/subr_bus.c
index 503e73ff59b0..e6abb1779a69 100644
--- a/sys/kern/subr_bus.c
+++ b/sys/kern/subr_bus.c
@@ -260,36 +260,33 @@ enum {
static int
device_sysctl_handler(SYSCTL_HANDLER_ARGS)
{
+ struct sbuf sb;
device_t dev = (device_t)arg1;
- const char *value;
- char *buf;
int error;
- buf = NULL;
+ sbuf_new_for_sysctl(&sb, NULL, 1024, req);
switch (arg2) {
case DEVICE_SYSCTL_DESC:
- value = dev->desc ? dev->desc : "";
+ sbuf_cpy(&sb, dev->desc ? dev->desc : "");
break;
case DEVICE_SYSCTL_DRIVER:
- value = dev->driver ? dev->driver->name : "";
+ sbuf_cpy(&sb, dev->driver ? dev->driver->name : "");
break;
case DEVICE_SYSCTL_LOCATION:
- value = buf = malloc(1024, M_BUS, M_WAITOK | M_ZERO);
- bus_child_location_str(dev, buf, 1024);
+ bus_child_location_sb(dev, &sb);
break;
case DEVICE_SYSCTL_PNPINFO:
- value = buf = malloc(1024, M_BUS, M_WAITOK | M_ZERO);
- bus_child_pnpinfo_str(dev, buf, 1024);
+ bus_child_pnpinfo_sb(dev, &sb);
break;
case DEVICE_SYSCTL_PARENT:
- value = dev->parent ? dev->parent->nameunit : "";
+ sbuf_cpy(&sb, dev->parent ? dev->parent->nameunit : "");
break;
default:
+ sbuf_delete(&sb);
return (EINVAL);
}
- error = SYSCTL_OUT_STR(req, value);
- if (buf != NULL)
- free(buf, M_BUS);
+ error = sbuf_finish(&sb);
+ sbuf_delete(&sb);
return (error);
}
@@ -5464,13 +5461,13 @@ SYSCTL_PROC(_hw_bus, OID_AUTO, info, CTLTYPE_STRUCT | CTLFLAG_RD |
static int
sysctl_devices(SYSCTL_HANDLER_ARGS)
{
+ struct sbuf sb;
int *name = (int *)arg1;
u_int namelen = arg2;
int index;
device_t dev;
struct u_device *udev;
int error;
- char *walker, *ep;
if (namelen != 2)
return (EINVAL);
@@ -5501,34 +5498,21 @@ sysctl_devices(SYSCTL_HANDLER_ARGS)
udev->dv_devflags = dev->devflags;
udev->dv_flags = dev->flags;
udev->dv_state = dev->state;
- walker = udev->dv_fields;
- ep = walker + sizeof(udev->dv_fields);
-#define CP(src) \
- if ((src) == NULL) \
- *walker++ = '\0'; \
- else { \
- strlcpy(walker, (src), ep - walker); \
- walker += strlen(walker) + 1; \
- } \
- if (walker >= ep) \
- break;
-
- do {
- CP(dev->nameunit);
- CP(dev->desc);
- CP(dev->driver != NULL ? dev->driver->name : NULL);
- bus_child_pnpinfo_str(dev, walker, ep - walker);
- walker += strlen(walker) + 1;
- if (walker >= ep)
- break;
- bus_child_location_str(dev, walker, ep - walker);
- walker += strlen(walker) + 1;
- if (walker >= ep)
- break;
- *walker++ = '\0';
- } while (0);
-#undef CP
- error = SYSCTL_OUT(req, udev, sizeof(*udev));
+ sbuf_new(&sb, udev->dv_fields, sizeof(udev->dv_fields), SBUF_FIXEDLEN);
+ sbuf_cat(&sb, dev->nameunit);
+ sbuf_putc(&sb, '\0');
+ sbuf_cat(&sb, dev->desc);
+ sbuf_putc(&sb, '\0');
+ sbuf_cat(&sb, dev->driver != NULL ? dev->driver->name : '\0');
+ sbuf_putc(&sb, '\0');
+ bus_child_pnpinfo_sb(dev, &sb);
+ sbuf_putc(&sb, '\0');
+ bus_child_location_sb(dev, &sb);
+ sbuf_putc(&sb, '\0');
+ error = sbuf_finish(&sb);
+ if (error == 0)
+ error = SYSCTL_OUT(req, udev, sizeof(*udev));
+ sbuf_delete(&sb);
free(udev, M_BUS);
return (error);
}