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.

Reply via email to