void _IO_doallocbuf (_IO_FILE *fp) { if (fp->_IO_buf_base) return; if (!(fp->_flags & _IO_UNBUFFERED) || fp->_mode > 0) if (_IO_DOALLOCATE (fp) != EOF) return; _IO_setb (fp, fp->_shortbuf, fp->_shortbuf+1, 0); }
int _IO_setvbuf (_IO_FILE *fp, char *buf, int mode, _IO_size_t size) { int result; CHECK_FILE (fp, EOF); _IO_acquire_lock (fp); switch (mode) { case _IOFBF: fp->_IO_file_flags &= ~(_IO_LINE_BUF|_IO_UNBUFFERED); if (buf == NULL) { if (fp->_IO_buf_base == NULL) { /* There is no flag to distinguish between "fully buffered mode has been explicitly set" as opposed to "line buffering has not been explicitly set". In both cases, _IO_LINE_BUF is off. If this is a tty, and _IO_filedoalloc later gets called, it cannot know if it should set the _IO_LINE_BUF flag (because that is the default), or not (because we have explicitly asked for fully buffered mode). So we make sure a buffer gets allocated now, and explicitly turn off line buffering. A possibly cleaner alternative would be to add an extra flag, but then flags are a finite resource. */ if (_IO_DOALLOCATE (fp) < 0) { result = EOF; goto unlock_return; } fp->_IO_file_flags &= ~_IO_LINE_BUF; } result = 0; goto unlock_return; } break; case _IOLBF: fp->_IO_file_flags &= ~_IO_UNBUFFERED; fp->_IO_file_flags |= _IO_LINE_BUF; if (buf == NULL) { result = 0; goto unlock_return; } break; case _IONBF: fp->_IO_file_flags &= ~_IO_LINE_BUF; fp->_IO_file_flags |= _IO_UNBUFFERED; buf = NULL; size = 0; break; default: result = EOF; goto unlock_return; } result = _IO_SETBUF (fp, buf, size) == NULL ? EOF : 0; unlock_return: _IO_release_lock (fp); return result; }