НАЗВАНИЕ
open, creat −− открыть и, вероятно, создать файл или устройство
КРАТКАЯ СВОДКА
#include
<sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int
open(const char *pathname, int
flags);
int open(const char *pathname, int
flags, mode_t mode);
int creat(const char *pathname, mode_t
mode);
ОПИСАНИЕ
Системный вызов open превращает имя файла в дескриптор файла (небольшое неотрицательное число, используемое при последующем вводе-выводе, например, с read, write, и т. п. Если системный вызов завершается успешно, возвращенный файловый дескриптор является самым маленьким дескриптором, который еще не открыт процессом. В результате этого вызова появляется новый открытый файл, не разделяемый ни с каким процессом (разделяемые открытые файлы могут возникнуть в результате системного вызова fork(2). Новый файловый дескриптор будет оставаться открытым при выполнении функции exec(2) (смотри описание fcntl(2)). Указатель в файле устанавливается в начало.
Параметр flags -- это O_RDONLY, O_WRONLY или O_RDWR, задающие, соответственно, открытие файла только для чтения, только для записи и для чтения и записи, которые можно комбинировать с помощью логического ИЛИ с нулем или более нижеследующих флагов:
O_CREAT |
Если файл не существует, то он будет создан. Владелец (uid) файла устанавливается в фактический идентификатор владельца процесса. Группа (gid) устанавливается либо в фактический идентификатор группы процесса или же в идентификатор группы родительского каталога (зависит от типа файловой системы и флагов программы mount, а также прав доступа к родительскому каталогу. См., например, флаги bsdgroups и sysvgroups в файловой системе ext2, которые описаны в mount(8)). | ||
O_EXCL |
Если используется совместно с O_CREAT, то если файл уже существует, то open завершится с ошибкой. В этом контексте символьная ссылка существует, независимо от того, куда она указывает. O_EXCL не работает на файловых системах NFS, а в программах, полагающихся на этот флаг для реализации блокировки, возникнет race condition. Решение для атомарной блокировки с помощью файла: создать файл с уникальным именем на той же самой файловой системе (это имя может содержать, например, имя машины и идентификатор процесса), использовать link(2), чтобы создать ссылку на файл блокировки. Если link() возвращает 0, значит, блокировка была успешной. В противном случае используйте stat(2), чтобы убедиться, что количество ссылок на уникальный файл возросло до двух, что опять означает, что блокировка была успешной. |
O_NOCTTY
Если pathname ссылается на терминальное устройство — см. tty(4), — то оно не станет контролирующим терминалом процесса, даже если у этого процесса нет такового.
O_TRUNC |
Если файл уже существует, является обычным файлом, а режим открытия позволяет запись (то бишь это O_RDWR или O_WRONLY), то он будет обрезан до нулевой длины. Если файл является FIFO или устройством терминала, то флаг O_TRUNC игнорируется. В противном случае действие O_TRUNC не описано. (На многих версиях Linux этот флаг будет игнорирован; на других версиях будет возвращена ошибка.) |
O_APPEND
Файл открывается в режиме добавления. Перед каждым write, файловый указатель перемещается в конец файла, как если бы использовался lseek. O_APPEND может привести к повреждению файлов на файловой системе NFS, если несколько процессов одновременно добавляют данные в один файл. Это происходит из-за того, что NFS не поддерживает добавление в файл, поэтому ядро на машине-клиенте должно эмулировать эту поддержку, что не может быть выполнено без race condition.
O_NONBLOCK или O_NDELAY
Если возможно, то файл открывается в неблокирующем режиме. Ни open, ни другие последующие операции над возвращенным дескриптором файла не заставят вызывающий процесс ждать. Работа с каналами FIFO также описана в fifo(4). Этот режим не обязан как-либо действовать на файлы, не являющиеся FIFO.
O_SYNC |
Файл открывается в режиме синхронного ввода-вывода. Все вызовы write для соответствующего дескриптора файла блокируют вызывающий процесс до тех пор, пока данные не будут физически записаны оборудованием, на котором находится файл. Однако же, смотри в разделе ОГРАНИЧЕНИЯ. |
O_NOFOLLOW
Если pathname -- это символическая ссылка, то open завершается с кодом ошибки. Это расширение из FreeBSD, которое было добавлено в Linux в версии 2.1.126. Все прочие символические ссылки в имени будут обработаны как обычно. Заголовочные файлы из glibc 2.0.100 и позже содержат определение этого флага; ядра с версиями меньше, чем 2.1.126, игнорируют этот флаг.
O_DIRECTORY
Если pathname не является каталогом, то open завершится с кодом ошибки. Этот флаг используется только в Linux, и был добавлен в ядре 2.1.126, чтобы избежать проблем с атаками типа "отказ обслуживания", если opendir(2) был вызван с каналом FIFO или ленточным устройством. Этот флаг не следует использовать вне реализации opendir.
O_LARGEFILE
На 32-битных системах, поддерживающих Большие Файловые Системы, этот флаг позволяет открывать файлы, длина которых не помещается в 31 бит.
Некоторые из вышеописанных флагов могут быть изменены после открытия файла с помощью fctnl.
Аргумент mode задает права доступа, которые используются в случае создания нового файла. Они модифицируются обычным способом, используя umask процесса: права доступа свежесозданного файла равны (mode & ~umask). Заметьте, что этот режим доступа относится только к последующим обращениям к свежесозданному файлу; системный вызов open, который создает новый файл только для чтения, вполне может вернуть файловый дескриптор для чтения/записи.
Нижеследующие
символические
константы
можно
использовать
в mode:
S_IRWXU
00700 пользователь (владелец файла) имеет права чтения, записи и выполнения.
S_IRUSR (S_IREAD)
00400 пользователь имеет право чтения
S_IWUSR (S_IWRITE)
00200 пользователь имеет право записи
S_IXUSR (S_IEXEC)
00100 пользователь имеет право выполнения
S_IRWXG
00070 группа имеет права чтения, записи и выполнения
S_IRGRP
00040 группа имеет право чтения
S_IWGRP
00020 группа имеет право записи
S_IXGRP
00010 группа имеет право выполнения
S_IRWXO
00007 все остальные имеют права чтения, записи и выполнения
S_IROTH
00004 все остальные имеют право чтения
S_IWOTH
00002 все остальные имеют право записи
S_IXOTH
00001 все остальные имеют право выполнения
mode всегда должен быть указан при использовании O_CREAT, во всех остальных случаях этот параметр игнорируется.
creat эквивалентен open с flags, равными O_CREAT | O_WRONLY | O_TRUNC.
ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
open и creat возвращают новый дескриптор файла, или −1, если произошла ошибка (в этом случае errno устанавливается должным образом). Заметьте, что open может открывать файлы устройств, но creat не может создавать их -- используйте для этого mknod(2).
На файловых системах NFS с включенным преобразованием идентификаторов пользователей open может вернуть файловый дескриптор, но, например, read(2) вернет ошибку EACCES. Это из-за того, что клиент выполняет open, проверяя права доступа, но преобразование идентификаторов производится сервером при запросах на чтение и запись.
Если файл только что создан, его atime, ctime и mtime, а также ctime и mtime родительского каталога, установлены в текущее время, В противном случае если файл модифицирован из-за флага O_TRUNC, его поля ctime и mtime устанавливаются в текущее время.
ОШИБКИ
EEXIST |
pathname уже существует, и были использованы O_CREAT и O_EXCL. | ||
EISDIR |
pathname ссылается на каталог, а тип доступа подразумевает запись. | ||
EACCES |
Запрошенный доступ к файлу не разрешен, или же один из каталогов в pathname не позволяет поиск (выполнение), или же файл еще не существует, а доступ для записи в родительский каталог не разрешен. error_ENAMETOOLONG(pathname) error_ENOENT(pathname) | ||
ENOTDIR |
Компонент, использованный как каталог в pathname, таковым не является, или был указан флаг O_DIRECTORY, а pathname не является каталогом. | ||
ENXIO |
Установлены O_NONBLOCK | O_WRONLY, файл является каналом FIFO, но нет процессов, которые открыли этот канал для чтения. Возможно также, что файл является файлом устройства, но соответствующее устройство не установлено. | ||
ENODEV |
pathname ссылается на файл устройства, но соответствующего устройства не существует. (Это ошибка в ядре Linux: должен возвращаться ENXIO.) | ||
EROFS |
pathname ссылается на файл, находящийся на файловой системе, смонтированной только для чтения, и был запрошен доступ для записи. | ||
ETXTBSY |
pathname ссылается на исполняемый файл, который в настоящее время исполняется, и был запрошен доступ для записи. error_EFAULT(pathname) | ||
ELOOP |
Слишком много символических ссылок было пройдено при обнаружении pathname, или был указан флаг O_NOFOLLOW, а pathname является символической ссылкой. | ||
ENOSPC |
pathname нужно было создать на устройстве, на котором не было места для нового файла. error_ENOMEM | ||
EMFILE |
Процесс уже открыл максимально допустимое количество файлов. | ||
ENFILE |
Достигнут предел на максимальное общее количество файлов, открытых в системе. |
СООТВЕТСТВИЕ СТАНДАРТАМ
SVr4, SVID, POSIX, X/OPEN, BSD 4.3 Флаги O_NOFOLLOW и O_DIRECTORY специфичны для Linux. Для того, чтобы получить их определение, может потребоваться определить (через #define) символ _GNU_SOURCE.
ОГРАНИЧЕНИЯ
В протоколе, на котором работает NFS, существует множество недоработок, в числе прочего, оказывающих влияние на O_SYNC и O_NDELAY.
POSIX предоставляет три разных варианта синхронного ввода-вывода, соответствующего флагам O_SYNC, O_DSYNC и O_RSYNC. В настоящее время (версия 2.1.130), все они являются синонимами под Linux.
СМОТРИ ТАКЖЕ
read(2), write(2), fcntl(2), close(2), link(2), mknod(2), mount(2), stat(2), umask(2), unlink(2), socket(2), fopen(3), fifo(4)
ПЕРЕВОД
Copyright (C) Alexey Mahotkin <alexm [AT] hsys.ru> 1999-2001