TEST(stdio_ext, _flushlbf) { FILE* fp = fopen("/dev/null", "w"); char buf[128]; ASSERT_EQ(0, setvbuf(fp, buf, _IOLBF, sizeof(buf))); ASSERT_EQ('a', fputc('a', fp)); ASSERT_EQ(1U, __fpending(fp)); _flushlbf(); ASSERT_EQ(0U, __fpending(fp)); fclose(fp); }
/* fill buffer, return first character or EOF */ int _filbuf(FILE *iop) { ssize_t res; size_t nbyte; Uchar *endbuf; #ifdef _LP64 unsigned int flag; #else unsigned char flag; #endif if (!(iop->_flag & _IOREAD)) /* check, correct permissions */ { if (iop->_flag & _IORW) iop->_flag |= _IOREAD; /* change direction */ /* to read - fseek */ else { errno = EBADF; return (EOF); } } if (iop->_base == 0) { if ((endbuf = _findbuf(iop)) == 0) /* get buffer and */ /* end_of_buffer */ return (EOF); } else endbuf = _bufend(iop); /* * Flush all line-buffered streams before we * read no-buffered or line-buffered input. */ if (iop->_flag & (_IONBF | _IOLBF)) _flushlbf(); /* * Changed the get family fns in Solaris 10 to comply with the * 1990 C Standard and standards based upon it. If the * end-of-file indicator for the stream is set, or if the stream * is at end-of-file, the function will return EOF, and the file * position indicator for the stream will not be advanced. * Additional bytes appended to the file do not clear the EOF * indicator. */ if ((flag = iop->_flag) & _IOEOF) { if (_xpg4_check()) { /* * A previous read() has returned 0 (below), * therefore iop->_cnt was set to 0, and the EOF * indicator was set before returning EOF. Reset * iop->_cnt to 0; it has likely been changed by * a function such as getc(). */ iop->_cnt = 0; return (EOF); } } /* * Fill buffer or read 1 byte for unbuffered, handling any errors. */ iop->_ptr = iop->_base; if (flag & _IONBF) nbyte = 1; else nbyte = endbuf - iop->_base; if ((res = read(GET_FD(iop), (char *)iop->_base, nbyte)) > 0) { iop->_cnt = res - 1; return (*iop->_ptr++); } iop->_cnt = 0; if (res == 0) iop->_flag |= _IOEOF; else if (!cancel_active()) iop->_flag |= _IOERR; return (EOF); }