
- •Часть вторая. Подсистема управления файлами
- •Глава 3. Файловый ввод-вывод 2
- •Глава 4. Файлы и каталоги 21
- •Глава 5. Стандартная библиотека ввода-вывода 56
- •Глава 6. Информация о системе и файлы данных 72
- •Глава 3. Файловый ввод-вывод
- •3.1. Введение
- •3.2. Дескрипторы файлов
- •3.3. Функция open
- •3.4. Функция creat
- •3.5. Функция close
- •3.6. Функция lseek
- •3.7. Функция read
- •3.8. Функция write
- •3.9. Совместное использование файлов
- •3.10. Атомарные операции
- •3.11. Функции dup и dup2
- •3.12. Функции sync, fsync и fdatasync
- •3.13. Функция fcntl
- •3.14. Функция ioctl
- •3.15. Каталог /dev/fd
- •3.16. Выводы по главе 3
- •3.17. Упражнения по главе 3
- •Глава 4. Файлы и каталоги
- •4.1. Введение
- •4.2. Функции stat, fstat и lstat
- •4.3. Типы файлов
- •4.4. Set-user-id и set-group-id
- •4.5. Права доступа к файлу
- •4.6. Принадлежность новых файлов и каталогов
- •4.7. Функция access
- •4.8. Функция umask
- •4.9. Функции chmod и fchmod
- •4.10. Бит sticky
- •4.11. Функции chown, fchown и lchown
- •4.12. Размер файла
- •4.13. Усечение файлов
- •4.14. Файловые системы unix-подобных ос
- •4.14.1. Обзор построения файловых систем
- •4.14.2. Основные компоненты файловой системы ext2 ос Linux
- •4.14.3. Основные компоненты группы блоков
- •4.14.4. Структура индексного узла
- •4.14.5. Структура обычного файла
- •4.14.6. Структура каталогов
- •4.15. Функции link, unlink и rename
- •4.16. Символические ссылки
- •4.17. Функции symlink и readlink
- •4.18. Временные характеристики файлов
- •4.19. Функция utime
- •4.20. Функции mkdir и rmdir
- •4.21. Чтение каталогов
- •4.22. Функции chdir, fchdir, getcwd и chroot
- •4.23. Специальные файлы устройств
- •4.24. Выводы по главе 4
- •4.25. Упражнения по главе 4
- •Глава 5. Стандартная библиотека ввода-вывода
- •5.1. Введение
- •5.2. Потоки и объекты file
- •5.3. Стандартные потоки ввода, вывода и вывода сообщений об ошибках
- •5.4. Буферизация
- •5.5. Открытие и закрытие потока
- •5.6. Чтение из потока и запись в поток
- •5.6.1. Ввод-вывод символов
- •5.6.2. Построчный ввод-вывод
- •5.6.3. Ввод-вывод двоичных данных
- •5.7. Позиционирование в потоке
- •5.8. Форматированный ввод-вывод
- •5.9. Подробности реализации
- •5.10. Временные файлы
- •5.11. Выводы по главе 5
- •5.12. Упражнения по главе 5
- •Глава 6. Информация о системе и файлы данных
- •6.1. Введение
- •6.2. Файл паролей
- •6.3. Теневые пароли
- •6.4. Файл групп
- •6.5. Идентификаторы дополнительных групп
- •6.6. Прочие файлы данных
- •6.7. Учет входов в систему
- •6.8. Информация о системе
- •6.9. Функции даты и времени
- •6.10. Выводы по главе 6
- •6.11. Упражнения по главе 6
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.