Начиная с версии ядра 2.6.22, для получения информации о дескрипторах файлов любого имеющегося в системе процесса могут быть прочитаны файлы в каталоге /proc/PID/fdinfo, которые есть только в Linux. В этом каталоге находится по одному файлу для каждого дескриптора открытого процессом файла, с именем, совпадающим с номером дескриптора. В поле pos этого файла показано текущее смещение в файле (см. раздел 4.7). В поле flags находится восьмеричное число, показывающее флаги режима доступа к файлу и флаги состояния открытого файла. (Чтобы декодировать эти числа, нужно посмотреть на числовые значения флагов в заголовочных файлах библиотеки языка C.)
Рассмотрим константы флагов подробнее.
• O_APPEND — записи добавляются исключительно в конец файла. Значение этого флага рассматривается в разделе 5.1.
• O_ASYNC — генерирование сигнала при появлении возможности ввода-вывода с использованием файлового дескриптора, возвращенного системным вызовом open(). Это свойство называется
• O_CLOEXEC (с выходом Linux 2.6.23) — установка флага закрытия при выполнении — флага close-on-exec (FD_CLOEXEC) для нового дескриптора файла. Флаг FD_CLOEXEC рассматривается в разделе 27.4. Использование флага O_CLOEXEC позволяет программе не выполнять дополнительные операции F_GETFD и F_SETFD при вызове fcntl() для установки флага close-on-exec. Кроме того, в многопоточных программах необходимо избегать состояния гонки, возможное при использовании данной технологии. Например, такое состояние может возникать, когда один поток открывает дескриптор файла, а затем пытается пометить его флагом close-on-exec, и в то же самое время другой поток выполняет системный вызов fork(), а затем exec() из какой-нибудь другой программы. (Предположим, что второй поток справляется и с fork(), и с exec() в период между тем, как первый поток открывает файловый дескриптор и использует fcntl() для установки флага close-on-exec.) Такое состязание может привести к тому, что открытые дескрипторы файлов могут непреднамеренно быть переданы небезопасным программам. (Состояние гонки подробнее рассматривается в разделе 5.1.)
• O_CREAT — создание нового, пустого файла, если такого файла еще не существует. Этот флаг срабатывает, даже если файл открывается только для чтения. Если указывается O_CREAT, то при вызове open() нужно также обязательно предоставлять аргумент mode. В противном случае права доступа к новому файлу будут установлены по какому-либо произвольному значению, взятому из стека.
• O_DIRECT — разрешение файловому вводу-выводу обходить буферный кэш. Это свойство рассматривается в разделе 13.6. Чтобы сделать определение этой константы доступным из
• O_DIRECTORY — возвращение ошибки (в этом случае errno присваивается значение ENOTDIR), если путевое имя не является каталогом. Этот флаг представляет собой расширение, разработанное главным образом для реализации opendir() (см. раздел 18.8). Чтобы сделать определение этой константы доступным из
• O_DSYNC (с выходом Linux 2.6.33) — выполнение записи в файл в соответствии с требованиями соблюдения целостности данных при синхронизированном вводе-выводе. Обратите внимание на буферизацию ввода-вывода на уровне ядра, рассматриваемую в разделе 13.3.
• O_EXCL — используется в сочетании с флагом O_CREAT как указание, что файл, если он уже существует, не должен быть открыт. Вместо этого системный вызов open() не выполняется, а errno присваивается значение EEXIST. Иными словами, флаг позволяет вызывающему коду убедиться в том, что это и есть процесс, создающий файл. Проверка существования и создание файла выполняются в атомарном режиме. Понятие атомарности рассматривается в разделе 5.1. Когда в качестве флагов указаны и O_CREAT, и O_EXCL, системный вызов open() не выполняется (с ошибкой EEXIST), если путевое имя является символьной ссылкой. Такое поведение в SUSv3 требуется, чтобы привилегированные приложения могли создавать файл в определенном месте и при этом исключалась возможность создания файла в другом месте с использованием символьной ссылки (например, в системном каталоге), которая негативно скажется на безопасности.