home *** CD-ROM | disk | FTP | other *** search
- /***
- *setvbuf.c - set buffer size for a stream
- *
- * Copyright (c) 1985-1997, Microsoft Corporation. All rights reserved.
- *
- *Purpose:
- * defines setvbuf() - set the buffering mode and size for a stream.
- *
- *******************************************************************************/
-
- #include <cruntime.h>
- #include <stdio.h>
- #include <file2.h>
- #include <malloc.h>
- #include <internal.h>
- #include <mtdll.h>
- #include <limits.h>
- #include <dbgint.h>
-
- /***
- *int setvbuf(stream, buffer, type, size) - set buffering for a file
- *
- *Purpose:
- * Controls buffering and buffer size for the specified stream. The
- * array pointed to by buf is used as a buffer, unless NULL, in which
- * case we'll allocate a buffer automatically. type specifies the type
- * of buffering: _IONBF = no buffer, _IOFBF = buffered, _IOLBF = same
- * as _IOFBF.
- *
- *Entry:
- * FILE *stream - stream to control buffer on
- * char *buffer - pointer to buffer to use (NULL means auto allocate)
- * int type - type of buffering (_IONBF, _IOFBF or _IOLBF)
- * size_t size - size of buffer
- *
- *Exit:
- * return 0 if successful
- * returns non-zero if fails
- *
- *Exceptions:
- *
- *******************************************************************************/
-
- int __cdecl setvbuf (
- FILE *str,
- char *buffer,
- int type,
- size_t size
- )
- {
- REG1 FILE *stream;
- int retval=0; /* assume good return */
-
- _ASSERTE(str != NULL);
-
- /*
- * (1) Make sure type is one of the three legal values.
- * (2) If we are buffering, make sure size is greater than 0.
- */
- #ifdef _WIN32
- if ( (type != _IONBF) && ((size < 2) || (size > INT_MAX) ||
- #else /* _WIN32 */
- #if defined (_M_MPPC) || defined (_M_M68K)
- if ( (type != _IONBF) && ((size == 0) || (size > INT_MAX) ||
- #endif /* defined (_M_MPPC) || defined (_M_M68K) */
- #endif /* _WIN32 */
- ((type != _IOFBF) && (type != _IOLBF))) )
- return(-1);
-
- #ifdef _WIN32
- /*
- * force size to be even by masking down to the nearest multiple
- * of 2
- */
- size &= (size_t)~1;
- #endif /* _WIN32 */
-
- /*
- * Init stream pointers
- */
- stream = str;
-
- /*
- * Lock the file
- */
- _lock_str(stream);
-
- /*
- * Flush the current buffer and free it, if it is ours.
- */
- _flush(stream);
- _freebuf(stream);
-
- /*
- * Clear a bunch of bits in stream->_flag (all bits related to
- * buffering and those which used to be in stream2->_flag2). Most
- * of these should never be set when setvbuf() is called, but it
- * doesn't cost anything to be safe.
- */
- stream->_flag &= ~(_IOMYBUF | _IOYOURBUF | _IONBF |
- #ifdef _WIN32
- _IOSETVBUF |
- #endif /* _WIN32 */
- _IOFEOF | _IOFLRTN | _IOCTRLZ);
-
- /*
- * CASE 1: No Buffering.
- */
- if (type & _IONBF) {
- stream->_flag |= _IONBF;
- buffer = (char *)&(stream->_charbuf);
- #ifdef _WIN32
- size = 2;
- #else /* _WIN32 */
- #if defined (_M_MPPC) || defined (_M_M68K)
- size = 1;
- #endif /* defined (_M_MPPC) || defined (_M_M68K) */
- #endif /* _WIN32 */
- }
-
- /*
- * NOTE: Cases 2 and 3 (below) cover type == _IOFBF or type == _IOLBF
- * Line buffering is treated as the same as full buffering, so the
- * _IOLBF bit in stream->_flag is never set. Finally, since _IOFBF is
- * defined to be 0, full buffering is simply assumed whenever _IONBF
- * is not set.
- */
-
- /*
- * CASE 2: Default Buffering -- Allocate a buffer for the user.
- */
- else if ( buffer == NULL ) {
- if ( (buffer = _malloc_crt(size)) == NULL ) {
- #ifndef CRTDLL
- /*
- * force library pre-termination procedure (placed here
- * because the code path should almost never be hit)
- */
- _cflush++;
- #endif /* CRTDLL */
- retval = -1;
- goto done;
- }
- #ifdef _WIN32
- stream->_flag |= _IOMYBUF | _IOSETVBUF;
- #else /* _WIN32 */
- #if defined (_M_MPPC) || defined (_M_M68K)
- stream->_flag |= _IOMYBUF;
- #endif /* defined (_M_MPPC) || defined (_M_M68K) */
- #endif /* _WIN32 */
- }
-
- /*
- * CASE 3: User Buffering -- Use the buffer supplied by the user.
- */
- else {
- #ifdef _WIN32
- stream->_flag |= _IOYOURBUF | _IOSETVBUF;
- #else /* _WIN32 */
- #if defined (_M_MPPC) || defined (_M_M68K)
- stream->_flag |= _IOYOURBUF;
- #endif /* defined (_M_MPPC) || defined (_M_M68K) */
- #endif /* _WIN32 */
- }
-
- /*
- * Common return for all cases.
- */
- stream->_bufsiz = size;
- stream->_ptr = stream->_base = buffer;
- stream->_cnt = 0;
- done:
- _unlock_str(stream);
- return(retval);
- }
-