summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/libsbuf/Symbol.map8
-rw-r--r--lib/libsbuf/Version.def3
-rw-r--r--share/man/man9/sbuf.911
-rw-r--r--sys/kern/subr_prf.c58
-rw-r--r--sys/sys/sbuf.h1
5 files changed, 68 insertions, 13 deletions
diff --git a/lib/libsbuf/Symbol.map b/lib/libsbuf/Symbol.map
index 164b8f3..7bbc4bf 100644
--- a/lib/libsbuf/Symbol.map
+++ b/lib/libsbuf/Symbol.map
@@ -21,6 +21,9 @@ FBSD_1.2 {
sbuf_len;
sbuf_done;
sbuf_delete;
+ sbuf_clear_flags;
+ sbuf_get_flags;
+ sbuf_set_flags;
};
FBSD_1.3 {
@@ -31,3 +34,8 @@ FBSD_1.3 {
FBSD_1.4 {
sbuf_hexdump;
};
+
+FBSD_1.5 {
+ sbuf_putbuf;
+};
+
diff --git a/lib/libsbuf/Version.def b/lib/libsbuf/Version.def
index fd5c6be..2894712 100644
--- a/lib/libsbuf/Version.def
+++ b/lib/libsbuf/Version.def
@@ -8,3 +8,6 @@ FBSD_1.3 {
FBSD_1.4 {
} FBSD_1.3;
+
+FBSD_1.5 {
+} FBSD_1.4;
diff --git a/share/man/man9/sbuf.9 b/share/man/man9/sbuf.9
index 1cd39dc..a74a569 100644
--- a/share/man/man9/sbuf.9
+++ b/share/man/man9/sbuf.9
@@ -54,7 +54,8 @@
.Nm sbuf_delete ,
.Nm sbuf_start_section ,
.Nm sbuf_end_section ,
-.Nm sbuf_hexdump
+.Nm sbuf_hexdump ,
+.Nm sbuf_putbuf
.Nd safe string composition
.Sh SYNOPSIS
.In sys/types.h
@@ -115,6 +116,8 @@
.Fa "const char *hdr"
.Fa "int flags"
.Fc
+.Ft void
+.Fn sbuf_putbuf "struct sbuf *s"
.In sys/sysctl.h
.Ft struct sbuf *
.Fn sbuf_new_for_sysctl "struct sbuf *s" "char *buf" "int length" "struct sysctl_req *req"
@@ -449,6 +452,12 @@ representation of the bytes if possible.
See the
.Xr hexdump 3
man page for more details on the interface.
+.Pp
+The
+.Fn sbuf_putbuf
+function printfs the sbuf to stdout if in userland, and to the console
+and log if in the kernel.
+It does not drain the buffer or update any pointers.
.Sh NOTES
If an operation caused an
.Fa sbuf
diff --git a/sys/kern/subr_prf.c b/sys/kern/subr_prf.c
index 23c9681..6ed3c00 100644
--- a/sys/kern/subr_prf.c
+++ b/sys/kern/subr_prf.c
@@ -72,7 +72,19 @@ __FBSDID("$FreeBSD$");
* Note that stdarg.h and the ANSI style va_start macro is used for both
* ANSI and traditional C compilers.
*/
+#ifdef _KERNEL
#include <machine/stdarg.h>
+#else
+#include <stdarg.h>
+#endif
+
+/*
+ * This is needed for sbuf_putbuf() when compiled into userland. Due to the
+ * shared nature of this file, it's the only place to put it.
+ */
+#ifndef _KERNEL
+#include <stdio.h>
+#endif
#ifdef _KERNEL
@@ -403,6 +415,23 @@ vprintf(const char *fmt, va_list ap)
}
static void
+prf_putbuf(char *bufr, int flags, int pri)
+{
+
+ if (flags & TOLOG)
+ msglogstr(bufr, pri, /*filter_cr*/1);
+
+ if (flags & TOCONS) {
+ if ((panicstr == NULL) && (constty != NULL))
+ msgbuf_addstr(&consmsgbuf, -1,
+ bufr, /*filter_cr*/ 0);
+
+ if ((constty == NULL) ||(always_console_output))
+ cnputs(bufr);
+ }
+}
+
+static void
putbuf(int c, struct putchar_arg *ap)
{
/* Check if no console output buffer was provided. */
@@ -423,18 +452,7 @@ putbuf(int c, struct putchar_arg *ap)
/* Check if the buffer needs to be flushed. */
if (ap->remain == 2 || c == '\n') {
-
- if (ap->flags & TOLOG)
- msglogstr(ap->p_bufr, ap->pri, /*filter_cr*/1);
-
- if (ap->flags & TOCONS) {
- if ((panicstr == NULL) && (constty != NULL))
- msgbuf_addstr(&consmsgbuf, -1,
- ap->p_bufr, /*filter_cr*/ 0);
-
- if ((constty == NULL) ||(always_console_output))
- cnputs(ap->p_bufr);
- }
+ prf_putbuf(ap->p_bufr, ap->flags, ap->pri);
ap->p_next = ap->p_bufr;
ap->remain = ap->n_bufr;
@@ -1205,3 +1223,19 @@ counted_warning(unsigned *counter, const char *msg)
}
}
#endif
+
+#ifdef _KERNEL
+void
+sbuf_putbuf(struct sbuf *sb)
+{
+
+ prf_putbuf(sbuf_data(sb), TOLOG | TOCONS, -1);
+}
+#else
+void
+sbuf_putbuf(struct sbuf *sb)
+{
+
+ printf("%s", sbuf_data(sb));
+}
+#endif
diff --git a/sys/sys/sbuf.h b/sys/sys/sbuf.h
index dbe2f68..2b4f302 100644
--- a/sys/sys/sbuf.h
+++ b/sys/sys/sbuf.h
@@ -95,6 +95,7 @@ void sbuf_start_section(struct sbuf *, ssize_t *);
ssize_t sbuf_end_section(struct sbuf *, ssize_t, size_t, int);
void sbuf_hexdump(struct sbuf *, const void *, int, const char *,
int);
+void sbuf_putbuf(struct sbuf *);
#ifdef _KERNEL
struct uio;
OpenPOWER on IntegriCloud