Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/lib/libc/stdio Allow changing the default buffering policy f...



details:   https://anonhg.NetBSD.org/src/rev/8f9a3c789396
branches:  trunk
changeset: 339352:8f9a3c789396
user:      christos <christos%NetBSD.org@localhost>
date:      Wed Jul 15 19:08:43 2015 +0000

description:
Allow changing the default buffering policy for a stdio stream during
construction by setting environment variables.

diffstat:

 lib/libc/stdio/fopen.3   |   9 ++++-
 lib/libc/stdio/makebuf.c |  86 +++++++++++++++++++++++++++++++++++++++++------
 lib/libc/stdio/setbuf.3  |  23 ++++++++++++-
 3 files changed, 104 insertions(+), 14 deletions(-)

diffs (187 lines):

diff -r e5574b0c9c9d -r 8f9a3c789396 lib/libc/stdio/fopen.3
--- a/lib/libc/stdio/fopen.3    Wed Jul 15 14:43:01 2015 +0000
+++ b/lib/libc/stdio/fopen.3    Wed Jul 15 19:08:43 2015 +0000
@@ -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 @@
 .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 ,
diff -r e5574b0c9c9d -r 8f9a3c789396 lib/libc/stdio/makebuf.c
--- a/lib/libc/stdio/makebuf.c  Wed Jul 15 14:43:01 2015 +0000
+++ b/lib/libc/stdio/makebuf.c  Wed Jul 15 19:08:43 2015 +0000
@@ -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 @@
 #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 @@
 
        _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 @@
        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;
 }
 
 /*
diff -r e5574b0c9c9d -r 8f9a3c789396 lib/libc/stdio/setbuf.3
--- a/lib/libc/stdio/setbuf.3   Wed Jul 15 14:43:01 2015 +0000
+++ b/lib/libc/stdio/setbuf.3   Wed Jul 15 19:08:43 2015 +0000
@@ -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 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.



Home | Main Index | Thread Index | Old Index