summaryrefslogtreecommitdiffstats
path: root/private/crt32/stdio/setvbuf.c
diff options
context:
space:
mode:
Diffstat (limited to 'private/crt32/stdio/setvbuf.c')
-rw-r--r--private/crt32/stdio/setvbuf.c180
1 files changed, 180 insertions, 0 deletions
diff --git a/private/crt32/stdio/setvbuf.c b/private/crt32/stdio/setvbuf.c
new file mode 100644
index 000000000..665cee028
--- /dev/null
+++ b/private/crt32/stdio/setvbuf.c
@@ -0,0 +1,180 @@
+/***
+*setvbuf.c - set buffer size for a stream
+*
+* Copyright (c) 1985-1993, Microsoft Corporation. All rights reserved.
+*
+*Purpose:
+* defines setvbuf() - set the buffering mode and size for a stream.
+*
+*Revision History:
+* 09-19-83 RN initial version
+* 06-26-85 TC modified to allow user defined buffers of various sizes
+* 06-24-86 DFW kludged to fix incompatability with Xenix values of
+* _IOFBF, _IOLBF
+* 02-09-87 JCR added "buffer=&(_iob2[fileno(stream)]._charbuf);"
+* to handle _IONBF case
+* 02-25-87 JCR added support for default buffer and IBMC20-condition
+* code
+* 04-13-87 JCR changed type of szie from int to size_t (unsigned int)
+* and changed a related comparison
+* 06-29-87 JCR Took out the _OLD_IOFBF/_OLD_IOLBF kludge for MSC.
+* Should be taken out for IBM too...
+* 09-28-87 JCR Corrected _iob2 indexing (now uses _iob_index() macro).
+* 11-02-87 JCR Multi-thread support
+* 12-11-87 JCR Added "_LOAD_DS" to declaration
+* 05-27-88 PHG Merged DLL and normal versions
+* 06-06-88 JCR Optimized _iob2 references
+* 06-14-88 JCR Use near pointer to reference _iob[] entries
+* 08-09-88 JCR Buffer size can't be greater than INT_MAX
+* 08-25-88 GJF Don't use FP_OFF() macro for the 386
+* 08-18-89 GJF Clean up, now specific to OS/2 2.0 (i.e., 386 flat
+* model). Also fixed copyright and indents.
+* 02-15-90 GJF _iob[], _iob2[] merge. Also, cleanup, a little tuning
+* and fixed copyright.
+* 03-19-90 GJF Made calling type _CALLTYPE1, added #include
+* <cruntime.h> and removed #include <register.h>.
+* 05-29-90 SBM Use _flush, not [_]fflush[_lk]
+* 07-23-90 SBM Replaced <assertm.h> by <assert.h>
+* 10-03-90 GJF New-style function declarator.
+* 04-27-93 CFW Change _IONBF size to 2 bytes to hold wide char.
+*
+*******************************************************************************/
+
+#include <cruntime.h>
+#include <stdio.h>
+#include <file2.h>
+#include <assert.h>
+#include <malloc.h>
+#include <internal.h>
+#include <os2dll.h>
+#include <limits.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 _CRTAPI1 setvbuf (
+ FILE *str,
+ char *buffer,
+ int type,
+ size_t size
+ )
+{
+ REG1 FILE *stream;
+#ifdef MTHREAD
+ int index;
+#endif
+ int retval=0; /* assume good return */
+
+ assert(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.
+ */
+ if ( (type != _IONBF) && ((size == 0) || (size > INT_MAX) ||
+ ((type != _IOFBF) && (type != _IOLBF))) )
+ return(-1);
+
+ /* force size to be even */
+ size &= (size_t)~1;
+
+ /*
+ * Init stream pointers
+ */
+ stream = str;
+
+#ifdef MTHREAD
+ index = _iob_index(stream);
+#endif
+ /*
+ * Lock the file
+ */
+ _lock_str(index);
+
+ /*
+ * 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 | _IOFEOF |
+ _IOFLRTN | _IOCTRLZ);
+
+ /*
+ * CASE 1: No Buffering.
+ */
+ if (type & _IONBF) {
+ stream->_flag |= _IONBF;
+ buffer = (char *)&(stream->_charbuf);
+ size = 2;
+ }
+
+ /*
+ * 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(size)) == NULL ) {
+ /*
+ * force library pre-termination procedure (placed here
+ * because the code path should almost never be hit)
+ */
+ _cflush++;
+
+ retval = -1;
+ goto done;
+ }
+ stream->_flag |= _IOMYBUF;
+ }
+
+ /*
+ * CASE 3: User Buffering -- Use the buffer supplied by the user.
+ */
+ else {
+ stream->_flag |= _IOYOURBUF;
+ }
+
+ /*
+ * Common return for all cases.
+ */
+ stream->_bufsiz = size;
+ stream->_ptr = stream->_base = buffer;
+ stream->_cnt = 0;
+done:
+ _unlock_str(index);
+ return(retval);
+}