Thank you marcov and ludob, especially for the link.
Well I just can't get locking a region of a file (record locking) to work.
I suspect that FPfcntl() is not returning the correct results.
Please look at the code below and see if you can replicate this problem.
Here is simplified code...
1. Create a file, filedescriptor F1 of 256 bytes, read/write access.
2. Apply a lock from byte 10 to byte 29 with FpFcntl (F1, F_SETLK, Region)
3. Check that a lock exists with Fpfcntl(F1, F_GETLK, Region)
Step 3 should overwrite "region" with the existing lock details including PID.
It does not. It also reports that there is no lock.
Here are code fragements..
STEP 1
uses BaseUnix; //For file flags and TMode
Const
Fn = '/home/laurie/test_lock';
F_RDLCK = 0;
F_WRLCK = 1;
F_UNLCK = 2;
var
F1: Integer; //File descriptor
{$I+}
procedure TForm1.btnOpenFileClick(Sender: TObject);
var i:integer;
begin //create and open file of length 256
If FileExists (Fn) Then DeleteFile (Fn);
F1 := FpOpen (Fn, O_RDWR Or O_CREAT, $1B6); // $1B6 = o666
For I := 0 To 255 Do FpWrite (F1, I, 1);
end;
STEP 2
procedure TForm1.btnSetReadLockClick(Sender: TObject);
Var
Region : FLock;
Begin //Apply read lock from byte 10 to 29
With Region Do Begin
l_type := F_RDLCK; l_whence := SEEK_SET;
l_start := 10; l_len := 20
End;
If FpFcntl (F1, F_SETLK, Region) = -1 Then
Showmessage ('unable to apply read writelock. Extended error='+IntToStr(fpGetErrno)); // <-- OK
end;
STEP 3
procedure TForm1.btnCheckForLockClick(Sender: TObject);
Var
Region : FLock; ret:integer;
Begin //check for a lock on bytes 10 to 29
Region.l_type := F_WRLCK;
Region.l_start := 10;
Region.l_whence := SEEK_SET;
Region.l_len := 20;
Region.l_pid := -1;
ret := Fpfcntl(F1, F_GETLK, Region);
if ret < 0 then begin
ShowMessage('Fpfcntl failed msg:'+IntToStr(fpGetErrno));
exit;
end;
With Region do Case l_type of
F_UNLCK:ShowMessage('file fd= '+IntToStr(F1)+' pid= '+IntToStr(l_pid)+' is unlocked');
F_RDLCK:ShowMessage('file fd= '+IntToStr(F1)+' pid= '+IntToStr(l_pid)+' has a read lock');
F_WRLCK:ShowMessage('file fd= '+IntToStr(F1)+' pid= '+IntToStr(l_pid)+' has a write lock');
end; //case
end;
end.
Step 3 never confirms the presence of a lock and never fills in the correct PID in Region.l_PID.
All help greatly appreciated.
Laurie