Промывка для stdout
определяется его буферизацией. Буферизация может быть настроена на три режима: _IOFBF
(полная буферизация: ждет, когда возможно fflush()
), _IOLBF
(буферизация строк: триггеры новой строки запускают автоматический сброс) и _IONBF
(всегда используется прямая запись). «Поддержка этих характеристик определяется реализацией и может быть затронута функциями setbuf()
и setvbuf()
». [C99: 7.19.3.3]
«При запуске программы три текстовых потока предварительно заданы и их явно не нужно открывать - стандартный ввод (для чтения обычного ввода), стандартный вывод (для записи обычного вывода) и стандартная ошибка (для записи диагностического вывода). Как первоначально было открыто, стандартный поток ошибок не полностью буферизирован, стандартные входные и стандартные выходные потоки полностью буферизованы тогда и только тогда, когда можно определить поток, чтобы не ссылаться на интерактивное устройство ». [C99: 7.19.3.7]
Итак, происходит то, что реализация делает что-то специфичное для платформы, чтобы решить, будет ли stdout
буферизация. В большинстве реализаций libc этот тест выполняется при первом использовании потока.
printf()
автоматически сбрасывается. fflush()
, если вы не напишите gobloads of данные к нему. printf()
, stdout получил режим буферизации строк. Когда мы поменяем файл fd на файл, он по-прежнему буферизируется, поэтому данные автоматически сбрасываются. Каждый libc имеет широту в как он интерпретирует эти требования, поскольку C99 не указывает, что такое «интерактивное устройство», а также запись stdio в POSIX расширяется (за исключением того, что stderr будет открыт для чтения).
stat()
для проверки, является ли fd tty, и соответственно настройте режим буферизации. (Это вызвано из fileops.c.) stdout
изначально имеет нулевой буфер и выделяется при первом использовании потока на основе характеристик fd 1.