Module Name: src Committed By: christos Date: Wed Jul 15 19:08:43 UTC 2015
Modified Files: src/lib/libc/stdio: fopen.3 makebuf.c setbuf.3 Log Message: Allow changing the default buffering policy for a stdio stream during construction by setting environment variables. To generate a diff of this commit: cvs rdiff -u -r1.30 -r1.31 src/lib/libc/stdio/fopen.3 cvs rdiff -u -r1.17 -r1.18 src/lib/libc/stdio/makebuf.c cvs rdiff -u -r1.13 -r1.14 src/lib/libc/stdio/setbuf.3 Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/lib/libc/stdio/fopen.3 diff -u src/lib/libc/stdio/fopen.3:1.30 src/lib/libc/stdio/fopen.3:1.31 --- src/lib/libc/stdio/fopen.3:1.30 Wed Feb 11 10:19:05 2015 +++ src/lib/libc/stdio/fopen.3 Wed Jul 15 15:08:43 2015 @@ -1,4 +1,4 @@ -.\" $NetBSD: fopen.3,v 1.30 2015/02/11 15:19:05 riastradh Exp $ +.\" $NetBSD: fopen.3,v 1.31 2015/07/15 19:08:43 christos Exp $ .\" .\" Copyright (c) 1990, 1991, 1993 .\" The Regents of the University of California. All rights reserved. @@ -196,6 +196,13 @@ standard text stream .Em stdin , or .Em stdout ) . +.Pp +Input and output against the opened stream will be fully buffered, unless +it refers to an interactive terminal device, or a different kind of buffering +is specified in the environment. +See +.Xr setvbuf 3 +for additional details. .Sh RETURN VALUES Upon successful completion .Fn fopen , Index: src/lib/libc/stdio/makebuf.c diff -u src/lib/libc/stdio/makebuf.c:1.17 src/lib/libc/stdio/makebuf.c:1.18 --- src/lib/libc/stdio/makebuf.c:1.17 Thu Mar 15 14:22:30 2012 +++ src/lib/libc/stdio/makebuf.c Wed Jul 15 15:08:43 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: makebuf.c,v 1.17 2012/03/15 18:22:30 christos Exp $ */ +/* $NetBSD: makebuf.c,v 1.18 2015/07/15 19:08:43 christos Exp $ */ /*- * Copyright (c) 1990, 1993 @@ -37,7 +37,7 @@ #if 0 static char sccsid[] = "@(#)makebuf.c 8.1 (Berkeley) 6/4/93"; #else -__RCSID("$NetBSD: makebuf.c,v 1.17 2012/03/15 18:22:30 christos Exp $"); +__RCSID("$NetBSD: makebuf.c,v 1.18 2015/07/15 19:08:43 christos Exp $"); #endif #endif /* LIBC_SCCS and not lint */ @@ -49,10 +49,64 @@ __RCSID("$NetBSD: makebuf.c,v 1.17 2012/ #include <stdio.h> #include <stdlib.h> #include <unistd.h> +#include <inttypes.h> +#include <ctype.h> #include "reentrant.h" #include "local.h" /* + * Override the file buffering based on the environment setting STDBUF%d + * (for the specific file descriptor) and STDBUF (for all descriptors). + * the setting is ULB<num> standing for "Unbuffered", "Linebuffered", + * and Fullybuffered", and <num> is a value from 0 to 1M. + */ +static int +__senvbuf(FILE *fp, size_t *size, int *couldbetty) +{ + char evb[64], *evp; + int flags, e; + intmax_t s; + + flags = 0; + if (snprintf(evb, sizeof(evb), "STDBUF%d", fp->_file) < 0) + return flags; + + if ((evp = getenv(evb)) == NULL && (evp = getenv("STDBUF")) == NULL) + return flags; + + switch (*evp) { + case 'u': + case 'U': + evp++; + flags |= __SNBF; + break; + case 'l': + case 'L': + evp++; + flags |= __SLBF; + break; + case 'f': + case 'F': + evp++; + *couldbetty = 0; + break; + } + + if (!isdigit((unsigned char)*evp)) + return flags; + + s = strtoi(evp, NULL, 0, 0, 1024 * 1024, &e); + if (e != 0) + return flags; + + *size = (size_t)s; + if (*size == 0) + return __SNBF; + + return flags; +} + +/* * Allocate a file buffer, or switch to unbuffered I/O. * Per the ANSI C standard, ALL tty devices default to line buffered. * @@ -69,18 +123,21 @@ __smakebuf(FILE *fp) _DIAGASSERT(fp != NULL); - if (fp->_flags & __SNBF) { - fp->_bf._base = fp->_p = fp->_nbuf; - fp->_bf._size = 1; - return; - } + if (fp->_flags & __SNBF) + goto unbuf; + flags = __swhatbuf(fp, &size, &couldbetty); - if ((p = malloc(size)) == NULL) { - fp->_flags |= __SNBF; - fp->_bf._base = fp->_p = fp->_nbuf; - fp->_bf._size = 1; - return; + + if ((fp->_flags & (__SLBF|__SNBF|__SMBF)) == 0 + && fp->_cookie == fp && fp->_file >= 0) { + flags |= __senvbuf(fp, &size, &couldbetty); + if (flags & __SNBF) + goto unbuf; } + + if ((p = malloc(size)) == NULL) + goto unbuf; + __cleanup = _cleanup; flags |= __SMBF; fp->_bf._base = fp->_p = p; @@ -89,6 +146,11 @@ __smakebuf(FILE *fp) if (couldbetty && isatty(__sfileno(fp))) flags |= __SLBF; fp->_flags |= flags; + return; +unbuf: + fp->_flags |= __SNBF; + fp->_bf._base = fp->_p = fp->_nbuf; + fp->_bf._size = 1; } /* Index: src/lib/libc/stdio/setbuf.3 diff -u src/lib/libc/stdio/setbuf.3:1.13 src/lib/libc/stdio/setbuf.3:1.14 --- src/lib/libc/stdio/setbuf.3:1.13 Thu Aug 7 12:43:31 2003 +++ src/lib/libc/stdio/setbuf.3 Wed Jul 15 15:08:43 2015 @@ -1,4 +1,4 @@ -.\" $NetBSD: setbuf.3,v 1.13 2003/08/07 16:43:31 agc Exp $ +.\" $NetBSD: setbuf.3,v 1.14 2015/07/15 19:08:43 christos Exp $ .\" .\" Copyright (c) 1980, 1991, 1993 .\" The Regents of the University of California. All rights reserved. @@ -63,6 +63,27 @@ when it is block buffered many character when it is line buffered characters are saved up until a newline is output or input is read from any stream attached to a terminal device (typically stdin). +.Pp +The default buffer settings can be overwritten per descriptor +.Dv ( STDBUFn ) +where +.Dv n +is the numeric value of the file descriptor represented by the stream, or +for all descriptors +.Dv ( STDBUF ) . +The environment variable value is a letter followed by an optional numeric +value indicating the size of the buffer. +Valid sizes range from 0B to 1MB. +Valid letters are: +.Bl -tag -width X -indent +.It Dv Li U +Unbuffered. +.It Dv Li L +Line-buffered. +.It Dv Li F +Fully-buffered. +.El +.Pp The function .Xr fflush 3 may be used to force the block out early.