Читайте также:
|
|
Системный вызов open (2) открывает файл для чтения или записи и возвращает дескриптор файла для последующих операций с этим файлом. Синтаксис:
#include <fcntl.h> /*для flags */
int open(const char *pathname, int flags, mode_t mode);
аргумент pathname - является указателем на маршрутное имя файла; cflag – поразрядное ИЛИ с одной или более констант, устанавливает флаги статуса файла;
O_RDONLY | открыть только для чтения |
O_WRONLY | открыть только для записи |
O_RDWR | открыть на чтение/запись |
O_APPEND | принудительно осуществлять все записи в конец файла |
O_CREAT | создает новый файл, если он не существует, идентификаторы владельца и группы создаваемого файла устанавливаются равными, соответственно, действующим идентификаторам пользователя и группы процесса, а младшие 12 бит значения режима доступа к файлу устанавливаются равными значению аргумента mode; если файл существует, то флаг игнорируется |
O_TRUNC | если файл существует, то он опустошается (размер = 0), а режим доступа и владелец не изменяются |
O_EXCL | если установлены оба флага O_EXCL и O_CREAT, то системный вызов open(2) завершается неудачей, если файл уже существует |
При создании файла следует указать права доступа к нему. Это можно сделать с помощью восьмеричного числа (часто использовалось в старом коде). Лучше использовать побитовую операцию ИЛИ для одного или более символических имен из <sys/stat.h>:
S_IRWXU | чтение, запись и выполнение для владельца | |
S_IRUSR | чтение для владельца (или S_IREAD) | |
S_IWUSR | запись для владельца (или S_IWRITE) | |
S_IXUSR | исполнение для владельца (или S_IWRITE) | |
S_IRWXG | чтение, запись и выполнение для группы | |
S_IRGRP | чтение для группы | |
S_IWGRP | запись для группы | |
S_IXGRP | исполнение для группы | |
S_IRWXO | чтение, запись и выполнение для остальных | |
S_IROTH | чтение для остальных | |
S_IWOTH | запись для остальных | |
S_IXOTX | исполнение для остальных |
Пример. Создание переменных типа mode_t:
mode_t m1, m2;
m1 = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; /* 0644 -rw -r-- r -- */
m2 = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTX /* 0755 –rwx r-x r-x */
Биты дополнительных разрешений (S_ISUID, S_ISGID, S_ISVTX) не должны использоваться при первоначальном создании файла. Изменять их следует с помощью chmod (2) и fchmod (2).
Пример. Открытие/создание файлов для оболочки, соответствующее операторам > и >>:
fd = open (filename, O_CREAT | O_WRONLY | O_TRUNC, mode); /* для > */
fd = open (filename, O_CREAT | O_WRONLY | O_APPEND, mode); /* для >> */
здесь флаг O_EXCL не используется, т.к. для > и >> существование файла ошибкой не является.
[EACCES] | доступ запрещен |
[EAGAIN] | файл существует, но доступ к нему заблокирован |
[EEXIST] | флаги O_CREAT и O_EXCL установлены и указанный файл существует. |
[EIO] | разрыв связи или ошибка при открытии псевдоустройства |
[EISDIR] | указанный файл является каталогом и открывается на запись или чтение/запись. |
[EMFILE] | превышается максимально допустимое количество дескрипторов файлов, открытых одновременно в одном процессе. |
[ENFILE] | переполнение системной таблицы файлов. |
[ENOENT] | флаг O_CREAT не установлен и указанный файл не существует. |
[ENOLINK] | маршрутное имя path указывает на удаленный компьютер, связи с которым в данный момент нет. |
[ENOSPC] | установлены флаги O_CREAT и O_EXCL и нет свободных описателей файлов. |
[ENOTDIR] | компонент маршрута не является каталогом. |
[ENXIO] | указанный файл является специальным символьным или блочным файлом, а устройство, ассоциированное с этим специальным файлом, не существует. |
[EROFS] | указанный файл расположен в файловой системе, доступной только на чтение, а открывается на запись или чтение/запись. |
При успешном завершении результатом служит дескриптор файла; в случае ошибки возвращается ‑1, а переменной errno присваивается код ошибки. Приведем ряд условий (неполный список), из-за которых системный вызов open завершается неудачей, и дескриптор указанного файла не открывается:
Системный вызов creat (2) тоже создает новые файлы. Он объявлен следующим образом:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int creat (const char *pathname, mode_t mode);
Если файл существует, то его размер становится равным 0, а режим доступа и владелец не изменяются. Если файл не существует, то идентификаторы владельца и группы создаваемого файла устанавливаются равными, соответственно, действующим идентификаторам пользователя и группы процесса, а младшие 12 бит значения режима доступа файла устанавливаются равными значению аргумента mode, модифицированному в соответствии с umask; бит навязчивости (присутствия) обнуляется.
В случае успешного завершения системного вызова возвращается дескриптор файла, открытого только на запись, даже если режим доступа к файлу не разрешает запись. Указатель текущей позиции устанавливается на начало файла.
Процесс может иметь открытыми одновременно не более 20 файлов. Новый файл может быть создан с режимом доступа, запрещающим запись.
Системный вызов creat (2) завершается неудачей (возвращает –1), если выполнено хотя бы одно из условий, перечисленных для open (2).
Системный вызов read (2) – чтение из файла. Синтаксис:
int read (int fildes, char *buf, unsigned nbyte)
Аргумент fildes ‑ это дескриптор файла, полученный после выполнения системных вызовов creat (2), open (2), и нек. других. Системный вызов read (2) пытается прочитать nbyte байт из файла, ассоциированного с дескриптором fildes, в буфер, указателем на который является аргумент buf. Для устройств, допускающих позиционирование (например ЖД, ГД), системный вызов read (2) выполняет чтение из файла, начиная с указателя текущей позиции, ассоциированного с дескриптором fildes. После завершения чтения указатель текущей позиции файла увеличивается на количество прочитанных байт.
При успешном завершении системного вызова read (2) возвращается количество байт (неотрицательное целое число), реально прочитанных и помещенных в буфер; это количество может быть меньше значения аргумента nbyte, если количество байт, оставшихся в файле, меньше значения аргумента nbyte. Если текущая позиция совпадала с концом файла, результат будет равен 0. В случае ошибки возвращается -1, а переменной errno присваивается код ошибки.
Системный вызов read (2) завершается неудачей, если выполнено хотя бы одно из следующих условий (перечень далеко не полный, не рассматривается чтение из псевдоустройств, из каналов, из файлов, к которым разрешен совместный доступ):
[EBADF] | аргумент fildes не является корректным дескриптором файла, открытого на чтение. |
[EFAULT] | аргумент buf указывает за пределы отведенного процессу адресного пространства. |
[ENOLINK] | аргумент fildes является дескриптором файла на удаленном компьютере, связи с которым в данный момент нет. |
[EIO] | ошибка ввода/вывода |
Системный вызов write (2) осуществляет запись в файл. Синтаксис:
int write (int fildes, char *buf, unsigned nbyte)
Аргумент fildes ‑ это дескриптор файла, полученный после выполнения системных вызовов creat (2), open (2) и некоторых других. Системный вызов write (2) пытается записать nbyte байт из буфера, на который указывает аргумент buf, в файл, ассоциированный с дескриптором fildes.
Для устройств, допускающих позиционирование, системный вызов write выполняет запись в файл, начиная с указателя текущей позиции, ассоциированного с дескриптором fildes. После завершения записи указатель текущей позиции файла увеличивается на количество записанных байт.
Системный вызов write (2) завершается неудачей и указатель текущей позиции файла остается без изменений, если выполнено хотя бы одно из следующих условий (перечень неполный):
[EAGAIN] | общее количество системной памяти, предоставленной для бесструктурного ввода/вывода, временно оказалось недостаточным. |
[EBADF] | аргумент fildes не является корректным дескриптором файла, открытого для записи. |
[EFAULT] | аргумент buf указывает за пределы отведенного процессу адресного пространства. |
[EFBIG] | превышение допустимого размера файлов [см. ulimit(2)]. |
[ENOLINK] | fildes является дескриптором файла на удаленном компьютере, связи с которым в данный момент нет. |
[ENOSPC] | при попытке записи в обычный файл нет свободного места на устройстве. |
[ENXIO] | зависание при записи в поток stream. |
При попытке записать большее количество байт, чем позволяет максимальный размер файла или наличие свободного пространства на устройстве, записывается столько байт, сколько возможно. Например, пусть в файле осталось 20 байт до достижения максимального размера. Тогда попытка записи в этот файл 512 байт приводит к тому, что реально пишется 20 байт и системный вызов write (2) возвращает значение 20. Последующая попытка записи ненулевого количества байт приводит к ошибке.
При успешном завершении результат равен неотрицательному целому числу - количеству реально записанных байт; в случае ошибки возвращается ‑1, а переменной errno присваивается код ошибки
Системный вызов close(2) закрывает файл. Синтаксис:
int close (int fildes)
Аргумент fildes – это дескриптор файла, полученный в результате выполнения системных вызовов creat (2), open (2) и некоторых других. Системный вызов close (2) закрывает этот дескриптор. Последний вызов close для потока, связанного с дескриптором fildes, приводит к ликвидации потока. Системный вызов close завершается неудачей и указанный дескриптор файла не закрывается, если выполнено хотя бы одно из следующих условий:
[EBADF] | аргумент fildes не является корректным дескриптором открытого файла. |
[EINTR] | во время выполнения системного вызова перехвачен сигнал. |
[ENOLINK] | аргумент fildes указывает на удаленный компьютер, связи с которым в данный момент нет. |
При успешном завершении результат равен 0; в случае ошибки возвращается ‑1, а переменной errno присваивается код ошибки.
Дата добавления: 2014-12-15; просмотров: 132 | Поможем написать вашу работу | Нарушение авторских прав |