В обычных условиях любая программа в Unix имеет три потока, открытых для нее
при запуске: один для вывода, другой для ввода и один для вывода
диагностики или сообщений об ошибках.
Обычно они прикреплены к пользовательскому терминалу (см.
tty(4)),
но могут ссылаться и на другие файлы или устройства в зависимости от
того, что установлено родительским процессом (прочтите раздел
``Перенаправление ввода/вывода (Redirection)'' в
sh(1)).
Поток ввода называется ``стандартным вводом (standard input)''; поток вывода
называется ``стандартным выводом (standard output)''; а поток сообщений об ошибках
называется ``стандартными ошибками (standard error)''. Эти термины
были сокращены для названий файлов, на которые указывают ссылки, а именно:
stdinstdout
и
stderr
Каждый из этих терминов является макросом
stdio(3),
указывающим на FILE; возможно их использование с такими функциями, как
fprintf(3)
или
fread(3).
Переменные типа FILE являются буферизируемыми оболочками описателей
файлов Unix. Доступ к этим файлам можно осуществить также при помощи низкоуровнего
интерфейса для работы с файлами и с использованием таких функций, как
read(2)
и
lseek(2).
Целые описатели файлов, ассоциированных с потоками
stdinstdout
и
stderr
будут соответственно равны 0, 1 и 2. Константы STDIN_FILENO,
STDOUT_FILENO и STDERR_FILENO определены этими значениями в <unistd.h>.
Заметьте, что совместное использование FILE и описателей низкого уровня
может привести к непредвиденным последствиям, этого следует избегать при
любом удобном случае. Для "мазохистов": POSIX.1, раздел 8.2.3, детально
описывает, как определяется такая совместная работа. Общее правило
гласит, что описатели поддерживаются ядром, а stdio всего лишь
библиотека. Это означает, например, что после выполнения операции
дочерний процесс наследует все описатели открытых файлов, но все старые
потоки становятся недоступными.
Так как
stdinstdout
и
stderr
определены как макросы, то наследовать их нельзя. Стандартные потоки
могут ссылаться на другие файлы при помощи библиотечной функции
freopen(3),
специально разработанной для возможности наследования
stdinstdout
и
stderr
Стандартные потоки можно закрыть вызовом
exit(3)
и при обычном завершении программы.
Поток
stderr
не буферизируется. Поток
stdout
буферизируется построчно при обращении к терминалу.
Неполные строки не появятся либо до вызовов
fflush(3)
или
exit(3),
либо пока не будет напечатана новая строка. Это может привести к
непредсказуемым последствиям, особенно при выводе отчета об отладке.
Режим буферизации стандартных потоков (или любых других) может быть
изменен вызовами
setbuf(3)
или
setvbuf(3).
Заметьте, что в этом случае
stdin
ассоциируется с терминалом, при этом возможна буферизация ввода
драйвером терминала, который не соотносится с буферизацией ввода/вывода.
На самом деле, ввод с терминала построчно буферизируется в ядре.
Обработка вводимой ядром информации может быть изменена при помощи
вызовов типа
tcsetattr(3);
см. также
stty(1)
и
termios(3).
СООТВЕТСТВИЕ СТАНДАРТАМ
Макросы
stdinstdout
и
stderr
соответствуют стандарту
St -ansiC ,
где оговаривается, что эти три потока должны открываться
во время запуска программы.