fcntl

Autres langues

Langue: ru

Autres versions - même langue

Version: 12 July 1999 (fedora - 25/11/07)

Section: 2 (Appels système)

НАЗВАНИЕ

fcntl - манипуляция файловым дескриптором

КРАТКАЯ СВОДКА

 #include <unistd.h>
 #include <fcntl.h>
 
 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 на одном из дескрипторов, то оно также меняется на другом.

Два дескриптора, однако, не делят флаг закрыть-при-exec. У копии этот флаг будет установлен в ноль, означая, что он не будет закрыт при выполнении exec.

При успешном завершении возвращается новый дескриптор.

F_GETFD
Получить состояние флага закрыть-при-exec. Если бит FD_CLOEXEC результата равен нулю, то файл будет оставаться открытым после выполнения exec, в противном случае он закроется.
F_SETFD
Установить флаг закрыть-при-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 не является открытым файловым дескриптором.
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.

СМОТРИ ТАКЖЕ

dup2(2), flock(2), open(2), socket(2),

ПЕРЕВОД

Copyright (C) Alexey Mahotkin <alexm@hsys.msk.ru> 1999