Ejemplo n.º 1
0
extern "C" wint_t __cdecl _ungetwc_nolock(wint_t const c, FILE* const public_stream)
{
    __crt_stdio_stream const stream(public_stream);

    // Ungetting WEOF is expressly forbidden:
    if (c == WEOF)
        return WEOF;

    // To unget, the stream must currently be in read mode, _or_ it must be open
    // for update (read and write) and must not _currently_ be in write mode:
    bool const is_in_read_mode   = stream.has_all_of(_IOREAD);
    bool const is_in_update_mode = stream.has_all_of(_IOUPDATE);
    bool const is_in_write_mode  = stream.has_all_of(_IOWRITE);

    if (!is_in_read_mode && !(is_in_update_mode && !is_in_write_mode))
        return WEOF;

    // If the stream is currently unbuffered, buffer it:
    if (stream->_base == nullptr)
        __acrt_stdio_allocate_buffer_nolock(stream.public_stream());

    // If the stream is file-backed and is open in text mode, we need to perform
    // text mode translations:
    if (!stream.is_string_backed() && (_osfile_safe(_fileno(stream.public_stream())) & FTEXT) != 0)
    {
        return ungetwc_text_mode_nolock(c, stream);
    }

    // Otherwise, the stream is string-backed or is a file-backed file open in
    // binary mode; we can simply push the character back into the stream:
    return ungetwc_binary_mode_nolock(c, stream);
}
Ejemplo n.º 2
0
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))++);

}
Ejemplo n.º 3
0
static int __cdecl common_refill_and_read_nolock(__crt_stdio_stream const stream) throw()
{
    typedef __acrt_stdio_char_traits<Character> stdio_traits;

    _VALIDATE_RETURN(stream.valid(), EINVAL, stdio_traits::eof);

    if (!stream.is_in_use() || stream.is_string_backed())
        return stdio_traits::eof;

    if (stream.has_all_of(_IOWRITE))
    {
        stream.set_flags(_IOERROR);
        return stdio_traits::eof;
    }

    stream.set_flags(_IOREAD);

    // Get a buffer, if necessary:
    if (!stream.has_any_buffer())
        __acrt_stdio_allocate_buffer_nolock(stream.public_stream());

    auto const context = get_context_nolock(stream, Character());

    stream->_ptr = stream->_base;
    stream->_cnt = _read(_fileno(stream.public_stream()), stream->_base, stream->_bufsiz);

    if (!is_buffer_valid_nolock(stream, Character()))
    {
        stream.set_flags(stream->_cnt != 0 ? _IOERROR : _IOEOF);
        stream->_cnt = 0;
        return stdio_traits::eof;
    }

    if (!stream.has_any_of(_IOWRITE | _IOUPDATE) &&
        ((_osfile_safe(_fileno(stream.public_stream())) & (FTEXT | FEOFLAG)) == (FTEXT | FEOFLAG)))
    {
        stream.set_flags(_IOCTRLZ);
    }

    // Check for small _bufsiz (_SMALL_BUFSIZ). If it is small and if it is our
    // buffer, then this must be the first call to this function after an fseek
    // on a read-access-only stream. Restore _bufsiz to its larger value
    // (_INTERNAL_BUFSIZ) so that the next call to this function, if one is made,
    // will fill the whole buffer.
    if (stream->_bufsiz == _SMALL_BUFSIZ &&
        stream.has_crt_buffer() &&
        !stream.has_all_of(_IOBUFFER_SETVBUF))
    {
        stream->_bufsiz = _INTERNAL_BUFSIZ;
    }

    return read_character_nolock(stream, context, Character());
}
Ejemplo n.º 4
0
void __cdecl rewind (
        FILE *str
        )
{
        REG1 FILE *stream;
        REG2 int fd;

        _VALIDATE_RETURN_VOID( (str != NULL), EINVAL);

        /* Init stream pointer */
        stream = str;

        fd = _fileno(stream);

        /* Lock the file */
        _lock_str(stream);
        __try {

        /* Flush the stream */
        _flush(stream);

        /* Clear errors */
        stream->_flag &= ~(_IOERR|_IOEOF);
        _osfile_safe(fd) &= ~(FEOFLAG);

        /* Set flags */
        /* [note: _flush set _cnt=0 and _ptr=_base] */
        if (stream->_flag & _IORW)
            stream->_flag &= ~(_IOREAD|_IOWRT);

        /* Position to beginning of file */
        if(_lseek(fd,0L,0)==-1)
                {
                        stream->_flag |= _IOERR;
                }

        }
        __finally {
            /* unlock stream */
            _unlock_str(stream);
        }

}
Ejemplo n.º 5
0
wint_t __cdecl fputwc (
        wint_t ch,
        FILE *str
        )
{

#endif  /* _MT */

        if (!(str->_flag & _IOSTRG) && (_osfile_safe(_fileno(str)) & FTEXT))
        {
                int size;
                char mbc[4];

                /* text (multi-byte) mode */
                if ((size = wctomb(mbc, ch)) == -1)
                {
                        /*
                         * Conversion failed! Set errno and return
                         * failure.
                         */
                        errno = EILSEQ;
                        return WEOF;
                }
                else if ( size == 1 )
                {
                        if ( _putc_lk(mbc[0], str) == EOF )
                                return WEOF;
                        return (wint_t)(0xffff & ch);
                }
                else { /* size == 2 */
                        if ( (_putc_lk(mbc[0], str) == EOF) ||
                             (_putc_lk(mbc[1], str) == EOF) )
                                return WEOF;
                        return (wint_t)(0xffff & ch);
                }
        }
        /* binary (Unicode) mode */
        if ( (str->_cnt -= sizeof(wchar_t)) >= 0 )
                return (wint_t) (0xffff & (*((wchar_t *)(str->_ptr))++ = (wchar_t)ch));
        else
                return (wint_t) _flswbuf(ch, str);
}
void __cdecl clearerr (
        FILE *stream
        )
{
        _ASSERTE(stream != NULL);

        _lock_str(stream);

        /* Clear stdio level flags */
        stream->_flag &= ~(_IOERR|_IOEOF);

        /* Clear lowio level flags */

#ifdef _WIN32

        _osfile_safe(_fileno(stream)) &= ~(FEOFLAG);

#else  /* _WIN32 */
        _osfile[_fileno(stream)] &= ~(FEOFLAG);
#endif  /* _WIN32 */

        _unlock_str(stream);
}
Ejemplo n.º 7
0
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 */

}
Ejemplo n.º 8
0
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 */

}
wint_t __cdecl ungetwc (
        wint_t ch,
        FILE *str
        )
{

#endif  /* _MT */

        _ASSERTE(str != NULL);

        /*
         * Requirements for success:
         *
         * 1. Character to be pushed back on the stream must not be WEOF.
         *
         * 2. The stream must currently be in read mode, or must be open for
         *    update (i.e., read/write) and must NOT currently be in write
         *    mode.
         */
        if ( (ch != WEOF) &&
             ( (str->_flag & _IOREAD) || ((str->_flag & _IORW) &&
                !(str->_flag & _IOWRT))
             )
           )
        {
                /* If stream is unbuffered, get one. */
                if (str->_base == NULL)
                        _getbuf(str);

            if (!(str->_flag & _IOSTRG) && (_osfile_safe(_fileno(str)) &
                  FTEXT))
                {
                        /*
                         * Text mode, sigh... Convert the wc to a mbc.
                         */
                        int size;
                        char mbc[4];

                if ((size = wctomb(mbc, ch)) == -1)
                        {
                                /*
                                 * Conversion failed! Set errno and return
                                 * failure.
                                 */
                                errno = EILSEQ;
                                return WEOF;
                        }

                        /* we know _base != NULL; since file is buffered */
                        if (str->_ptr == str->_base)
                        {
                                if (str->_cnt)
                                /* my back is against the wall; i've already done
                                 * ungetwc, and there's no room for this one
                                 */
                                        return WEOF;
                                str->_ptr += size;
                        }

                        if ( size == 1 )
                        {
                                *--str->_ptr = mbc[0];
                        }
                        else /* size == 2 */
                        {
                                *--str->_ptr = mbc[1];
                                *--str->_ptr = mbc[0];
                        }

                        str->_cnt += size;

                        str->_flag &= ~_IOEOF;
                        str->_flag |= _IOREAD;  /* may already be set */
                        return (wint_t) (0x0ffff & ch);
                }
                /*
                 * Binary mode - push back the wide char.
                 */
                /* we know _base != NULL; since file is buffered */
                if (str->_ptr == str->_base)
                {
                        if (str->_cnt)
                                /* my back is against the wall; i've already done
                                 * ungetc, and there's no room for this one
                                 */
                                return WEOF;
                        str->_ptr += sizeof(wchar_t);
                }

                str->_cnt += sizeof(wchar_t);

                str->_flag &= ~_IOEOF;
                str->_flag |= _IOREAD;  /* may already be set */

                return (wint_t) (*--((wchar_t *)(str->_ptr)) = (wchar_t)(ch & 0xffff));

        }
        return WEOF;
}
Ejemplo n.º 10
0
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++);
}
Ejemplo n.º 11
0
extern "C" wint_t __cdecl _fgetwc_nolock(FILE* const public_stream)
{
    __crt_stdio_stream const stream(public_stream);

    // If the stream is backed by a real file and is open in a Unicode text mode,
    // we need to read two bytes (note that we read two bytes for both UTF-8 and
    // UTF-16 backed streams, since lowio translates UTF-8 to UTF-16 when we read.
    if (!stream.is_string_backed() &&
        _textmode_safe(_fileno(stream.public_stream())) != __crt_lowio_text_mode::ansi)
    {
        wchar_t wc;

        // Compose the wide character by reading byte-by-byte from the stream:
        char* const wc_first = reinterpret_cast<char*>(&wc);
        char* const wc_last  = wc_first + sizeof(wc);

        for (char* it = wc_first; it != wc_last; ++it)
        {
            int const c = _getc_nolock(stream.public_stream());
            if (c == EOF)
                return WEOF;

            *it = static_cast<char>(c);
        }

        return wc;
    }

    if (!stream.is_string_backed() &&
        (_osfile_safe(_fileno(stream.public_stream())) & FTEXT))
    {
        int size = 1;
        int ch;
        char mbc[4];
        wchar_t wch;

        /* text (multi-byte) mode */
        if ((ch = _getc_nolock(stream.public_stream())) == EOF)
            return WEOF;

        mbc[0] = static_cast<char>(ch);

        if (isleadbyte(static_cast<unsigned char>(mbc[0])))
        {
            if ((ch = _getc_nolock(stream.public_stream())) == EOF)
            {
                ungetc(mbc[0], stream.public_stream());
                return WEOF;
            }
            mbc[1] = static_cast<char>(ch);
            size = 2;
        }

        if (mbtowc(&wch, mbc, size) == -1)
        {
            // Conversion failed! Set errno and return failure:
            errno = EILSEQ;
            return WEOF;
        }

        return wch;
    }

    // binary (Unicode) mode
    if (stream->_cnt >= static_cast<int>(sizeof(wchar_t)))
    {
        stream->_cnt -= static_cast<int>(sizeof(wchar_t));
        return *reinterpret_cast<wchar_t*&>(stream->_ptr)++;
    }
    else
    {
        return static_cast<wint_t>(__acrt_stdio_refill_and_read_wide_nolock(stream.public_stream()));
    }
}