int filbuf(FILE *stream) { if (stream->flag & _IOSTR) return EOF; if (stream->flag & _IOWR) { stream->flag |= _IOERR; return EOF; } stream->flag |= _IORD; // Get a buffer, if necessary. if (!anybuf(stream)) { getbuf(stream); } else { stream->ptr = stream->base; } stream->cnt = read(fileno(stream), stream->base, stream->bufsiz); if (stream->cnt <= 0) { stream->flag |= stream->cnt ? _IOERR : _IOEOF; stream->cnt = 0; return EOF; } stream->cnt--; return *stream->ptr++ & 0xff; }
int __cdecl _filwbuf ( FILE *str ) { REG1 FILE *stream; _ASSERTE(str != NULL); /* Init pointer to _iob2 entry. */ stream = str; if (!inuse(stream) || stream->_flag & _IOSTRG) return(WEOF); if (stream->_flag & _IOWRT) { stream->_flag |= _IOERR; return(WEOF); } stream->_flag |= _IOREAD; /* Get a buffer, if necessary. */ if (!anybuf(stream)) _getbuf(stream); else stream->_ptr = stream->_base; stream->_cnt = _read(_fileno(stream), stream->_base, stream->_bufsiz); if ((stream->_cnt == 0) || (stream->_cnt == 1) || stream->_cnt == -1) { stream->_flag |= stream->_cnt ? _IOERR : _IOEOF; stream->_cnt = 0; return(WEOF); } if ( !(stream->_flag & (_IOWRT|_IORW)) && ((_osfile_safe(_fileno(stream)) & (FTEXT|FEOFLAG)) == (FTEXT|FEOFLAG)) ) stream->_flag |= _IOCTRLZ; /* Check for small _bufsiz (_SMALL_BUFSIZ). If it is small and if it is our buffer, then this must be the first _filbuf after an fseek on a read-access-only stream. Restore _bufsiz to its larger value (_INTERNAL_BUFSIZ) so that the next _filbuf call, if one is made, will fill the whole buffer. */ if ( (stream->_bufsiz == _SMALL_BUFSIZ) && (stream->_flag & _IOMYBUF) && !(stream->_flag & _IOSETVBUF) ) { stream->_bufsiz = _INTERNAL_BUFSIZ; } stream->_cnt -= sizeof(wchar_t); return (0xffff & *((wchar_t *)(stream->_ptr))++); }
int __cdecl _stbuf ( FILE *str ) { FILE *stream; int index; _ASSERTE(str != NULL); /* Init near stream pointer */ stream = str; /* do nothing if not a tty device */ if (!_isatty(_fileno(stream))) 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); #ifndef CRTDLL /* force library pre-termination procedure */ _cflush++; #endif /* CRTDLL */ /* 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) && ((_stdbuf[index]=_malloc_crt(_INTERNAL_BUFSIZ)) == NULL) ) { /* Cannot allocate buffer. Use _charbuf this time */ stream->_ptr = stream->_base = (void *)&(stream->_charbuf); stream->_cnt = stream->_bufsiz = 2; } else { /* Set up the buffer */ stream->_ptr = stream->_base = _stdbuf[index]; stream->_cnt = stream->_bufsiz = _INTERNAL_BUFSIZ; } stream->_flag |= (_IOWRT | _IOYOURBUF | _IOFLRTN); return(1); }
int __cdecl _stbuf ( FILE *str ) { REG1 FILE *stream; int index; _ASSERTE(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); #ifndef CRTDLL /* force library pre-termination procedure */ _cflush++; #endif /* CRTDLL */ /* 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) #ifdef _WIN32 if ( (_stdbuf[index]=_malloc_crt(_INTERNAL_BUFSIZ)) == NULL ) #else #if defined(_M_MPPC) || defined(_M_M68K) if ( (_stdbuf[index]=_malloc_crt(BUFSIZ)) == NULL ) #endif #endif return(0); /* error */ /* Set up the buffer */ stream->_ptr = stream->_base = _stdbuf[index]; #ifdef _WIN32 stream->_cnt = stream->_bufsiz = _INTERNAL_BUFSIZ; #else #if defined(_M_MPPC) || defined(_M_M68K) stream->_cnt = stream->_bufsiz = BUFSIZ; #endif #endif stream->_flag |= (_IOWRT | _IOYOURBUF | _IOFLRTN); return(1); }
size_t fwrite(const void *buffer, size_t size, size_t num, FILE *stream) { const char *data; // Point to where data comes from next unsigned total; // Total bytes to write unsigned count; // Num bytes left to write unsigned bufsize; // Size of stream buffer unsigned nbytes; // Number of bytes to write now unsigned nwritten; // Number of bytes written int c; // A temp char // Initialize local vars data = buffer; count = total = size * num; if (count == 0) return 0; if (anybuf(stream)) { // Already has buffer, use its size bufsize = stream->bufsiz; } else { // Assume will get BUFSIZ buffer bufsize = BUFSIZ; } // Here is the main loop -- we go through here until we're done while (count != 0) { // If the buffer is big and has room, copy data to buffer if (bigbuf(stream) && stream->cnt != 0) { // How much do we want? nbytes = (count < (unsigned) stream->cnt) ? count : stream->cnt; memcpy(stream->ptr, data, nbytes); // Update stream and amount of data written count -= nbytes; stream->cnt -= nbytes; stream->ptr += nbytes; data += nbytes; } else if (count >= bufsize) { // If we have more than bufsize chars to write, write // data by calling write with an integral number of // bufsiz blocks. If we reach here and we have a big // buffer, it must be full so flush it. if (bigbuf(stream)) { if (fflush(stream)) { // Error, stream flags set -- we're out of here return (total - count) / size; } } // Calc chars to write -- (count / bufsize) * bufsize nbytes = bufsize ? (count - count % bufsize) : count; if (stream->flag & _IOCRLF) { nwritten = write_translated(fileno(stream), (char *) data, nbytes); } else { nwritten = write(fileno(stream), data, nbytes); } if ((int) nwritten < 0) { // Error -- out of here stream->flag |= _IOERR; return (total - count) / size; } // Update count and data to reflect write count -= nwritten; data += nwritten; if (nwritten < nbytes) { // Error -- out of here stream->flag |= _IOERR; return (total - count) / size; } } else { // Buffer full and not enough chars to do direct write, so do a flsbuf. c = *data; if (flsbuf(c, stream) == EOF) { // Error or eof, stream flags set by _flsbuf return (total - count) / size; } // flsbuf wrote a char -- update count ++data; --count; // Update buffer size bufsize = stream->bufsiz > 0 ? stream->bufsiz : 1; } } // We finished successfully, so just return num return num; }
size_t fread(void *buffer, size_t size, size_t num, FILE *stream) { char *data; // Point to where should be read next unsigned total; // Total bytes to read unsigned count; // Num bytes left to read unsigned bufsize; // Size of stream buffer unsigned nbytes; // How much to read now unsigned nread; // How much we did read int c; // A temp char // Initialize local vars data = buffer; if ((count = total = size * num) == 0) return 0; if (anybuf(stream)) { // Already has buffer, use its size bufsize = stream->bufsiz; } else { // Assume will get BUFSIZ buffer bufsize = BUFSIZ; } // Here is the main loop -- we go through here until we're done while (count != 0) { // if the buffer exists and has characters, copy them to user buffer if (anybuf(stream) && stream->cnt != 0) { // How much do we want? nbytes = (count < (unsigned) stream->cnt) ? count : stream->cnt; memcpy(data, stream->ptr, nbytes); // Update stream and amount of data read count -= nbytes; stream->cnt -= nbytes; stream->ptr += nbytes; data += nbytes; } else if (count >= bufsize) { // If we have more than bufsize chars to read, get data // by calling read with an integral number of bufsiz // blocks. // Calc chars to read -- (count / bufsize) * bufsize nbytes = bufsize ? count - count % bufsize : count; nread = read(fileno(stream), data, nbytes); if (nread == 0) { // End of file -- out of here stream->flag |= _IOEOF; return (total - count) / size; } else if ((int) nread < 0) { // Error -- out of here stream->flag |= _IOERR; return (total - count) / size; } // Update count and data to reflect read count -= nread; data += nread; } else { // Less than bufsize chars to read, so call filbuf to fill buffer if ((c = filbuf(stream)) == EOF) { // Error or eof, stream flags set by filbuf return (total - count) / size; } // filbuf returned a char -- store it *data++ = (char) c; count--; // Update buffer size bufsize = stream->bufsiz; } } // We finished successfully, so just return num return num; }
int flsbuf(int ch, FILE *stream) { int count; int written; int fh; char chbuf; fh = fileno(stream); if (!(stream->flag & (_IOWR | _IORW)) || (stream->flag & _IOSTR)) { stream->flag |= _IOERR; return -1; } if (stream->flag & _IORD) { stream->cnt = 0; if (stream->flag & _IOEOF) { stream->ptr = stream->base; stream->flag &= ~_IORD; } else { stream->flag |= _IOERR; return -1; } } stream->flag |= _IOWR; stream->flag &= ~_IOEOF; written = count = stream->cnt = 0; // Get a buffer for this stream, if necessary if (!anybuf(stream)) getbuf(stream); // If big buffer is assigned to stream if (bigbuf(stream)) { count = stream->ptr - stream->base; stream->ptr = stream->base + 1; stream->cnt = stream->bufsiz - 1; if (count > 0) { if (stream->flag & _IOCRLF) { written = write_translated(fh, stream->base, count); } else { written = write(fh, stream->base, count); } } *stream->base = (char) ch; } else { // Perform single character output (either _IONBF or no buffering) count = 1; chbuf = (char) ch; if (stream->flag & _IOCRLF) { written = write_translated(fh, &chbuf, count); } else { written = write(fh, &chbuf, count); } } // See if the write was successful. if (written != count) { stream->flag |= _IOERR; return -1; } return ch & 0xff; }
/* define the normal version */ size_t __cdecl _fread_nolock_s( void *buffer, size_t bufferSize, size_t elementSize, size_t num, FILE *stream ) { char *data; /* point inside the destination buffer to where we need to copy the read chars */ size_t dataSize; /* space left in the destionation buffer (in bytes) */ size_t total; /* total bytes to read */ size_t count; /* num bytes left to read */ unsigned streambufsize; /* size of stream buffer */ unsigned nbytes; /* how much to read now */ unsigned nread; /* how much we did read */ int c; /* a temp char */ /* initialize local vars */ data = buffer; dataSize = bufferSize; if (elementSize == 0 || num == 0) { return 0; } count = total = elementSize * num; if (anybuf(stream)) { /* already has buffer, use its size */ streambufsize = stream->_bufsiz; } else { /* assume will get _INTERNAL_BUFSIZ buffer */ streambufsize = _INTERNAL_BUFSIZ; } /* here is the main loop -- we go through here until we're done */ while (count != 0) { /* if the buffer exists and has characters, copy them to user buffer */ if (anybuf(stream) && stream->_cnt != 0) { if(stream->_cnt < 0) { _ASSERTE(("Inconsistent Stream Count. Flush between consecutive read and write", stream->_cnt >= 0)); stream->_flag |= _IOERR; return (total - count) / elementSize; } /* how much do we want? */ nbytes = (count < (size_t)stream->_cnt) ? (unsigned)count : stream->_cnt; if (nbytes > dataSize) { if (bufferSize != SIZE_MAX) { memset(buffer, _BUFFER_FILL_PATTERN, bufferSize); } _VALIDATE_RETURN(("buffer too small", 0), ERANGE, 0) } memcpy_s(data, dataSize, stream->_ptr, nbytes); /* update stream and amt of data read */ count -= nbytes; stream->_cnt -= nbytes; stream->_ptr += nbytes; data += nbytes; dataSize -= nbytes; } else if (count >= streambufsize) { /* If we have more than streambufsize chars to read, get data by calling read with an integral number of bufsiz blocks. Note that if the stream is text mode, read will return less chars than we ordered. */ /* calc chars to read -- (count/streambufsize) * streambufsize */ nbytes = ( streambufsize ? (unsigned)(count - count % streambufsize) : (unsigned)count ); if (nbytes > dataSize) { if (bufferSize != SIZE_MAX) { memset(buffer, _BUFFER_FILL_PATTERN, bufferSize); } _VALIDATE_RETURN(("buffer too small", 0), ERANGE, 0) } nread = _read(_fileno(stream), data, nbytes); if (nread == 0) { /* end of file -- out of here */ stream->_flag |= _IOEOF; return (total - count) / elementSize; } else if (nread == (unsigned)-1) { /* error -- out of here */ stream->_flag |= _IOERR; return (total - count) / elementSize; } /* update count and data to reflect read */ count -= nread; data += nread; dataSize -= nread; }
int __cdecl _filwbuf ( FILE *str ) #endif /* _UNICODE */ { REG1 FILE *stream=NULL; /* In safecrt, we assume we always have a buffer */ _VALIDATE_RETURN(str != NULL, EINVAL, _TEOF); /* Init pointer to _iob2 entry. */ stream = str; if (!inuse(stream) || stream->_flag & _IOSTRG) return(_TEOF); if (stream->_flag & _IOWRT) { stream->_flag |= _IOERR; return(_TEOF); } stream->_flag |= _IOREAD; /* Get a buffer, if necessary. */ if (!anybuf(stream)) { #ifndef _SAFECRT_IMPL _getbuf(stream); #else /* _SAFECRT_IMPL */ /* In safecrt, we assume we always have a buffer */ _VALIDATE_RETURN(FALSE, EINVAL, _TEOF); #endif /* _SAFECRT_IMPL */ } else { stream->_ptr = stream->_base; } stream->_cnt = _read(_fileno(stream), stream->_base, stream->_bufsiz); #ifndef _UNICODE if ((stream->_cnt == 0) || (stream->_cnt == -1)) { #else /* _UNICODE */ if ((stream->_cnt == 0) || (stream->_cnt == 1) || stream->_cnt == -1) { #endif /* _UNICODE */ stream->_flag |= stream->_cnt ? _IOERR : _IOEOF; stream->_cnt = 0; return(_TEOF); } if ( !(stream->_flag & (_IOWRT|_IORW)) && ((_osfile_safe(_fileno(stream)) & (FTEXT|FEOFLAG)) == (FTEXT|FEOFLAG)) ) stream->_flag |= _IOCTRLZ; /* Check for small _bufsiz (_SMALL_BUFSIZ). If it is small and if it is our buffer, then this must be the first _filbuf after an fseek on a read-access-only stream. Restore _bufsiz to its larger value (_INTERNAL_BUFSIZ) so that the next _filbuf call, if one is made, will fill the whole buffer. */ if ( (stream->_bufsiz == _SMALL_BUFSIZ) && (stream->_flag & _IOMYBUF) && !(stream->_flag & _IOSETVBUF) ) { stream->_bufsiz = _INTERNAL_BUFSIZ; } #ifndef _UNICODE stream->_cnt--; return(0xff & *stream->_ptr++); #else /* _UNICODE */ stream->_cnt -= sizeof(wchar_t); return (0xffff & *((wchar_t *)(stream->_ptr))++); #endif /* _UNICODE */ }
int __cdecl _flswbuf ( int ch, FILE *str ) #endif /* _UNICODE */ { REG1 FILE *stream; REG2 int charcount; REG3 int written; int fh; _ASSERTE(str != NULL); /* Init file handle and pointers */ stream = str; fh = _fileno(stream); if (!(stream->_flag & (_IOWRT|_IORW))) { errno = EBADF; stream->_flag |= _IOERR; return(_TEOF); } else if ((stream->_flag & _IOSTRG)) { errno = ERANGE; 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)) && (_isatty(fh)) )) _getbuf(stream); } /* end !anybuf() */ /* If big buffer is assigned to stream... */ if (bigbuf(stream)) { _ASSERTE(("inconsistent IOB fields", stream->_ptr - stream->_base >= 0)); charcount = (int)(stream->_ptr - stream->_base); stream->_ptr = stream->_base + sizeof(TCHAR); stream->_cnt = stream->_bufsiz - (int)sizeof(TCHAR); if (charcount > 0) written = _write(fh, stream->_base, charcount); else if (_osfile_safe(fh) & FAPPEND) { if( _lseeki64(fh,0L,SEEK_END)==-1) { stream->_flag |= _IOERR; return(_TEOF); } } #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 written = _write(fh, &ch, charcount); #else /* _UNICODE */ { char mbc[4]; *(wchar_t *)mbc = (wchar_t)(ch & 0xffff); written = _write(fh, mbc, charcount); } #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 */ }
int __cdecl _filwbuf ( FILE *str ) #endif /* _UNICODE */ { #ifdef _NTSUBSET_ return(_TEOF); #else /* ndef _NTSUBSET_ */ REG1 FILE *stream; _ASSERTE(str != NULL); /* Init pointer to _iob2 entry. */ stream = str; if (!inuse(stream) || stream->_flag & _IOSTRG) return(_TEOF); if (stream->_flag & _IOWRT) { #ifdef _POSIX_ errno = EBADF; #endif stream->_flag |= _IOERR; return(_TEOF); } stream->_flag |= _IOREAD; /* Get a buffer, if necessary. */ if (!anybuf(stream)) _getbuf(stream); else stream->_ptr = stream->_base; #ifdef _POSIX_ stream->_cnt = read(fileno(stream), stream->_base, stream->_bufsiz); #else stream->_cnt = _read(_fileno(stream), stream->_base, stream->_bufsiz); #endif #ifndef _UNICODE if ((stream->_cnt == 0) || (stream->_cnt == -1)) { #else /* _UNICODE */ if ((stream->_cnt == 0) || (stream->_cnt == 1) || stream->_cnt == -1) { #endif /* _UNICODE */ stream->_flag |= stream->_cnt ? _IOERR : _IOEOF; stream->_cnt = 0; return(_TEOF); } #ifndef _POSIX_ if ( !(stream->_flag & (_IOWRT|_IORW)) && ((_osfile_safe(_fileno(stream)) & (FTEXT|FEOFLAG)) == (FTEXT|FEOFLAG)) ) stream->_flag |= _IOCTRLZ; #endif /* Check for small _bufsiz (_SMALL_BUFSIZ). If it is small and if it is our buffer, then this must be the first _filbuf after an fseek on a read-access-only stream. Restore _bufsiz to its larger value (_INTERNAL_BUFSIZ) so that the next _filbuf call, if one is made, will fill the whole buffer. */ if ( (stream->_bufsiz == _SMALL_BUFSIZ) && (stream->_flag & _IOMYBUF) && !(stream->_flag & _IOSETVBUF) ) { stream->_bufsiz = _INTERNAL_BUFSIZ; } #ifndef _UNICODE stream->_cnt--; return(0xff & *stream->_ptr++); #else /* _UNICODE */ stream->_cnt -= sizeof(wchar_t); return (0xffff & *((wchar_t *)(stream->_ptr))++); #endif /* _UNICODE */ #endif /* _NTSUBSET_ */ } #else /* ndef _WIN32 */ #if defined(_M_MPPC) || defined(_M_M68K) #include <cruntime.h> #include <stdio.h> #include <file2.h> #include <io.h> #include <dbgint.h> #include <malloc.h> #include <internal.h> #include <msdos.h> /*** *int _filbuf(stream) - fill buffer and get first character * *Purpose: * get a buffer if the file doesn't have one, read into it, return first * char. try to get a buffer, if a user buffer is not assigned. called * only from getc; intended for use only within library. assume no input * stream is to remain unbuffered when memory is available unless it is * marked _IONBF. at worst, give it a single char buffer. the need for a * buffer, no matter how small, becomes evident when we consider the * ungetc's necessary in scanf * *Entry: * FILE *stream - stream to read from * *Exit: * returns first character from buffer (next character to be read) * returns EOF if the FILE is actually a string, or not open for reading, * or if open for writing or if no more chars to read. * all fields in FILE structure may be changed except _file. * *Exceptions: * *******************************************************************************/ int __cdecl _filbuf ( FILE *str ) { REG1 FILE *stream; _ASSERTE(str != NULL); /* Init pointer to _iob2 entry. */ stream = str; if (!inuse(stream) || stream->_flag & _IOSTRG) return(EOF); if (stream->_flag & _IOWRT) { stream->_flag |= _IOERR; return(EOF); } stream->_flag |= _IOREAD; /* Get a buffer, if necessary. */ if (!anybuf(stream)) _getbuf(stream); else stream->_ptr = stream->_base; stream->_cnt = _read(_fileno(stream), stream->_base, stream->_bufsiz); if ((stream->_cnt == 0) || (stream->_cnt == -1)) { stream->_flag |= stream->_cnt ? _IOERR : _IOEOF; stream->_cnt = 0; return(EOF); } if ( !(stream->_flag & (_IOWRT|_IORW)) && ((_osfile[_fileno(stream)] & (FTEXT|FEOFLAG)) == (FTEXT|FEOFLAG)) ) stream->_flag |= _IOCTRLZ; stream->_cnt--; return(0xff & *stream->_ptr++); }
/* define the normal version */ #ifdef _MT size_t __cdecl _fwrite_lk ( #else /* _MT */ size_t __cdecl fwrite ( #endif /* _MT */ const void *buffer, size_t size, size_t num, FILE *stream ) { const char *data; /* point to where data comes from next */ unsigned total; /* total bytes to write */ unsigned count; /* num bytes left to write */ unsigned bufsize; /* size of stream buffer */ unsigned nbytes; /* number of bytes to write now */ unsigned nwritten; /* number of bytes written */ int c; /* a temp char */ /* initialize local vars */ data = buffer; count = total = size * num; if (0 == count) return 0; if (anybuf(stream)) /* already has buffer, use its size */ bufsize = stream->_bufsiz; else #if defined (_M_M68K) || defined (_M_MPPC) /* assume will get BUFSIZ buffer */ bufsize = BUFSIZ; #else /* defined (_M_M68K) || defined (_M_MPPC) */ /* assume will get _INTERNAL_BUFSIZ buffer */ bufsize = _INTERNAL_BUFSIZ; #endif /* defined (_M_M68K) || defined (_M_MPPC) */ /* here is the main loop -- we go through here until we're done */ while (count != 0) { /* if the buffer is big and has room, copy data to buffer */ if (bigbuf(stream) && stream->_cnt != 0) { /* how much do we want? */ nbytes = (count < (unsigned)stream->_cnt) ? count : stream->_cnt; memcpy(stream->_ptr, data, nbytes); /* update stream and amt of data written */ count -= nbytes; stream->_cnt -= nbytes; stream->_ptr += nbytes; data += nbytes; } else if (count >= bufsize) { /* If we have more than bufsize chars to write, write data by calling write with an integral number of bufsiz blocks. If we reach here and we have a big buffer, it must be full so _flush it. */ if (bigbuf(stream)) { if (_flush(stream)) { /* error, stream flags set -- we're out of here */ return (total - count) / size; } } /* calc chars to read -- (count/bufsize) * bufsize */ nbytes = ( bufsize ? (count - count % bufsize) : count ); nwritten = _write(_fileno(stream), data, nbytes); if (nwritten == (unsigned)EOF) { /* error -- out of here */ stream->_flag |= _IOERR; return (total - count) / size; } /* update count and data to reflect write */ count -= nwritten; data += nwritten; if (nwritten < nbytes) { /* error -- out of here */ stream->_flag |= _IOERR; return (total - count) / size; } } else { /* buffer full and not enough chars to do direct write, so do a _flsbuf. */ c = *data; /* _flsbuf write one char, this is it */ if (_flsbuf(c, stream) == EOF) { /* error or eof, stream flags set by _flsbuf */ return (total - count) / size; } /* _flsbuf wrote a char -- update count */ ++data; --count; /* update buffer size */ bufsize = stream->_bufsiz > 0 ? stream->_bufsiz : 1; } } /* we finished successfully, so just return num */ return num; }