Скачиваний:
86
Добавлен:
12.05.2015
Размер:
533.5 Кб
Скачать

3.14. Функция ioctl

Функция ioctl всегда была универсальным инструментом ввода-вывода. Все, что невозможно выразить с помощью функций, описанных в этой главе, как правило, делается с помощью ioctl. Возможности этой функции чаще всего использовались в операциях терминального ввода-вывода.

#include <sys/ioctl.h>

int ioctl (int filedes, int request, ...);

/* возвращает -1 в случае ошибки, другие значения – в случае успеха */

Согласно стандарту ISO C необязательные аргументы обозначены многоточием. Однако в большинстве случаев передается только один дополнительный аргумент, который представляет собой указатель на переменную или структуру.

Каждый драйвер устройства может определять свой собственный набор команд ioctl. Тем не менее, операционная система предоставляет набор универсальных команд ioctl для различных классов устройств.

Операции с накопителями на магнитной ленте позволяют записывать на ленту признак конца файла, перематывать ленту в начало, перемещаться вперед через заданное число файлов или записей и тому подобное. Ни одну из этих операций нельзя достаточно просто выразить в терминах других функций, описанных в данной главе (read, write, lseek и т. д.). Таким образом, простейший способ взаимодействия с такими устройствами всегда заключался в управлении ими через функцию ioctl.

3.15. Каталог /dev/fd

В современных Unix-подобных ОС (в том числе Linux) имеется каталог /dev/fd, в котором находятся файлы с именами 0, 1, 2 и т. д. Открытие файла /dev/fd/<n> эквивалентно созданию дубликата дескриптора с номером n, где n – это номер открытого дескриптора.

В ОС Linux также имеются файлы /dev/stdin, /dev/stdout и /dev/stderr, которые эквивалентны файлам /dev/fd/0, /dev/fd/1 и /dev/fd/2 соответственно.

Файлы из каталога /dev/fd преимущественно используют командные оболочки. Это позволяет программам, которые требуют указания имени файла, работать со стандартными устройствами ввода и вывода таким же образом, как и с обычными файлами. Например, в следующем примере программа cat использует в качестве входного файла стандартный ввод, обозначаемый символом “-”:

tail file2 | cat file1 – file3 | lpr

Сначала утилита cat читает содержимое файла file1, затем файл стандартного ввода (результат работы утилиты tail, обрабатывающей файл file2) и, наконец, файл file3. Если в системе есть каталог /dev/fd, можно опустить символ “-” и переписать команду следующим способом:

tail file2 | cat file1 /dev/fd/0 file3 | lpr

Символ “-” в качестве аргумента командной строки для обозначения файла стандартного ввода или стандартного вывода – это своего рода ляп, который присутствует во многих программах. Например, если он будет стоять на месте первого файла, то будет очень похож на префикс для задания опции в командной строке. Использование каталога /dev/fd – это шаг к единообразию и порядку.

3.16. Выводы по главе 3

В этой главе были описаны базовые функции ввода-вывода, предоставляемые системой Unix. Их часто называют функциями небуферизованного ввода-вывода, потому что каждый вызов функции read или write означает обращение к системному вызову ядра.

Были рассмотрены атомарные операции, которые используются для доступа к одному и тому же файлу из нескольких процессов. Мы также вкратце познакомились со структурами данных, используемых ядром для организации совместного доступа к информации об открытых файлах. В дальнейшем мы еще вернемся к этим структурам.

Также были описаны функции fcntl и ioctl.

Соседние файлы в папке Chapter.2