summaryrefslogtreecommitdiffstats
path: root/private/crt32/stdio/_sftbuf.c
diff options
context:
space:
mode:
Diffstat (limited to 'private/crt32/stdio/_sftbuf.c')
-rw-r--r--private/crt32/stdio/_sftbuf.c223
1 files changed, 223 insertions, 0 deletions
diff --git a/private/crt32/stdio/_sftbuf.c b/private/crt32/stdio/_sftbuf.c
new file mode 100644
index 000000000..ec81c7657
--- /dev/null
+++ b/private/crt32/stdio/_sftbuf.c
@@ -0,0 +1,223 @@
+/***
+*_sftbuf.c - temporary buffering initialization and flushing
+*
+* Copyright (c) 1985-1992, Microsoft Corporation. All rights reserved.
+*
+*Purpose:
+* temporary buffering initialization and flushing. if stdout/err is
+* unbuffered, buffer it temporarily so that string is sent to kernel as
+* a batch of chars, not char-at-a-time. if appropriate, make buffering
+* permanent.
+*
+* [NOTE 1: These routines assume that the temporary buffering is only
+* used for output. In particular, note that _stbuf() sets _IOWRT.]
+*
+* [NOTE 2: It is valid for this module to assign a value directly to
+* _flag instead of simply twiddling bits since we are initializing the
+* buffer data base.]
+*
+*Revision History:
+* 09-01-83 RN initial version
+* 06-26-85 TC added code to _stbuf to allow variable buffer lengths
+* ??-??-?? TC fixed case in _flbuf where flag is off, but a temporary
+* buffer still needs to be fflushed.
+* 05-27-87 JCR protect mode does not know about stdprn.
+* 06-26-87 JCR Conditionalized out code in _ftbuf that caused
+* redirected stdout to be flushed on every call.
+* 07-01-87 JCR Put in code to support re-entrant calling from
+* interrupt level (MSC only).
+* 08-06-87 JCR Fixed a _ftbuf() problem pertaining to stderr/stdprn
+* when _bufout is being used by stdout.
+* 08-07-87 JCR (1) When assigning _bufout to an _iob, we now set the
+* _IOWRT flag. This fixes a bug involving freopen()
+* issued against one of the std handles.
+* (2) Removed some annoying commented out code.
+* 08-13-87 JCR _ftbuf() does NOT clear _IOWRT now. Fixes a bug where
+* _getstream() would reassign stdout because none of the
+* flags were set.
+* 09-28-87 JCR Corrected _iob2 indexing (now uses _iob_index() macro).
+* 11-05-87 JCR Re-written for multi-thread support and simplicity
+* 01-11-88 JCR Merged mthread version into normal version
+* 01-13-88 SKS Changed bogus "_fileno_lk" to "fileno"
+* 06-06-88 JCR Optimized _iob2 references
+* 06-10-88 JCR Use near pointer to reference _iob[] entries
+* 06-27-88 JCR Added stdprn temporary buffering support (DOS only),
+* and made buffer allocation dynamic; also added _IOFLRTN
+* (flush stream on per routine basis).
+* 08-25-88 GJF Modified to also work for the 386 (small model only).
+* 06-20-89 PHG Changed return value to void
+* 08-28-89 JCR Removed _NEAR_ for 386
+* 02-15-90 GJF _iob[], _iob2[] merge. Also, fixed copyright and
+* indents.
+* 03-16-90 GJF Made calling type _CALLTYPE1, added #include
+* <cruntime.h> and removed #include <register.h>. Also,
+* removed some leftover 16-bit DOS support.
+* 03-27-90 GJF Added #include <io.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.
+* 01-22-91 GJF ANSI naming.
+* 03-27-92 DJM POSIX support.
+* 08-26-92 GJF Include unistd.h for POSIX build.
+*
+*******************************************************************************/
+
+#include <cruntime.h>
+#ifdef _POSIX_
+#include <unistd.h>
+#endif
+#include <stdio.h>
+#include <file2.h>
+#include <io.h>
+#include <assert.h>
+#include <internal.h>
+#include <malloc.h>
+#ifdef MTHREAD
+#include <os2dll.h>
+#endif
+
+/* Buffer pointers for stdout and stderr */
+void *_stdbuf[2] = { NULL, NULL};
+
+/***
+*int _stbuf(stream) - set temp buffer on stdout, stdprn, stderr
+*
+*Purpose:
+* if stdout/stderr is still unbuffered, buffer it.
+* this function works intimately with _ftbuf, and accompanies it in
+* bracketing normally unbuffered output. these functions intended for
+* library use only.
+*
+* Multi-thread: It is assumed that the caller has already aquired the
+* stream lock.
+*
+*Entry:
+* FILE *stream - stream to temp buffer
+*
+*Exit:
+* returns 1 if buffer initialized, 0 if not
+* sets fields in stdout or stderr to indicate buffering
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+int _CALLTYPE1 _stbuf (
+ FILE *str
+ )
+{
+ REG1 FILE *stream;
+ int index;
+
+ assert(str != NULL);
+
+ /* Init near stream pointer */
+ stream = str;
+
+ /* do nothing if not a tty device */
+#ifdef _POSIX_
+ if (!isatty(fileno(stream)))
+#else
+ if (!_isatty(_fileno(stream)))
+#endif
+ return(0);
+
+ /* Make sure stream is stdout/stderr and init _stdbuf index */
+ if (stream == stdout)
+ index = 0;
+ else if (stream == stderr)
+ index = 1;
+ else
+ return(0);
+
+ _cflush++; /* force library pre-termination procedure */
+
+ /* Make sure the stream is not already buffered. */
+ if (anybuf(stream))
+ return(0);
+
+ /* Allocate a buffer for this stream if we haven't done so yet. */
+ if (_stdbuf[index] == NULL)
+ if ( (_stdbuf[index]=malloc(BUFSIZ)) == NULL )
+ return(0); /* error */
+
+ /* Set up the buffer */
+ stream->_ptr = stream->_base = _stdbuf[index];
+ stream->_cnt = stream->_bufsiz = BUFSIZ;
+ stream->_flag |= (_IOWRT | _IOYOURBUF | _IOFLRTN);
+
+ return(1);
+}
+
+
+/***
+*void _ftbuf(flag, stream) - take temp buffering off a stream
+*
+*Purpose:
+* If stdout/stderr is being buffered and it is a device, _flush and
+* dismantle the buffer. if it's not a device, leave the buffering on.
+* This function works intimately with _stbuf, and accompanies it in
+* bracketing normally unbuffered output. these functions intended for
+* library use only
+*
+* Multi-thread: It is assumed that the caller has already aquired the
+* stream lock.
+*
+*Entry:
+* int flag - a flag to tell whether to dismantle temp buffering on a
+* stream
+* FILE *stream - the stream
+*
+*Exit:
+* no return value
+* sets fields in stdout/stderr
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+void _CALLTYPE1 _ftbuf (
+ int flag,
+ FILE *str
+ )
+{
+ REG1 FILE *stream;
+
+ assert(flag == 0 || flag == 1);
+
+ /* Init near stream pointers */
+ stream = str;
+
+ if (flag) {
+
+ if (stream->_flag & _IOFLRTN) {
+
+ /* Flush the stream and tear down temp buffering. */
+ _flush(stream);
+ stream->_flag &= ~(_IOYOURBUF | _IOFLRTN);
+ stream->_bufsiz = 0;
+ stream->_base = stream->_ptr = NULL;
+ }
+
+ /* Note: If we expand the functionality of the _IOFLRTN bit to
+ include other streams, we may want to clear that bit here under
+ an 'else' clause (i.e., clear bit in the case that we leave the
+ buffer permanently assigned. Given our current use of the bit,
+ the extra code is not needed. */
+
+ } /* end flag = 1 */
+
+#ifndef MTHREAD
+/* NOTE: Currently, writing to the same string at interrupt level does not
+ work in multi-thread programs. */
+
+/* The following code is needed if an interrupt occurs between calls
+ to _stbuf/_ftbuf and the interrupt handler also calls _stbuf/_ftbuf. */
+
+ else
+ if (stream->_flag & _IOFLRTN)
+ _flush(stream);
+
+#endif /* MTHREAD */
+
+}