[fpc-pascal] (Unix) file locking
Björn Lundin
b.f.lundin at gmail.com
Mon Jun 20 23:15:08 CEST 2016
On 2016-06-20 11:28, Mark Morgan Lloyd wrote:
> I'm approaching a situation where up to four identical processes will be
> reading and writing the same files. There will be process-level
> synchronisation which should prevent clashes, but I'd still like to add
> locking at the file level.
>
> I presume that what I should be looking at is Fcntl(F_SetLk) etc., but
> what is the appropriate API for reading and writing? All access will be
> in fixed-size (256 byte) blocks, and blocks will be aligned.
>
on Linux and AIX I use lockf.
then read() and write() from the os.
However I lock the whole file, but the manpage says it is possible to
lock parts of it.
Here some relevant code (in Ada - sorry) but it's the interesting parts
declare
C_Name : Chars_Ptr := New_String (To_String(A_Lock.Name));
begin
A_Lock.Fd := Posix.Open(C_name, O_WRONLY + O_CREAT , 8#644#);
--O_NONBLOCK is not needed
Free(C_Name);
end;
-- test lock, and lock if unlocked, error if already locked
Result := Posix.Lockf(A_Lock.Fd, F_TLOCK, 0);
-- the last parameter above says how much to lock; 0 = whole file
else seek() and then lock som bytes
if Result = -1 then
Log(Me & "Take", "Take lock failed, Errno =" & Errno'Img);
raise Lock_Error with "Errno =" & Errno'Img ;
end if;
-- file is now locked
--put pid in file
declare
use Interfaces.C;
use Calendar2;
Str : String := Posix.Getpid'img & Ascii.LF);
C_Pid_Str : Chars_Ptr := New_String (Str);
Size : Posix.Size_t;
begin
Size := Posix.Write(A_Lock.Fd, C_Pid_Str, Str'Length);
Free(C_Pid_Str);
if Integer(Size) = -1 then
Log(Me & "Take", "write pid Errno =" & Errno'Img);
end if;
if Integer(Size) /= Str'length then
Log(Me & "Take", "Size/str'length =" & Size'Img &
"/" & Str'Length'Img);
end if;
end;
to unlock it later
Result := Posix.Lockf(A_Lock.Fd, F_ULOCK, 0); --unlock
or just close it
Result := Posix.Close(A_lock.Fd);
--
--
Björn
More information about the fpc-pascal
mailing list