diff options
author | ngie <ngie@FreeBSD.org> | 2017-07-18 06:45:41 +0000 |
---|---|---|
committer | ngie <ngie@FreeBSD.org> | 2017-07-18 06:45:41 +0000 |
commit | 64e85b71e8a50aa56fe271bbb1ee1a7fd9a5cbb2 (patch) | |
tree | 3fa6fefb13e334e18fdacc4e7fd1c3a4df3fc5b7 | |
parent | 7d68c5317a5fb9f8afd0fe8ba9d65a5a271174a7 (diff) | |
download | FreeBSD-src-64e85b71e8a50aa56fe271bbb1ee1a7fd9a5cbb2.zip FreeBSD-src-64e85b71e8a50aa56fe271bbb1ee1a7fd9a5cbb2.tar.gz |
MFC r307873,r314397,r314399,r314419,r314420,r314533,r316553:
r307873 (by marcel):
Include <stdarg.h> instead of <machine/stdarg.h> when compiled as
part of libsbuf. The former is the standard header, and allows us
to compile libsbuf on macOS/linux.
r314397 (by scottl):
Implement sbuf_prf(), which takes an sbuf and outputs it
to stdout in the non-kernel case and to the console+log
in the kernel case. For the kernel case it hooks the
putbuf() machinery underneath printf(9) so that the buffer
is written completely atomically and without a copy into
another temporary buffer. This is useful for fixing
compound console/log messages that become broken and
interleaved when multiple threads are competing for the
console.
r314399 (by scottl):
Add prototype for sbuf_putbuf()
r314419 (by jkim):
Include stdio.h to fix libsbuf build.
r314420 (by scottl):
Provide a comment on why stdio.h needs to be included.
r314533 (by scottl):
Expose the sbuf_putbuf() symbol to libsbuf. There are a few other symbols
that are present but not exposed, like get/set/clear flags, not sure if they
need to be exposed at this point.
r316553:
sbuf(3): expose sbuf_{clear,get,set}_flags(3) via libsbuf
These functions were added to sbuf(9) in r279992, but never
exposed to userspace. Expose them now so they can be used/tested.
-rw-r--r-- | lib/libsbuf/Symbol.map | 8 | ||||
-rw-r--r-- | lib/libsbuf/Version.def | 3 | ||||
-rw-r--r-- | share/man/man9/sbuf.9 | 11 | ||||
-rw-r--r-- | sys/kern/subr_prf.c | 58 | ||||
-rw-r--r-- | sys/sys/sbuf.h | 1 |
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; |