Как обычно, аргумент filedes должен
uses linux, stdio;
Procedure Fcntl(filedes:longint; Cmd:longint; ldata: pflockrec);
Как обычно, аргумент filedes должен быть допустимым дескриптором открытого файла. Для блокировки чтения дескриптор filedes должен быть открыт при помощи флагов Open_RDONLY или Open_RDWR, поэтому в качестве него не подойдет дескриптор, возвращаемый вызовом fdcreat. Для блокировки записи дескриптор filedes должен быть открыт при помощи флагов Open_WRONLY или Open_RDWR.
Как уже упоминалось, параметр вызова cmd определяет выполняемое действие, кодируемое одним из значений, определенных в файле linux. Следуют три команды относятся к блокировке записей:
F_GETLK |
Получить описание блокировки на основе данных, передаваемых в аргументе ldata. (Возвращаемая информация описывает первую блокировку, которая препятствует наложению блокировки, описанной структурой ldata) |
F_SETLK |
Попытаться применить блокировку к файлу и немедленно возвратить управление, если это невозможно. Используется также для удаления активной блокировки |
F_SETLKW |
Попытаться применить блокировку к файлу и приостановить работу, если блокировка уже наложена другим процессом. Ожидание процесса внутри вызова fcntl можно прервать при помощи сигнала |
ldata содержит описание блокировки. Структура flockrec определена в файле stdio и включает следующие элементы:
flockrec=record
l_type:word; (*Описывает тип блокировки: F_RDLCK, F_WRLCK, F_UNLCK. *)
l_whence:word; (* Тип смещения, как и в вызове lseek *)
l_start:longint; (* Смещение в байтах *)
l_len:longint; (*Размер сегмента данных; 0 означает до конца файла *)
l_pid:longint; (*Устанавливается командой F_GETLK *)
end;
Три элемента, l_whence, l_start и l_len, определяют участок файла, который будет заблокирован, проверен или разблокирован. Переменная l_whence идентична третьему аргументу вызова lseek. Она принимает одно из трех значений: SEEK_SET, SEEK_CUR или SEEK_END, обозначая, что смещение должно вычисляться от начала файла, от текущей позиции указателя чтения-записи или конца файла. Элемент l_start устанавливает начальное положение участка файла по отношению к точке, заданной элементом l_whence. Элемент l_len является длиной участка в байтах; нулевое значение обозначает участок с заданной начальной позиции до максимально возможного смещения. На рис. 8.1. показано, как это работает для случая, если значение поля l_whence равно SEEK_CUR. Структура tsemid_ds определена в файле linux.
Указатель файла |
||||||||||||||||||||||
| | | | v |
||||||||||||||||||||||
Блокируемый участок |
||||||||||||||||||||||
/ |
\ |
|||||||||||||||||||||
a |
b |
c |
d |
e |
f |
g |
h |
i |
j |
k |
l |
m |
n |
o |
p |
q |
r |
s |
t |
u |
v |
w |
^ | | | |
||||||||||||||||||||||
l_start |
l_len |
|||||||||||||||||||||
<–––––––> |
<–––––––> |
|||||||||||||||||||||
l_whence= SEEK_CUR |
Рис. 8.1. Параметры блокировки
Тип l_type определяет тип блокировки. Он может принимать одно из трех значений, определенных в файле stdio:
F_RDLCK Выполняется блокировка чтения
F_WRLCK Выполняется блокировка записи
F_UNLCK Снимается блокировка заданного участка
Поле l_pid существенно только при выборе команды F_GETLK в вызове fcntl. Если существует блокировка, препятствующая установке блокировки, описанной полями структуры ldata, то значение поля l_pid будет равно значению идентификатора процесса, установившего ее. Другие элементы структуры также будут переустановлены системой. Они будут содержать параметры блокировки, наложенной другим процессом.