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 _______________________________________________ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal