Allow changing the default buffering policy for a stdio stream during
construction by setting environment variables.
This commit is contained in:
parent
2e2a488279
commit
90b9d61d73
|
@ -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 ,
|
||||
|
|
|
@ -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,9 +49,63 @@ __RCSID("$NetBSD: makebuf.c,v 1.17 2012/03/15 18:22:30 christos Exp $");
|
|||
#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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -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 characters are saved up and written as a block;
|
|||
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.
|
||||
|
|
Loading…
Reference in New Issue