fcntl - функция для работы с файловыми описателями
НАЗВАНИЕfcntl - функция для работы с файловыми описателями
СИНТАКСИС
#include
#include
int fcntl(int fd, int cmd);
int fcntl(int fd, int cmd, long arg);
int fcntl(int fd, int cmd, struct flock * lock);
ОПИСАНИЕ
fcntl выполняет различные операции над файловым описателем
fd. Рассматриваемая операция определяется значением cmd:
F_DUPFD ищет первый доступный файловый описатель, больший
или равный значению arg, и делает его копией fd.
Это поведение отличается от поведения функции
dup2(2), которая использует именно заданный
файловый описатель.
Старый и новый описатели могут заменять друг
друга. У них общие блокировки, общее положение
указателя в файле и флаги; например, если
положение указателя изменяется с помощью lseek в
одном из описателей, то оно также меняется в
другом.
Два описателя, однако, не делят флаг "close-on-
exec". В копии значение этого флага будет равно
нулю; это значит, что он не будет закрыт при
запуске exec.
При успешном завершении работы возвращается новый
описатель.
F_GETFD Получить состояние флага "close-on-exec". Если
бит FD_CLOEXEC результата равен нулю, то файл
будет оставаться открытым после выполнения exec,
в противном случае файл будет закрыт.
F_SETFD Установить флаг "close-on-exec", как указано в
бите FD_CLOEXEC параметра arg.
F_GETFL Прочитать флаги описателя (возвращаются все
флаги, установленные при помощи open(2)).
F_SETFL Установить значение флагов описателя, заданное в
arg. Можно установить только флаги O_APPEND,
O_NONBLOCK и O_ASYNC (прочие флаги не будут
затронуты).
Флаги являются общими для копий файлового
описателя, сделанных с помощью dup(2), fork(2) и
т.п.
Флаги и их семантика описаны в open(2).
F_GETLK, F_SETLK и F_SETLKW используются для управления
файловыми блокировками. Третий аргумент, lock, указывает
на структуру struct flock (которая может быть перезаписана
этим системным вызовом).
F_GETLK
Возвращает структуру flock, которая препятствует
своей собственной блокировке или установке значения
поля l_type равным F_UNLCK, если других блокировок
нет.
F_SETLK
Блокировка устанавливается (если поле l_type равно
F_RDLCK или F_WRLCK) или снимается (если это поле
равно F_UNLCK). Если блокировка установлена кем-то
ещё, этот вызов возвращает значение -1 и
устанавливает значение errno равным EACCESS или
EAGAIN.
Значение
F_SETLKW аналогично F_SETLK, только вместо того,
чтобы вернуть код ошибки, пользователь ждет снятия
блокировки. Если во время ожидания к Вам приходит
соответствующий
сигнал, то системный вызов прерывается и, после
того, как обработан сигнал, значение -1 немедленно
возвращается, а значение errno становится равным
EINTR.
F_GETOWN, F_SETOWN, F_GETSIG и F_SETSIG используются для
управления сигналами о доступности ввода/вывода:
F_GETOWN
Получает идентификатор процесса или группы
процессов, к которым посылаются сигналы SIGIO и
SIGURG о событиях в файловом описателе fd.
Возвращаемое значение группы процессов становится
отрицательным.
F_SETOWN
Устанавливает идентификатор процесса или группы
процессов, которые будут получать сигналы SIGIO и
SIGURG о событиях в файловом описателе fd.
Значение групп процессов становится отрицательным.
(F_SETSIG может использоваться для задания другого
сигнала вместо SIGIO). Если Вы установите флаг
O_ASYNC в файловом описателе (передав этот флаг при
вызове open(2) или задав команду F_SETFL при вызове
fcntl), то сигнал SIGIO будет посылаться каждый
раз, когда в этом файловом описателе становится
возможым ввод и вывод.
Процесс или группа процессов, которые будут
получать сигнал, могут быть выбраны с помощью
команды F_SETOWN, заданной функцией fcntl. Если
файловый описатель - это сокет, то при этом будет
также выбран адресат сигналов SIGURG, которые
посылаются, когда на сокет приходят данные из
пространства вне основного канала. (SIGURG
отсылается в любой ситуации, когда функция
select(2) сообщает о сложившейся в сокете
"исключительной ситуации".) Если файловый
описатель соответствует терминальному устройству,
то сигналы
SIGIO посылаются группе нефоновых процессов на
терминале.
F_GETSIG
Дает возможность узнать, какой сигнал посылается,
когда становится возможным ввод или вывод. Ноль
означает, что посылается SIGIO. Любое другое
значение (включая SIGIO) - это сигнал, который
посылается вместо SIGIO (в этом случае доступна
дополнительная информация, если обработчик сигнала
был установлен с помощью функции SA_SIGINFO).
F_SETSIG
Задает сигнал, который посылается, когда становится
возможным ввод или вывод информации. Значение
"ноль" показывает, что нужно посылать стандартный
сигнал SIGIO. Любое другое значение (включая SIGIO)
означает, что нужно послать другой сигнал, и в этом
случае также доступна дополнительная информация,
если обработчик сигнала был установлен с помощью
SA_SIGINFO.
Используя F_SETSIG вместе с ненулевым значением и
предоставляя обработчику сигнала флаг SA_SIGINFO
(см. sigaction(2)), можно передать этому
обработчику дополнительную информацию о событиях
ввода-вывода с помощью структуры siginfo_t. Если в
поле si_code указано, что источником является
SI_SIGIO, то поле si_fd содержит файловый
описатель, в котором произошло событие. В
противном случае нет прямого указания, какие именно
файловые
описатели участвуют в происходящем, поэтому нужно
использовать обычные механизмы (select(2), poll(2),
read(2) с флагом O_NONBLOCK, и так далее), чтобы
определить, каким описателям доступен процесс
ввода-вывода.
Выбрав сигнал реального времени, соответствующий
стандарту POSIX (значение >= SIGRTMIN), можно
работать с очередями событий ввода-вывода,
использующих один и тот же номер сигнала.
(Построение очереди зависит от доступной памяти).
Дополнительная информация доступна, если
обработчику предоставлен SA_SIGINFO, как описано
выше.
При помощи этих механизмов можно реализовать полностью
асинхронный ввод-вывод без использования, по большей
части, select(2) или poll(2).
Использование O_ASYNC, F_GETOWN, F_SETOWN специфично для
систем BSD и Linux. F_GETSIG и F_SETSIG специфичны для
Linux. POSIX включает в себя описание асинхронного
ввода-вывода и структуру aio_sigevent, с помощью которой
достигаются эти цели; они также доступны в Linux как
часть библиотеки GNU C (Glibc).
ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При успешном завершении работы возвращаемое значение
зависит от того, как действуют следующие установки:
F_DUPFD (новый описатель);
F_GETFD (значение флага);
F_GETFL (значение флагов);
F_GETOWN (владелец описателя);
F_GETSIG (номер сигнала, который посылается, когда
появляется возможность чтения или записи, или же
ноль, означающий традиционное поведение сигнала
SIGIO).
При задании всех остальных команд возвращаемое значение
равно нулю, а при ошибке оно равно -1; а переменной errno
присваивается соответствующий код ошибки.
КОДЫ ОШИБОК
EACCES Выполнение операции невозможно из-за блокировки,
установленной другим процессом.
EAGAIN Операция запрещена, потому что файл был записан в
память другим процессом.
EBADF fd не является открытым файловым описателем или
командой была F_SETLK или F_SETLKW и режим
открытия файлового описателя не совпадает с типом
запрошенной блокировки.
EDEADLK Обнаружено, что заданная команда F_SETLKW вызовет
"мертвую" блокировку.
EFAULT lock указывает на каталог за пределами доступного
адресного пространства.
EINTR Выполнение команды F_SETLKW было прервано
сигналом. Выполнение команд F_GETLK и F_SETLK
было прервано сигналом, пока блокировка еще не
была проверена или
установлена. Это чаще всего случается при
блокировке сетевого файла (например, при работе с
NFS), но иногда может случиться и локально.
EINVAL Ошибка команды F_DUPFD: arg отрицателен или
значение его больше, чем максимально разрешенное.
Команда F_SETSIG: arg не является разрешенным
номером сигнала.
EMFILE Команда F_DUPFD: процесс уже открыл максимальное
количество файловых описателей.
ENOLCK слишком много сегментов заблокировано, заполнена
таблица блокировок или же произошла ошибка при
сетевой блокировке (при работе с NFS).
EPERM Попытка сбросить флаг O_APPEND с файла, имеющего
атрибут "только добавление".
ЗАМЕЧАНИЯ
Коды ошибок, которые возвращает dup2, отличаются от тех,
которые возвращает F_DUPFD.
СООТВЕТСТВИЕ СТАНДАРТАМ
SVr4, SVID, POSIX, X/OPEN, BSD 4.3. В POSIX.1 указаны
только операции F_DUPFD, F_GETFD, F_SETFD, F_GETFL,
F_SETFL, F_GETLK, F_SETLK и F_SETLKW. F_GETOWN и F_SETOWN
являются специфичными для BSD, которые не поддерживаются в
SVr4; F_GETSIG и F_SETSIG специфичны для Linux. Флаги для
F_GETFL/F_SETFL - это флаги, которые поддерживаются
вызовом open(2), и они отличаются в разных системах;
O_APPEND, O_NONBLOCK, O_RDONLY и O_RDWR указаны в POSIX.1.
SVr4 поддерживает несколько других опций и флагов, не
описанных здесь.
SVr4 описывает дополнительные коды ошибок EIO, ENOLINK и
EOVERFLOW.