Теория и практика программирования на Си в Unix

       

Ввод-вывод


Для осуществления ввода-вывода в системах UNIX существуют два способа: - использование стандартной библиотеки Си: функции fopen (), fread (), fwrite ()... Примитив fopen () возвращает указатель объекта типа FILE (FILE pointer). Запись и считыва- ние, т.о. осуществляются в буферном режиме. - использование библиотеки UNIX: системные вызовы open (), read (), write ()... Примитив open () возвращает целое значение, называемое file descriptor (дескриптор файла). Shell присваивает номер 0 стандартному вводу, 1 - стандартному выводу и 2 - сообщению об ошибке (stderr). Последующие номера присваиваются по нарастающей, за исключением случаев, когда номер был освобожден процессом посредством вызова функции close () или exit (). Другие примитивы возвращают дескриптор файла: creat (), dup (), pipe (), socket () и fcntl (). Функция fdopen () устанавливает связь между стандартной библиотекой Си и библиотекой UNIX, связывая FILE pointer c file descriptor. Системные вызовы fcntl () и ioctl () позволяют изменять характеристики уже открытого файла: право доступа, блокировка считывания или записи. Ввод-вывод на диск осуществляется механизмом кэширования с предварительным считыванием и отсроченной записью. Кэшем называется участок памяти, отведенный под эти операции. Т.о., при записи, данные передаются непосредственно на диск только тогда, когда кэш переполнен или существует потребность в записи именно на диск (sync оператора или демона update). Вызов dup () позволяет присваивать файлу дополнительный file descriptor, а система гарантирует, что этот новый номер является наименьшим из имеющихся. Это позволяет переориентировать стандартный ввод-вывод и вывод сообщений об ошибках.

ПРОГРАММА 3 /*пpимеp пеpеиндексации вывода в файл */ #include <stdio.h>

#include <fcntl.h>

main() { int fd; /* дескpиптоp файла */ /* откpытие вpеменного файла с маской создания 666*/ fd = open ("/tmp/file", O_CREAT|O_RDWR, 0666); /*можно было бы сделать и пpоще : с помощью функции dup2,котоpая эквивалентна close()+dup() : dup2(1,fd), dup2(2,fd) */ close(1); close(2); dup(fd); dup(fd); /*запись идет в stdout и stderr; из-за пеpеиндексации запись идет в файл /tmp/file */ write(1, "ecriture stdout\n", 16); write(2, "ecriture stderr\n", 16); }



Содержание раздела