НАЗВАНИЕ¶
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@hsys.msk.ru> 1999-2001