? o Index: makebuf.c =================================================================== RCS file: /cvsroot/src/lib/libc/stdio/makebuf.c,v retrieving revision 1.17 diff -u -u -r1.17 makebuf.c --- makebuf.c 15 Mar 2012 18:22:30 -0000 1.17 +++ makebuf.c 14 Jul 2015 19:57:24 -0000 @@ -49,10 +49,64 @@ #include #include #include +#include +#include #include "reentrant.h" #include "local.h" /* + * Override the file buffering based on the environment setting STDIOBUF%d + * (for the specific file descriptor) and STDIOBUF (for all descriptors). + * the setting is ULB standing for "Unbuffered", "Linebuffered", + * and Fullybuffered", and is a value from 0 to + */ +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,12 @@ 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; + return; } /*