146111Sbostic /*- 246111Sbostic * Copyright (c) 1990 The Regents of the University of California. 346111Sbostic * All rights reserved. 446111Sbostic * 546111Sbostic * This code is derived from software contributed to Berkeley by 646111Sbostic * Chris Torek. 746111Sbostic * 846111Sbostic * %sccs.include.redist.c% 946111Sbostic */ 1046111Sbostic 1146111Sbostic #if defined(LIBC_SCCS) && !defined(lint) 12*46217Sbostic static char sccsid[] = "@(#)setvbuf.c 5.2 (Berkeley) 02/01/91"; 1346111Sbostic #endif /* LIBC_SCCS and not lint */ 1446111Sbostic 1546111Sbostic #include <stdio.h> 1646111Sbostic #include <stdlib.h> 1746111Sbostic #include "local.h" 1846111Sbostic 1946111Sbostic /* 2046111Sbostic * Set one of the three kinds of buffering, optionally including 2146111Sbostic * a buffer. 2246111Sbostic */ 2346111Sbostic setvbuf(fp, buf, mode, size) 2446111Sbostic register FILE *fp; 2546111Sbostic char *buf; 2646111Sbostic register int mode; 2746111Sbostic register size_t size; 2846111Sbostic { 2946111Sbostic 3046111Sbostic /* 3146111Sbostic * Verify arguments. The `int' limit on `size' is due to this 3246111Sbostic * particular implementation. 3346111Sbostic */ 3446111Sbostic if ((mode != _IOFBF && mode != _IOLBF && mode != _IONBF) || 3546111Sbostic (int)size < 0) 3646111Sbostic return (EOF); 3746111Sbostic 3846111Sbostic /* 3946111Sbostic * Write current buffer, if any; drop read count, if any. 4046111Sbostic * Make sure putc() will not think fp is line buffered. 4146111Sbostic * Free old buffer if it was from malloc(). Clear line and 4246111Sbostic * non buffer flags, and clear malloc flag. 4346111Sbostic */ 44*46217Sbostic (void) __sflush(fp); 4546111Sbostic fp->_r = 0; 4646111Sbostic fp->_lbfsize = 0; 4746111Sbostic if (fp->_flags & __SMBF) 4846111Sbostic free((void *)fp->_bf._base); 4946111Sbostic fp->_flags &= ~(__SLBF|__SNBF|__SMBF); 5046111Sbostic 5146111Sbostic /* 5246111Sbostic * Now put back whichever flag is needed, and fix _lbfsize 5346111Sbostic * if line buffered. Ensure output flush on exit if the 5446111Sbostic * stream will be buffered at all. 5546111Sbostic */ 5646111Sbostic switch (mode) { 5746111Sbostic 5846111Sbostic case _IONBF: 5946111Sbostic fp->_flags |= __SNBF; 6046111Sbostic fp->_bf._base = fp->_p = fp->_nbuf; 6146111Sbostic fp->_bf._size = 1; 6246111Sbostic break; 6346111Sbostic 6446111Sbostic case _IOLBF: 6546111Sbostic fp->_flags |= __SLBF; 6646111Sbostic fp->_lbfsize = -size; 6746111Sbostic /* FALLTHROUGH */ 6846111Sbostic 6946111Sbostic case _IOFBF: 7046111Sbostic /* no flag */ 7146111Sbostic __cleanup = _cleanup; 7246111Sbostic fp->_bf._base = fp->_p = (unsigned char *)buf; 7346111Sbostic fp->_bf._size = size; 7446111Sbostic break; 7546111Sbostic } 7646111Sbostic 7746111Sbostic /* 7846111Sbostic * Patch up write count if necessary. 7946111Sbostic */ 8046111Sbostic if (fp->_flags & __SWR) 8146111Sbostic fp->_w = fp->_flags & (__SLBF|__SNBF) ? 0 : size; 8246111Sbostic 8346111Sbostic return (0); 8446111Sbostic } 85