
- •Часть вторая. Подсистема управления файлами
- •Глава 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.2. Дескрипторы файлов
Все открытые файлы представлены в ядре файловыми дескрипторами. Файловый дескриптор – это неотрицательное целое число. Когда процесс открывает существующий файл или создает новый, ядро возвращает ему файловый дескриптор. Чтобы выполнить запись в файл или чтение из него, нужно передать функции read или write его файловый дескриптор, полученный в результате вызова функции open или creat.
В соответствии с принятыми соглашениями командные оболочки Unix ассоциируют файловый дескриптор 0 со стандартным устройством ввода процесса, 1 – со стандартным устройством вывода и 2 – со стандартным устройством вывода сообщений об ошибках. Это соглашение используется командными оболочками и большинством приложений, но не является особенностью ядра Unix. Тем не менее, многие приложения не смогли бы работать, если это соглашение было бы нарушено.
В Posix-совместимых приложениях вместо фактических значений 0, 1 и 2 следует использовать константы STDIN_FILENO, STDOUT_FILENO и STDERR_FILENO. Определения этих констант находятся в заголовочном файле <unistd.h>.
Под файловые дескрипторы отводится диапазон чисел от 0 до OPEN_MAX. В ранних реализациях UNIX максимальным значением файлового дескриптора было число 19, что позволяло каждому процессу держать открытыми до 20 файлов, но многие системы увеличили это число до 63.
Значение OPEN_MAX, установленное в ОС Linux 2.6.9 по умолчанию, равно 1024, в чем можно легко убедиться с помощью вызова функцииsysconf(_SC_OPEN_MAX). Суперпользователь может увеличить этот предел, например, с помощью командыulimit –n, но не более чем до 1048576, то есть количество файловых дескрипторов на процесс здесь жестко ограничено сверху. Кроме того, суперпользователь может ограничивать использование файловых дескрипторов обычными пользователями с помощью конфигурационного файла /etc/security/limits.conf.
3.3. Функция open
Создание или открытие файла производится функцией open.
#include <fcntl.h>
int open (const char *pathname, int oflag, ... /* mode_t mode */);
/* возвращает неотрицательный дескриптор, если функция выполнена успешно, -1 – в случае ошибки */
Третий аргумент обозначен многоточием (...), таким образом стандарт ISO C указывает, что количество и типы остальных аргументов могут варьироваться. В этой функции третий аргумент используется только при создании нового файла, о чем мы поговорим немного позже. Этот аргумент мы привели в прототипе функции как комментарий.
Аргумент pathname представляет имя файла, который будет открыт или создан. Эта функция может принимать большое количество параметров, которые определяются аргументом oflag. Значение этого аргумента формируется объединением с помощью побитового ИЛИ (OR) одной или более констант, определяемых в заголовочном файле <fcntl.h> и перечисленных ниже в табл. 3.1 и 3.2:
Таблица 3.1
Обязательные константы
Константа |
Описание |
O_RDONLY |
Файл открывается только на чтение |
O_WRONLY |
Файл открывается только на запись |
O_RDWR |
Файл открывается как для чтения, так и для записи |
Должна быть указана одна и только одна из этих трех констант. Далее приводится список констант, присутствие которых в аргументе oflag необязательно:
Таблица 3.2
Необязательные константы
Константа |
Описание |
O_APPEND |
Запись производится в конец файла |
O_CREAT |
Если файл не существует, он будет создан. Этот флаг требует наличия третьего аргумента функции open (mode), который определяет значения битов прав доступа к создаваемому файлу |
O_EXCL |
Приводит к появлению ошибки, если файл уже существует и задан флаг O_CREAT. При такой комбинации флагов атомарно выполняется проверка существования файла и его создание, если файл не существует |
O_TRUNC |
Если файл существует и успешно открывается на запись либо на чтение и запись, то его размер усекается до нуля |
O_NOCTTY |
Если аргумент pathname ссылается на файл терминального устройства, то это устройство не назначается управляющим терминалом вызывающего процесса |
O_NONBLOCK |
Если аргумент pathname ссылается на именованный канал (FIFO), специальный блочный файл или специальный символьный файл, этот флаг задает неблокирующий режим открытия файла и последующих операций ввода-вывода |
O_SYNC |
Каждый вызов функции write ожидает завершения физической операции ввода-вывода, включая операцию обновления атрибутов файла |
Функция open гарантирует, что возвращаемый ею дескриптор файла будет представлять собой наименьшее не используемое в качестве дескриптора неотрицательное число. Это обстоятельство используется в некоторых приложениях для открытия нового файла вместо стандартного ввода, стандартного вывода или стандартного вывода сообщений об ошибках. Например, приложение может закрыть файл стандартного вывода (обычно это дескриптор 1) и затем открыть другой файл, зная, что он будет открыт с дескриптором 1. В разделе 3.12 мы продемонстрируем более надежный способ открытия файла на конкретном дескрипторе при помощи функции dup2.
Если полный путь к файлу превышает значение PATH_MAX или какой-либо компонент имени файла или строки пути превышает NAME_MAX, возвращается признак ошибки и в переменную errno записывается код ошибки ENAMETOOLONG.