Обновление с Babel до версии 7, имеющей проблемы с browserify

Промывка для stdout определяется его буферизацией. Буферизация может быть настроена на три режима: _IOFBF (полная буферизация: ждет, когда возможно fflush()), _IOLBF (буферизация строк: триггеры новой строки запускают автоматический сброс) и _IONBF (всегда используется прямая запись). «Поддержка этих характеристик определяется реализацией и может быть затронута функциями setbuf() и setvbuf()». [C99: 7.19.3.3]

«При запуске программы три текстовых потока предварительно заданы и их явно не нужно открывать - стандартный ввод (для чтения обычного ввода), стандартный вывод (для записи обычного вывода) и стандартная ошибка (для записи диагностического вывода). Как первоначально было открыто, стандартный поток ошибок не полностью буферизирован, стандартные входные и стандартные выходные потоки полностью буферизованы тогда и только тогда, когда можно определить поток, чтобы не ссылаться на интерактивное устройство ». [C99: 7.19.3.7]

Объяснение наблюдаемого поведения

Итак, происходит то, что реализация делает что-то специфичное для платформы, чтобы решить, будет ли stdout буферизация. В большинстве реализаций libc этот тест выполняется при первом использовании потока.

  1. Поведение # 1 легко объясняется: когда поток предназначен для интерактивного устройства, он буферизируется по строке, а printf() автоматически сбрасывается.
  2. Ожидается также случай # 2: при перенаправлении в файл поток полностью буферизируется и не будет очищаться, кроме как с помощью fflush(), если вы не напишите gobloads of данные к нему.
  3. Наконец, мы понимаем случай # 3 тоже для реализаций, которые выполняют только проверку на базовом fd один раз. Поскольку мы принудительно инициализировали буфер stdout в первом printf(), stdout получил режим буферизации строк. Когда мы поменяем файл fd на файл, он по-прежнему буферизируется, поэтому данные автоматически сбрасываются.

Некоторые фактические реализации

Каждый libc имеет широту в как он интерпретирует эти требования, поскольку C99 не указывает, что такое «интерактивное устройство», а также запись stdio в POSIX расширяется (за исключением того, что stderr будет открыт для чтения).

  1. Glibc. См. filedoalloc.c: L111 . Здесь мы используем stat() для проверки, является ли fd tty, и соответственно настройте режим буферизации. (Это вызвано из fileops.c.) stdout изначально имеет нулевой буфер и выделяется при первом использовании потока на основе характеристик fd 1.
  2. BSD libc. Очень похожий, но гораздо более чистый код для подражания! См. эту строку в makebuf.c

0
задан Chris Morris 18 January 2019 в 10:10
поделиться