LOCKF(3C)
НАЗВАНИЕ
lockf - блокировка сегментов файла
СИНТАКСИС
#include <unistd.h>
int lockf (fildes, function, size)
long size;
int fildes, function;
ОПИСАНИЕ
Функция lockf позволяет блокировать отдельные сегменты
файла. Учитывать ли блокировку при записи, определяется
режимом доступа к файлу [см. chmod(2)]. Если другие
процессы попытаются блокировать уже заблокированный
фрагмент, они либо получат в ответ код ошибки, либо будут ждать освобождения ресурса. При завершении процесса
все блокировки, установленные им, удаляются. Более подробная информация о блокировке приведена в fcntl(2).
Аргумент fildes - это дескриптор открытого файла. Чтобы
функция lockf завершилась успешно, файл должен быть
открыт с правом записи (O_WRONLY или O_RDWR).
Аргумент function - это значение, задающее вполняемые
действия. Допустимые значения определены во включаемом
файле <unistd.h>:
#define F_ULOCK 0 /* Разблокировать ранее блокированный
сегмент */
#define F_LOCK 1 /* Заблокировать сегмент */
#define F_TLOCK 2 /* Проверить и заблокировать сегмент */
#define F_TEST 3 /* Проверить сегмент */
Другие значения function зарезервированы для будущих
расширений и приводят к ошибке, если не реализованы.
Значение F_TEST используется для определения того, не
блокирован ли соответствующий сегмент файла каким-нибудь другим процессом. F_LOCK и F_TLOCK блокируют указанный сегмент, если это возможно. F_ULOCK разблокирует
ранее блокированный сегмент.
Аргумент size задает количество последовательных байт
файла, которые должны быть заблокированы или разблокированы. Началом сегмента является текущая позиция в
файле; сегмент распространяется вперед или назад по
файлу, в зависимости от положительного или отрицательного значения size (при распространении назад текущая
позиция не включается в блокируемую или разблокируемую
область). Если значение size равно 0, блокируется (или
разблокируется) сегмент от текущей позиции до конца
файла (текущего и любого будущего). Блокируемый сегмент
не обязан существовать в файле, допустима блокировка
областей за концом файла.
Сегменты, блокируемые посредством F_LOCK и F_TLOCK, могут полностью или частично пересекаться с сегментами,
ранее блокированными тем же процессом. При обнаружении
такого пересечения, а также при обнаружении смежных
сегментов, создается один блокируемый сегмент, охватывающий все смежные байты. Если при блокировании создается новый блокируемый сегмент, он заносится в таблицу
блокировок; при нехватке места в этой таблице обращение
к lockf завершается неудачей и блокировка не устанавливается.
Запросы F_LOCK и F_TLOCK отличаются только действиями,
которые производятся в случае, если блокировку осуществить невозможно. F_LOCK приводит к ожиданию освобождения ресурса. Запрос F_TLOCK, если сегмент уже блокирован другим процессом, приводит к возврату значения -1 и
присваивания переменной errno значения EACCES.
Запрос F_ULOCK может полностью или частично разблокировать один или более сегментов, заблокированных вызывающим процессом. Если сегмент разблокируется не полностью, остаток остается блокированным. Разблокирование
середины сегмента требует дополнительного элемента в
таблице блокировок. При нехватке места в этой таблице
происходит неудача, переменной errno присваивается значение EDEADLK и разблокировка не производится.
Если процесс, захвативший ресурс, ждет освобождения
другого ресурса другим процессом, может возникнуть тупик, поэтому lockf и fcntl контролируют возможность образования тупика, прежде чем начать ожидание ресурса.
Если обнаруживается, что ожидание ресурса вызовет тупик, выдается ошибка.
Ожидание ресурса может быть прервано произвольным сигналом. Для применений, в которых требуется временной
контроль, рекомендуется пользоваться системным вызовом
alarm(2).
Функция lockf завершается неудачей, если выполнено хотя
бы одно из следующих условий:
[EBADF] | Аргумент fd не является корректным дескриптором открытого файла.
|
---|
[EACCES] | Значение function равно F_TLOCK или F_TEST,
а сегмент уже блокирован другим процессом.
|
---|
[EDEADLK] | Значение function равно F_LOCK и может создаться тупик, или значение function равно
F_LOCK, F_TLOCK или F_ULOCK, а в таблице
блокировок не хватает места.
|
---|
[ECOMM] | Fildes является дескриптором файла на удаленном компьютере, связи с которым в данный
момент нет.
|
---|
СМ. ТАКЖЕ
chmod(2), close(2), creat(2), fcntl(2), intro(2),
open(2), read(2), write(2).
ДИАГНОСТИКА
При успешном завершении результат равен 0; в случае
ошибки возвращается -1, а переменной errno присваивается код ошибки.
ПРЕДОСТЕРЕЖЕНИЯ
Для процесса, который занимается буферизацией ввода/вывода в адресном пространстве пользователя, результаты
взаимодействия с механизмом блокировки могут оказаться
непредсказуемыми: запись в заблокированный сегмент
пройдет нормально, зато потом запись совсем в другое
место может привести к ошибке из-за выталкивания буферов. Главным источником неожиданной буферизации является стандартный пакет ввода/вывода.
Так как в будущем переменной errno будет присваиваться
значение EAGAIN, вместо значения EACCES в случае, если
сегмент файла уже блокирован другим процессом, для достижения мобильности прикладных программ следует ожидать
и обрабатывать оба кода ошибки.