1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
|
/***
*_flsbuf.c - flush buffer and output character.
*
* Copyright (c) 1985-1993, Microsoft Corporation. All rights reserved.
*
*Purpose:
* defines _flsbuf() - flush a file buffer and output a character.
* defines _flswbuf() - flush a file buffer and output a wide character.
* If no buffer, make one.
*
*Revision History:
* 09-01-83 RN initial version
* 06-26-85 TC added code to handle variable length buffers
* 06-08-87 JCR When buffer is allocated or when first write to buffer
* occurs, if stream is in append mode, then position file
* pointer to end.
* 07-20-87 SKS Change first parameter "ch" from (char) to (int)
* 09-28-87 JCR Corrected _iob2 indexing (now uses _iob_index() macro).
* 11-05-87 JCR Re-wrote for simplicity and for new stderr/stdout
* handling
* 12-11-87 JCR Added "_LOAD_DS" to declaration
* 01-11-88 JCR Merged mthread version into normal code
* 01-13-88 SKS Changed bogus "_fileno_lk" to "fileno"
* 06-06-88 JCR Optimized _iob2 references
* 06-13-88 JCR Use near pointer to reference _iob[] entries
* 06-28-88 JCR Support for dynamic buffer allocation for stdout/stderr
* 07-28-88 GJF Set stream->_cnt to 0 if _IOREAD is set.
* 08-25-88 GJF Added checked that OS2 is defined whenever M_I386 is.
* 06-20-89 PHG Removed FP_OFF macro call.
* 08-28-89 JCR Removed _NEAR_ for 386
* 02-15-90 GJF _iob[], _iob2[] merge. Also, fixed copyright and
* indents.
* 03-16-90 GJF Replaced cdecl _LOAD_DS with _CALLTYPE1, added #include
* <cruntime.h> and removed #include <register.h>. Also,
* removed some leftover 16-bit support.
* 03-27-90 GJF Added #include <io.h>.
* 07-23-90 SBM Replaced <assertm.h> by <assert.h>
* 08-07-90 SBM Restored descriptive text in assertion
* 08-14-90 SBM Compiles cleanly with -W3
* 10-03-90 GJF New-style function declarator.
* 01-22-91 GJF ANSI naming.
* 03-25-91 DJM POSIX support
* 08-26-92 GJF Include unistd.h for POSIX build.
* 04-26-93 CFW Wide char enable.
* 05-06-93 CFW Optimize wide char conversion.
*
*******************************************************************************/
#include <cruntime.h>
#include <stdio.h>
#include <file2.h>
#include <io.h>
#include <assert.h>
#include <malloc.h>
#ifdef _POSIX_
#include <unistd.h>
#include <errno.h>
#else
#include <msdos.h>
#endif
#include <internal.h>
#ifdef MTHREAD
#include <os2dll.h>
#endif
#include <wchar.h>
#include <tchar.h>
#ifndef _UNICODE
/***
*int _flsbuf(ch, stream) - flush buffer and output character.
*
*Purpose:
* flush a buffer if this stream has one. if not, try to get one. put the
* next output char (ch) into the buffer (or output it immediately if this
* stream can't have a buffer). called only from putc. intended for use
* only within library.
*
* [NOTE: Multi-thread - It is assumed that the caller has aquired
* the stream lock.]
*
*Entry:
* FILE *stream - stream to flish and write on
* int ch - character to output.
*
*Exit:
* returns -1 if FILE is actually a string, or if can't write ch to
* unbuffered file, or if we flush a buffer but the number of chars
* written doesn't agree with buffer size. Otherwise returns ch.
* all fields in FILE struct can be affected except _file.
*
*Exceptions:
*
*******************************************************************************/
int _CRTAPI1 _flsbuf (
int ch,
FILE *str
)
#else /* _UNICODE */
/***
*int _flswbuf(ch, stream) - flush buffer and output wide character.
*
*Purpose:
* flush a buffer if this stream has one. if not, try to get one. put the
* next output wide char (ch) into the buffer (or output it immediately if this
* stream can't have a buffer). called only from putwc. intended for use
* only within library.
*
* [NOTE: Multi-thread - It is assumed that the caller has aquired
* the stream lock.]
*
*Entry:
* FILE *stream - stream to flish and write on
* int ch - wide character to output.
*
*Exit:
* returns -1 if FILE is actually a string, or if can't write ch to
* unbuffered file, or if we flush a buffer but the number of wide chars
* written doesn't agree with buffer size. Otherwise returns ch.
* all fields in FILE struct can be affected except _file.
*
*Exceptions:
*
*******************************************************************************/
int _CRTAPI1 _flswbuf (
int ch,
FILE *str
)
#endif /* _UNICODE */
{
#if defined _NTSUBSET_ && !defined _POSIX_
str->_flag |= _IOERR;
return(_TEOF);
#else
REG1 FILE *stream;
REG2 int charcount;
REG3 int written;
int fh;
assert(str != NULL);
/* Init file handle and pointers */
stream = str;
#ifdef _POSIX_
fh = fileno(stream);
#else
fh = _fileno(stream);
#endif
if (!(stream->_flag & (_IOWRT|_IORW)) || (stream->_flag & _IOSTRG)) {
#ifdef _POSIX_
errno = EBADF;
#endif
stream->_flag |= _IOERR;
return(_TEOF);
}
/* Check that _IOREAD is not set or, if it is, then so is _IOEOF. Note
that _IOREAD and IOEOF both being set implies switching from read to
write at end-of-file, which is allowed by ANSI. Note that resetting
the _cnt and _ptr fields amounts to doing an fflush() on the stream
in this case. Note also that the _cnt field has to be reset to 0 for
the error path as well (i.e., _IOREAD set but _IOEOF not set) as
well as the non-error path. */
if (stream->_flag & _IOREAD) {
stream->_cnt = 0;
if (stream->_flag & _IOEOF) {
stream->_ptr = stream->_base;
stream->_flag &= ~_IOREAD;
}
else {
stream->_flag |= _IOERR;
return(_TEOF);
}
}
stream->_flag |= _IOWRT;
stream->_flag &= ~_IOEOF;
written = charcount = stream->_cnt = 0;
/* Get a buffer for this stream, if necessary. */
if (!anybuf(stream)) {
/* Do NOT get a buffer if (1) stream is stdout/stderr, and
(2) stream is NOT a tty.
[If stdout/stderr is a tty, we do NOT set up single char
buffering. This is so that later temporary buffering will
not be thwarted by the _IONBF bit being set (see
_stbuf/_ftbuf usage).]
*/
if (!( ((stream==stdout) || (stream==stderr))
#ifdef _POSIX_
&& (isatty(fh)) ))
#else
&& (_isatty(fh)) ))
#endif
_getbuf(stream);
} /* end !anybuf() */
/* If big buffer is assigned to stream... */
if (bigbuf(stream)) {
assert(("inconsistent IOB fields", stream->_ptr - stream->_base >= 0));
charcount = stream->_ptr - stream->_base;
stream->_ptr = stream->_base + sizeof(TCHAR);
stream->_cnt = stream->_bufsiz - sizeof(TCHAR);
if (charcount > 0)
#ifdef _POSIX_
written = write(fh, stream->_base, charcount);
#else
written = _write(fh, stream->_base, charcount);
#endif
else
#ifdef _POSIX_
if (stream->_flag & _IOAPPEND)
lseek(fh,0l,SEEK_END);
#else
if (_osfile[fh] & FAPPEND)
_lseek(fh,0L,SEEK_END);
#endif
#ifndef _UNICODE
*stream->_base = (char)ch;
#else /* _UNICODE */
*(wchar_t *)(stream->_base) = (wchar_t)(ch & 0xffff);
#endif /* _UNICODE */
}
/* Perform single character output (either _IONBF or no buffering) */
else {
charcount = sizeof(TCHAR);
#ifndef _UNICODE
#ifdef _POSIX_
written = write(fh, &ch, charcount);
#else
written = _write(fh, &ch, charcount);
#endif
#else /* _UNICODE */
{
char mbc[4];
*(wchar_t *)mbc = (wchar_t)(ch & 0xffff);
#ifdef _POSIX_
written = write(fh, mbc, charcount);
#else
written = _write(fh, mbc, charcount);
#endif
}
#endif /* _UNICODE */
}
/* See if the _write() was successful. */
if (written != charcount) {
stream->_flag |= _IOERR;
return(_TEOF);
}
#ifndef _UNICODE
return(ch & 0xff);
#else /* _UNICODE */
return(ch & 0xffff);
#endif /* _UNICODE */
#endif /* _NTSUBSET */
}
|