static void _IO_unbuffer_all (void) { struct _IO_FILE *fp; for (fp = (_IO_FILE *) _IO_list_all; fp; fp = fp->_chain) { if (! (fp->_flags & _IO_UNBUFFERED) /* Iff stream is un-orientated, it wasn't used. */ && fp->_mode != 0) { #ifdef _IO_MTSAFE_IO int cnt; #define MAXTRIES 2 for (cnt = 0; cnt < MAXTRIES; ++cnt) if (fp->_lock == NULL || _IO_lock_trylock (*fp->_lock) == 0) break; else /* Give the other thread time to finish up its use of the stream. */ __sched_yield (); #endif if (! dealloc_buffers && !(fp->_flags & _IO_USER_BUF)) { fp->_flags |= _IO_USER_BUF; fp->_freeres_list = freeres_list; freeres_list = fp; fp->_freeres_buf = fp->_IO_buf_base; } _IO_SETBUF (fp, NULL, 0); if (fp->_mode > 0) _IO_wsetb (fp, NULL, NULL, 0); #ifdef _IO_MTSAFE_IO if (cnt < MAXTRIES && fp->_lock != NULL) _IO_lock_unlock (*fp->_lock); #endif } /* Make sure that never again the wide char functions can be used. */ fp->_mode = -1; } }
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; }