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*59778Storek static char sccsid[] = "@(#)setvbuf.c 5.5 (Berkeley) 05/06/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; 30*59778Storek size_t iosize; 31*59778Storek int ttyflag; 3246111Sbostic 3346111Sbostic /* 3446111Sbostic * Verify arguments. The `int' limit on `size' is due to this 35*59778Storek * particular implementation. Note, buf and size are ignored 36*59778Storek * when setting _IONBF. 3746111Sbostic */ 38*59778Storek if (mode != _IONBF) 39*59778Storek if ((mode != _IOFBF && mode != _IOLBF) || (int)size < 0) 40*59778Storek return (EOF); 4146111Sbostic 4246111Sbostic /* 43*59778Storek * Write current buffer, if any. Discard unread input, cancel 44*59778Storek * line buffering, and free old buffer if malloc()ed. 4546111Sbostic */ 4656990Storek ret = 0; 47*59778Storek (void)__sflush(fp); 48*59778Storek fp->_r = fp->_lbfsize = 0; 4956990Storek flags = fp->_flags; 5056990Storek if (flags & __SMBF) 5146111Sbostic free((void *)fp->_bf._base); 52*59778Storek flags &= ~(__SLBF | __SNBF | __SMBF | __SOPT | __SNPT); 5346111Sbostic 54*59778Storek /* If setting unbuffered mode, skip all the hard work. */ 55*59778Storek if (mode == _IONBF) 56*59778Storek goto nbf; 57*59778Storek 58*59778Storek /* 59*59778Storek * Find optimal I/O size for seek optimization. This also returns 60*59778Storek * a `tty flag' to suggest that we check isatty(fd), but we do not 61*59778Storek * care since our caller told us how to buffer. 62*59778Storek */ 63*59778Storek flags |= __swhatbuf(fp, &iosize, &ttyflag); 64*59778Storek if (size == 0) { 65*59778Storek buf = NULL; /* force local allocation */ 66*59778Storek size = iosize; 67*59778Storek } 68*59778Storek 69*59778Storek /* Allocate buffer if needed. */ 70*59778Storek if (buf == NULL) { 7156990Storek if ((buf = malloc(size)) == NULL) { 72*59778Storek /* 73*59778Storek * Unable to honor user's request. We will return 74*59778Storek * failure, but try again with file system size. 75*59778Storek */ 7656990Storek ret = EOF; 77*59778Storek if (size != iosize) { 78*59778Storek size = iosize; 79*59778Storek buf = malloc(size); 80*59778Storek } 81*59778Storek } 82*59778Storek if (buf == NULL) { 83*59778Storek /* No luck; switch to unbuffered I/O. */ 84*59778Storek nbf: 85*59778Storek fp->_flags = flags | __SNBF; 86*59778Storek fp->_w = 0; 87*59778Storek fp->_bf._base = fp->_p = fp->_nbuf; 88*59778Storek fp->_bf._size = 1; 89*59778Storek return (ret); 90*59778Storek } 91*59778Storek flags |= __SMBF; 9256990Storek } 9356990Storek 9446111Sbostic /* 95*59778Storek * Kill any seek optimization if the buffer is not the 96*59778Storek * right size. 97*59778Storek * 98*59778Storek * SHOULD WE ALLOW MULTIPLES HERE (i.e., ok iff (size % iosize) == 0)? 9946111Sbostic */ 100*59778Storek if (size != iosize) 101*59778Storek flags |= __SNPT; 10246111Sbostic 103*59778Storek /* 104*59778Storek * Fix up the FILE fields, and set __cleanup for output flush on 105*59778Storek * exit (since we are buffered in some way). Note that _w can 106*59778Storek * always be set to 0 safely here---it should be 0 in read mode 107*59778Storek * or the `indeterminate' state, and 0 for line buffered---so 108*59778Storek * using the new buffer size for fully-buffered streams in write 109*59778Storek * mode is merely a tiny optimization. 110*59778Storek */ 111*59778Storek if (mode == _IOLBF) { 11256990Storek flags |= __SLBF; 11346111Sbostic fp->_lbfsize = -size; 114*59778Storek fp->_w = 0; 115*59778Storek } else 116*59778Storek fp->_w = flags & __SWR ? size : 0; 11756990Storek fp->_flags = flags; 118*59778Storek fp->_bf._base = fp->_p = (unsigned char *)buf; 119*59778Storek fp->_bf._size = size; 120*59778Storek __cleanup = _cleanup; 12146111Sbostic 12256990Storek return (ret); 12346111Sbostic } 124