[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

      C_Name : Chars_Ptr := New_String (To_String(A_Lock.Name));
      A_Lock.Fd := Posix.Open(C_name, O_WRONLY + O_CREAT , 8#644#);
      --O_NONBLOCK is not needed

-- 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

      use Interfaces.C;
      use Calendar2;
      Str : String := Posix.Getpid'img  & Ascii.LF);
      C_Pid_Str : Chars_Ptr := New_String (Str);
      Size      : Posix.Size_t;
      Size := Posix.Write(A_Lock.Fd, C_Pid_Str, Str'Length);
      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;

to unlock it later

      Result := Posix.Lockf(A_Lock.Fd, F_ULOCK, 0); --unlock

or just close it
      Result := Posix.Close(A_lock.Fd);


More information about the fpc-pascal mailing list