home *** CD-ROM | disk | FTP | other *** search
- /*-----------------------------------------------------------------------*
- * filename - setvbuf.c
- *
- * function(s)
- * setvbuf - assigns buffering to a stream
- *-----------------------------------------------------------------------*/
-
- /*[]------------------------------------------------------------[]*/
- /*| |*/
- /*| Turbo C Run Time Library - Version 3.0 |*/
- /*| |*/
- /*| |*/
- /*| Copyright (c) 1987,1988,1990 by Borland International |*/
- /*| All Rights Reserved. |*/
- /*| |*/
- /*[]------------------------------------------------------------[]*/
-
- #include <stdio.h>
- #include <stdlib.h>
-
- extern void (*_exitbuf)();
- extern void _xfflush();
-
- static int _stdinStarted = 0;
- static int _stdoutStarted = 0;
-
- /*-----------------------------------------------------------------------*
-
- Name setvbuf - assigns buffering to a stream
-
- Usage #include <stdio.h>
- int setvbuf(FILE *stream, char *buf, int type,
- size_t size);
-
- Prototype in stdio.h
-
- Description setbuf and setvbuf cause the buffer buf to be used
- for I/O buffering instead of an automatically allocated buffer.
- They are used after the given stream is opened.
-
- In setbuf, if buf is NULL, I/O will be unbuffered; otherwise,
- it will be fully buffered. The buffer must be BUFSIZ bytes long
- (specified in stdio.h). In setvbuf, if buf is NULL, a buffer
- will be allocated using malloc; the buffer will use size as the
- amount allocated. The size parameter specifies the buffer size
- and must be greater than zero.
-
- stdin and stdout are unbuffered if they are not redirected;
- otherwise, they are fully buffered. setbuf may be used to
- change the buffering style being used.
-
- Unbuffered means that characters written to a stream are
- immediately output to the file or device, while buffered
- means that the characters are accumulated and written as
- a block.
-
- In setvbuf, the type parameter is one of the following:
-
- _IOFBF The file is fully buffered. When a buffer
- is empty, the next input operation will
- attempt to fill the entire buffer.
-
- On output the buffer will be completely
- filled before any data is written to the file.
-
- _IOLBF The file is line buffered. When a buffer
- is empty, the next input operation will still
- attempt to fill the entire buffer. On output,
- however, the buffer will be flushed whenever
- a newline character is written to the file.
-
- _IONBF The file is unbuffered. The buf and size
- parameters are ignored. Each input operation
- will read directly from the file, and each
- output operation will immediately write the
- data to the file.
-
- setbuf will produce unpredictable results if it is called for a
- stream, except immediately after opening the stream or any call
- to fseek. Calling setbuf after a stream has been unbuffered is
- legal and will not cause problems.
-
- A common cause for error is to allocate the buffer as an
- automatic (local) variable and then fail to close the file
- before returning from the function where the buffer was
- declared.
-
- Return value setbuf returns nothing.
-
- setvbuf returns 0 on success. It returns non-zero if an
- invalid value is given for type or size, if buf is NULL,
- or if there is not enough space to allocate a buffer.
-
- setvbuf returns 0 on success.
-
- *-----------------------------------------------------------------------*/
- int setvbuf(register FILE *fp, char *buf, int type, size_t size)
- {
- if (fp->token != (short) fp || _IONBF < type || 0x7fff < size)
- return(EOF);
-
- if (! _stdoutStarted && ((short) fp == (short) stdout))
- _stdoutStarted = 1;
- else
- if (! _stdinStarted && ((short) fp == (short) stdin))
- _stdinStarted = 1;
-
- /* Ensure the change in buffering causes no loss of characters.
- fseek() will fflush and reposition safely.
- */
- if (fp->level)
- fseek (fp, 0L, SEEK_CUR);
-
- if (fp->flags & _F_BUF)
- free (fp->buffer);
-
- fp->flags &= ~(_F_BUF | _F_LBUF);
- fp->bsize = 0;
- fp->curp = fp->buffer = & fp->hold;
-
- if (_IONBF != type && size > 0)
- {
- _exitbuf = _xfflush;
-
- if (NULL == buf)
- {
- if ((buf = malloc (size)) != NULL)
- fp->flags |= _F_BUF;
- else
- return(EOF);
- }
- fp->buffer = fp->curp = (unsigned char *)buf;
- fp->bsize = size;
- if (_IOLBF == type)
- fp->flags |= _F_LBUF;
- }
-
- return 0;
-
- }
-