STDIN(3)

stdin, stdout, stderr - стандартные потоки I/O #include <stdio.h> extern FILE *stdin; extern FILE *stdout; extern FILE *stderr; В обычных условиях любая программа в Unix имеет три потока, открытых для нее при запуске: один для вывода, другой для ввода и один для вывода диагностики или сообщений об ошибках. Обычно они прикреплены к пользовательскому терминалу (см. tty(4) ), но могут ссылаться и на другие файлы или устройства в зависимости от того, что установлено родительским процессом (прочтите раздел ``Перенаправление ввода/вывода (Redirection)'' в sh(1) ).

Поток ввода называется ``стандартным вводом (standard input)''; поток вывода называется ``стандартным выводом (standard output)''; а поток сообщений об ошибках называется ``стандартными ошибками (standard error)''. Эти термины были сокращены для названий файлов, на которые указывают ссылки, а именно: stdin, stdout и stderr.

Каждый из этих терминов является макросом stdio(3), указывающим на FILE; возможно их использование с такими функциями, как fprintf(3) или fread(3).

Переменные типа FILE являются буферизируемыми оболочками описателей файлов Unix. Доступ к этим файлам можно осуществить также при помощи низкоуровнего интерфейса для работы с файлами и с использованием таких функций, как read(2) и lseek(2). Целые описатели файлов, ассоциированных с потоками stdin, stdout и stderr, будут соответственно равны 0, 1 и 2. Константы STDIN_FILENO, STDOUT_FILENO и STDERR_FILENO определены этими значениями в <unistd.h>.

Заметьте, что совместное использование FILE и описателей низкого уровня может привести к непредвиденным последствиям, этого следует избегать при любом удобном случае. Для "мазохистов": POSIX.1, раздел 8.2.3, детально описывает, как определяется такая совместная работа. Общее правило гласит, что описатели поддерживаются ядром, а stdio всего лишь библиотека. Это означает, например, что после выполнения операции дочерний процесс наследует все описатели открытых файлов, но все старые потоки становятся недоступными.

Так как stdin, stdout и stderr определены как макросы, то наследовать их нельзя. Стандартные потоки могут ссылаться на другие файлы при помощи библиотечной функции freopen(3), специально разработанной для возможности наследования stdin, stdout и stderr. Стандартные потоки можно закрыть вызовом exit(3) и при обычном завершении программы. sh(1), csh(1), open(2), fopen(3), stdio(3) Поток stderr не буферизируется. Поток stdout буферизируется построчно при обращении к терминалу. Неполные строки не появятся либо до вызовов fflush(3) или exit(3), либо пока не будет напечатана новая строка. Это может привести к непредсказуемым последствиям, особенно при выводе отчета об отладке. Режим буферизации стандартных потоков (или любых других) может быть изменен вызовами setbuf(3) или setvbuf(3). Заметьте, что в этом случае stdin ассоциируется с терминалом, при этом возможна буферизация ввода драйвером терминала, который не соотносится с буферизацией ввода/вывода. На самом деле, ввод с терминала построчно буферизируется в ядре. Обработка вводимой ядром информации может быть изменена при помощи вызовов типа tcsetattr(3); см. также stty(1) и termios(3). Макросы stdin, stdout и stderr соответствуют стандарту ansiC, где оговаривается, что эти три потока должны открываться во время запуска программы.