Index: contrib/libxo/libxo/libxo.c =================================================================== --- contrib/libxo/libxo/libxo.c +++ contrib/libxo/libxo/libxo.c @@ -78,8 +78,10 @@ unsigned short xo_style; /* XO_STYLE_* value */ unsigned short xo_indent; /* Indent level (if pretty) */ unsigned short xo_indent_by; /* Indent amount (tab stop) */ + xo_flush_func_t xo_flush; /* Flush callback */ xo_write_func_t xo_write; /* Write callback */ xo_close_func_t xo_close; /* Close callback */ + xo_getlinebuf_func_t xo_getlinebuf; /* Is file line buffered? */ xo_formatter_t xo_formatter; /* Custom formating function */ xo_checkpointer_t xo_checkpointer; /* Custom formating support function */ void *xo_opaque; /* Opaque data for write function */ @@ -220,6 +222,27 @@ xo_anchor_clear (xo_handle_t *xop); /* + * What buffer mode is the underlying file? + */ +static int +xo_getlinebuf_file (void *opaque) +{ + FILE *fp = (FILE *) opaque; + + return (__flbf(fp)); +} +/* + * Callback to flush a FILE pointer + */ +static int +xo_flush_file (void *opaque) +{ + FILE *fp = (FILE *) opaque; + + return (fflush(fp)); +} + +/* * Callback to write data to a FILE pointer */ static int @@ -300,6 +323,8 @@ { xop->xo_opaque = stdout; xop->xo_write = xo_write_to_file; + xop->xo_flush = xo_flush_file; + xop->xo_getlinebuf = xo_getlinebuf_file; /* * We need to initialize the locale, which isn't really pretty. @@ -1211,7 +1236,7 @@ break; } - xo_flush_h(xop); + (void)xo_flush_h(xop); } void @@ -1297,8 +1322,10 @@ if (xop) { xop->xo_opaque = fp; + xop->xo_flush = xo_flush_file; xop->xo_write = xo_write_to_file; xop->xo_close = xo_close_file; + xop->xo_getlinebuf = xo_getlinebuf_file; } return xop; @@ -3163,7 +3190,10 @@ for (cp = fmt; *cp; ) { if (*cp == '\n') { xo_line_close(xop); - xo_flush_h(xop); + if (xo_getlinebuf_h(xop)) { + if (xo_flush_h(xop)) + return -1; + } cp += 1; continue; @@ -4029,13 +4059,14 @@ void xo_set_writer (xo_handle_t *xop, void *opaque, xo_write_func_t write_func, - xo_close_func_t close_func) + xo_close_func_t close_func, xo_flush_func_t flush_func) { xop = xo_default(xop); xop->xo_opaque = opaque; xop->xo_write = write_func; xop->xo_close = close_func; + xop->xo_flush = flush_func; } void @@ -4045,7 +4076,7 @@ xo_free = free_func; } -void +int xo_flush_h (xo_handle_t *xop) { static char div_close[] = ""; @@ -4065,15 +4096,31 @@ } xo_write(xop); + if (xop->xo_flush == NULL) + return 0; + + return (xop->xo_flush(xop->xo_opaque)); + } -void +int +xo_getlinebuf_h(xo_handle_t *xop) +{ + + xop = xo_default(xop); + if (xop->xo_getlinebuf != NULL) + return (xop->xo_getlinebuf(xop->xo_opaque)); + + return (0); +} + +int xo_flush (void) { - xo_flush_h(NULL); + return xo_flush_h(NULL); } -void +int xo_finish_h (xo_handle_t *xop) { const char *cp = ""; @@ -4091,13 +4138,13 @@ break; } - xo_flush_h(xop); + return xo_flush_h(xop); } -void +int xo_finish (void) { - xo_finish_h(NULL); + return xo_finish_h(NULL); } /* Index: contrib/libxo/libxo/xo.h =================================================================== --- contrib/libxo/libxo/xo.h +++ contrib/libxo/libxo/xo.h @@ -69,7 +69,9 @@ typedef struct xo_handle_s xo_handle_t; /* Handle for XO output */ typedef int (*xo_write_func_t)(void *, const char *); +typedef int (*xo_flush_func_t)(void *); typedef void (*xo_close_func_t)(void *); +typedef int (*xo_getlinebuf_func_t)(void *); typedef void *(*xo_realloc_func_t)(void *, size_t); typedef void (*xo_free_func_t)(void *); @@ -93,7 +95,7 @@ void xo_set_writer (xo_handle_t *xop, void *opaque, xo_write_func_t write_func, - xo_close_func_t close_func); + xo_close_func_t close_func, xo_flush_func_t flush_func); void xo_set_allocator (xo_realloc_func_t realloc_func, xo_free_func_t free_func); @@ -227,16 +229,19 @@ void xo_error (const char *fmt, ...); -void +int +xo_getlinebuf_h(xo_handle_t *xop); + +int xo_flush_h (xo_handle_t *xop); -void +int xo_flush (void); -void +int xo_finish_h (xo_handle_t *xop); -void +int xo_finish (void); void Index: include/stdio.h =================================================================== --- include/stdio.h +++ include/stdio.h @@ -399,6 +399,7 @@ char *fgetln(FILE *, size_t *); const char *fmtcheck(const char *, const char *) __format_arg(2); int fpurge(FILE *); +int __flbf(FILE *); void setbuffer(FILE *, char *, int); int setlinebuf(FILE *); int vasprintf(char **, const char *, __va_list) Index: lib/libc/stdio/Makefile.inc =================================================================== --- lib/libc/stdio/Makefile.inc +++ lib/libc/stdio/Makefile.inc @@ -4,7 +4,7 @@ # stdio sources .PATH: ${LIBC_SRCTOP}/stdio -SRCS+= _flock_stub.c asprintf.c clrerr.c dprintf.c \ +SRCS+= __flbf.c _flock_stub.c asprintf.c clrerr.c dprintf.c \ fclose.c fcloseall.c fdopen.c \ feof.c ferror.c fflush.c fgetc.c fgetln.c fgetpos.c fgets.c fgetwc.c \ fgetwln.c fgetws.c \ @@ -79,6 +79,7 @@ MLINKS+=scanf_l.3 fscanf_l.3 scanf_l.3 sscanf_l.3 scanf_l.3 vfscanf_l.3 \ scanf_l.3 vscanf_l.3 scanf_l.3 vsscanf_l.3 MLINKS+=setbuf.3 setbuffer.3 setbuf.3 setlinebuf.3 setbuf.3 setvbuf.3 +MLINKS+=setbuf.3 __flbf.3 MLINKS+=tmpnam.3 tempnam.3 tmpnam.3 tmpfile.3 MLINKS+=wprintf.3 fwprintf.3 wprintf.3 swprintf.3 \ wprintf.3 vwprintf.3 wprintf.3 vfwprintf.3 wprintf.3 vswprintf.3 Index: lib/libc/stdio/Symbol.map =================================================================== --- lib/libc/stdio/Symbol.map +++ lib/libc/stdio/Symbol.map @@ -151,6 +151,7 @@ wscanf_l; fgetws_l; fputws_l; + __flbf; getwc_l; getwchar_l; putwc_l; Index: lib/libc/stdio/__flbf.c =================================================================== --- /dev/null +++ lib/libc/stdio/__flbf.c @@ -0,0 +1,50 @@ +/*- + * Copyright (c) 2014 Norse Corporation + * All rights reserved. + * + * Author: Alfred Perlstein + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)setvbuf.c 8.2 (Berkeley) 11/16/93"; +#endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD$"); + +#include "namespace.h" +#include +#include +#include +#include "un-namespace.h" +#include "local.h" +#include "libc_private.h" + +/* + * Return if file is line buffered or not. + */ +int +__flbf(FILE * __restrict fp) +{ + + return ((fp->_flags & __SLBF) != 0); +} Index: lib/libc/stdio/setbuf.3 =================================================================== --- lib/libc/stdio/setbuf.3 +++ lib/libc/stdio/setbuf.3 @@ -53,6 +53,8 @@ .Fn setlinebuf "FILE *stream" .Ft int .Fn setvbuf "FILE * restrict stream" "char * restrict buf" "int mode" "size_t size" +.Ft int +.Fn __flbf "FILE * restrict stream" .Sh DESCRIPTION The three types of buffering available are unbuffered, block buffered, and line buffered. @@ -166,6 +168,13 @@ is exactly equivalent to the call: .Pp .Dl "setvbuf(stream, (char *)NULL, _IOLBF, 0);" +The +.Pp +.Fn __flbf +function returns if the steam is line buffered or not. +.Fn __flbf +is a non-standard function and should not be used by code +that aims to be portable. .Sh RETURN VALUES The .Fn setvbuf @@ -179,6 +188,9 @@ function returns what the equivalent .Fn setvbuf would have returned. +.Pp +.Fn __flbf +returns 1 if the file is line buffered, otherwise it returns 0. .Sh SEE ALSO .Xr stdbuf 1 , .Xr fclose 3 , @@ -195,6 +207,10 @@ functions conform to .St -isoC . +.Pp +The function +.Fn __flbf +is a non-standard function that appears in Solaris and glibc. .Sh BUGS .Fn setbuf usually uses a suboptimal buffer size and should be avoided.