1*46111Sbostic /*- 2*46111Sbostic * Copyright (c) 1990 The Regents of the University of California. 3*46111Sbostic * All rights reserved. 4*46111Sbostic * 5*46111Sbostic * This code is derived from software contributed to Berkeley by 6*46111Sbostic * Chris Torek. 7*46111Sbostic * 8*46111Sbostic * %sccs.include.redist.c% 9*46111Sbostic */ 10*46111Sbostic 11*46111Sbostic #if defined(LIBC_SCCS) && !defined(lint) 12*46111Sbostic static char sccsid[] = "@(#)setvbuf.c 5.1 (Berkeley) 01/20/91"; 13*46111Sbostic #endif /* LIBC_SCCS and not lint */ 14*46111Sbostic 15*46111Sbostic #include <stdio.h> 16*46111Sbostic #include <stdlib.h> 17*46111Sbostic #include "local.h" 18*46111Sbostic 19*46111Sbostic /* 20*46111Sbostic * Set one of the three kinds of buffering, optionally including 21*46111Sbostic * a buffer. 22*46111Sbostic */ 23*46111Sbostic setvbuf(fp, buf, mode, size) 24*46111Sbostic register FILE *fp; 25*46111Sbostic char *buf; 26*46111Sbostic register int mode; 27*46111Sbostic register size_t size; 28*46111Sbostic { 29*46111Sbostic 30*46111Sbostic /* 31*46111Sbostic * Verify arguments. The `int' limit on `size' is due to this 32*46111Sbostic * particular implementation. 33*46111Sbostic */ 34*46111Sbostic if ((mode != _IOFBF && mode != _IOLBF && mode != _IONBF) || 35*46111Sbostic (int)size < 0) 36*46111Sbostic return (EOF); 37*46111Sbostic 38*46111Sbostic /* 39*46111Sbostic * Write current buffer, if any; drop read count, if any. 40*46111Sbostic * Make sure putc() will not think fp is line buffered. 41*46111Sbostic * Free old buffer if it was from malloc(). Clear line and 42*46111Sbostic * non buffer flags, and clear malloc flag. 43*46111Sbostic */ 44*46111Sbostic (void) fflush(fp); 45*46111Sbostic fp->_r = 0; 46*46111Sbostic fp->_lbfsize = 0; 47*46111Sbostic if (fp->_flags & __SMBF) 48*46111Sbostic free((void *)fp->_bf._base); 49*46111Sbostic fp->_flags &= ~(__SLBF|__SNBF|__SMBF); 50*46111Sbostic 51*46111Sbostic /* 52*46111Sbostic * Now put back whichever flag is needed, and fix _lbfsize 53*46111Sbostic * if line buffered. Ensure output flush on exit if the 54*46111Sbostic * stream will be buffered at all. 55*46111Sbostic */ 56*46111Sbostic switch (mode) { 57*46111Sbostic 58*46111Sbostic case _IONBF: 59*46111Sbostic fp->_flags |= __SNBF; 60*46111Sbostic fp->_bf._base = fp->_p = fp->_nbuf; 61*46111Sbostic fp->_bf._size = 1; 62*46111Sbostic break; 63*46111Sbostic 64*46111Sbostic case _IOLBF: 65*46111Sbostic fp->_flags |= __SLBF; 66*46111Sbostic fp->_lbfsize = -size; 67*46111Sbostic /* FALLTHROUGH */ 68*46111Sbostic 69*46111Sbostic case _IOFBF: 70*46111Sbostic /* no flag */ 71*46111Sbostic __cleanup = _cleanup; 72*46111Sbostic fp->_bf._base = fp->_p = (unsigned char *)buf; 73*46111Sbostic fp->_bf._size = size; 74*46111Sbostic break; 75*46111Sbostic } 76*46111Sbostic 77*46111Sbostic /* 78*46111Sbostic * Patch up write count if necessary. 79*46111Sbostic */ 80*46111Sbostic if (fp->_flags & __SWR) 81*46111Sbostic fp->_w = fp->_flags & (__SLBF|__SNBF) ? 0 : size; 82*46111Sbostic 83*46111Sbostic return (0); 84*46111Sbostic } 85