* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
* This code is derived from software contributed to Berkeley by
* %sccs.include.redist.c%
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid
[] = "@(#)setvbuf.c 8.1 (Berkeley) %G%";
#endif /* LIBC_SCCS and not lint */
* Set one of the three kinds of buffering, optionally including
setvbuf(fp
, buf
, mode
, size
)
* Verify arguments. The `int' limit on `size' is due to this
* particular implementation. Note, buf and size are ignored
if ((mode
!= _IOFBF
&& mode
!= _IOLBF
) || (int)size
< 0)
* Write current buffer, if any. Discard unread input, cancel
* line buffering, and free old buffer if malloc()ed.
fp
->_r
= fp
->_lbfsize
= 0;
free((void *)fp
->_bf
._base
);
flags
&= ~(__SLBF
| __SNBF
| __SMBF
| __SOPT
| __SNPT
);
/* If setting unbuffered mode, skip all the hard work. */
* Find optimal I/O size for seek optimization. This also returns
* a `tty flag' to suggest that we check isatty(fd), but we do not
* care since our caller told us how to buffer.
flags
|= __swhatbuf(fp
, &iosize
, &ttyflag
);
buf
= NULL
; /* force local allocation */
/* Allocate buffer if needed. */
if ((buf
= malloc(size
)) == NULL
) {
* Unable to honor user's request. We will return
* failure, but try again with file system size.
/* No luck; switch to unbuffered I/O. */
fp
->_flags
= flags
| __SNBF
;
fp
->_bf
._base
= fp
->_p
= fp
->_nbuf
;
* Kill any seek optimization if the buffer is not the
* SHOULD WE ALLOW MULTIPLES HERE (i.e., ok iff (size % iosize) == 0)?
* Fix up the FILE fields, and set __cleanup for output flush on
* exit (since we are buffered in some way). If in r/w mode, go
* to the intermediate state, so that everyone has to call
* __srefill or __swsetup on the first operation -- it is more
* trouble than it is worth to set things up correctly here.
flags
&= ~(__SRD
| __SWR
);
fp
->_bf
._base
= fp
->_p
= (unsigned char *)buf
;