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*60232Storek static char sccsid[] = "@(#)setvbuf.c 5.6 (Berkeley) 05/22/93"; 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 { 2956990Storek register int ret, flags; 3059778Storek size_t iosize; 3159778Storek int ttyflag; 3246111Sbostic 3346111Sbostic /* 3446111Sbostic * Verify arguments. The `int' limit on `size' is due to this 3559778Storek * particular implementation. Note, buf and size are ignored 3659778Storek * when setting _IONBF. 3746111Sbostic */ 3859778Storek if (mode != _IONBF) 3959778Storek if ((mode != _IOFBF && mode != _IOLBF) || (int)size < 0) 4059778Storek return (EOF); 4146111Sbostic 4246111Sbostic /* 4359778Storek * Write current buffer, if any. Discard unread input, cancel 4459778Storek * line buffering, and free old buffer if malloc()ed. 4546111Sbostic */ 4656990Storek ret = 0; 4759778Storek (void)__sflush(fp); 4859778Storek fp->_r = fp->_lbfsize = 0; 4956990Storek flags = fp->_flags; 5056990Storek if (flags & __SMBF) 5146111Sbostic free((void *)fp->_bf._base); 5259778Storek flags &= ~(__SLBF | __SNBF | __SMBF | __SOPT | __SNPT); 5346111Sbostic 5459778Storek /* If setting unbuffered mode, skip all the hard work. */ 5559778Storek if (mode == _IONBF) 5659778Storek goto nbf; 5759778Storek 5859778Storek /* 5959778Storek * Find optimal I/O size for seek optimization. This also returns 6059778Storek * a `tty flag' to suggest that we check isatty(fd), but we do not 6159778Storek * care since our caller told us how to buffer. 6259778Storek */ 6359778Storek flags |= __swhatbuf(fp, &iosize, &ttyflag); 6459778Storek if (size == 0) { 6559778Storek buf = NULL; /* force local allocation */ 6659778Storek size = iosize; 6759778Storek } 6859778Storek 6959778Storek /* Allocate buffer if needed. */ 7059778Storek if (buf == NULL) { 7156990Storek if ((buf = malloc(size)) == NULL) { 7259778Storek /* 7359778Storek * Unable to honor user's request. We will return 7459778Storek * failure, but try again with file system size. 7559778Storek */ 7656990Storek ret = EOF; 7759778Storek if (size != iosize) { 7859778Storek size = iosize; 7959778Storek buf = malloc(size); 8059778Storek } 8159778Storek } 8259778Storek if (buf == NULL) { 8359778Storek /* No luck; switch to unbuffered I/O. */ 8459778Storek nbf: 8559778Storek fp->_flags = flags | __SNBF; 8659778Storek fp->_w = 0; 8759778Storek fp->_bf._base = fp->_p = fp->_nbuf; 8859778Storek fp->_bf._size = 1; 8959778Storek return (ret); 9059778Storek } 9159778Storek flags |= __SMBF; 9256990Storek } 9356990Storek 9446111Sbostic /* 9559778Storek * Kill any seek optimization if the buffer is not the 9659778Storek * right size. 9759778Storek * 9859778Storek * SHOULD WE ALLOW MULTIPLES HERE (i.e., ok iff (size % iosize) == 0)? 9946111Sbostic */ 10059778Storek if (size != iosize) 10159778Storek flags |= __SNPT; 10246111Sbostic 10359778Storek /* 10459778Storek * Fix up the FILE fields, and set __cleanup for output flush on 105*60232Storek * exit (since we are buffered in some way). If in r/w mode, go 106*60232Storek * to the intermediate state, so that everyone has to call 107*60232Storek * __srefill or __swsetup on the first operation -- it is more 108*60232Storek * trouble than it is worth to set things up correctly here. 10959778Storek */ 110*60232Storek if (mode == _IOLBF) 11156990Storek flags |= __SLBF; 112*60232Storek if (flags & __SRW) 113*60232Storek flags &= ~(__SRD | __SWR); 114*60232Storek fp->_w = 0; 11556990Storek fp->_flags = flags; 11659778Storek fp->_bf._base = fp->_p = (unsigned char *)buf; 11759778Storek fp->_bf._size = size; 118*60232Storek fp->_lbfsize = 0; 11959778Storek __cleanup = _cleanup; 12046111Sbostic 12156990Storek return (ret); 12246111Sbostic } 123