1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
5 -- G N A T . L O C K _ F I L E S --
9 -- Copyright (C) 1998-2017, Free Software Foundation, Inc. --
11 -- GNAT is free software; you can redistribute it and/or modify it under --
12 -- terms of the GNU General Public License as published by the Free Soft- --
13 -- ware Foundation; either version 3, or (at your option) any later ver- --
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE. --
18 -- As a special exception under Section 7 of GPL version 3, you are granted --
19 -- additional permissions described in the GCC Runtime Library Exception, --
20 -- version 3.1, as published by the Free Software Foundation. --
22 -- You should have received a copy of the GNU General Public License and --
23 -- a copy of the GCC Runtime Library Exception along with this program; --
24 -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
25 -- <http://www.gnu.org/licenses/>. --
27 -- GNAT was originally developed by the GNAT team at New York University. --
28 -- Extensive contributions were provided by Ada Core Technologies Inc. --
30 ------------------------------------------------------------------------------
34 package body GNAT
.Lock_Files
is
36 Dir_Separator
: Character;
37 pragma Import
(C
, Dir_Separator
, "__gnat_dir_separator");
44 (Directory
: Path_Name
;
45 Lock_File_Name
: Path_Name
;
46 Wait
: Duration := 1.0;
47 Retries
: Natural := Natural'Last)
49 Dir
: aliased String := Directory
& ASCII
.NUL
;
50 File
: aliased String := Lock_File_Name
& ASCII
.NUL
;
52 function Try_Lock
(Dir
, File
: System
.Address
) return Integer;
53 pragma Import
(C
, Try_Lock
, "__gnat_try_lock");
56 -- If a directory separator was provided, just remove the one we have
59 if Directory
(Directory
'Last) = Dir_Separator
60 or else Directory
(Directory
'Last) = '/'
62 Dir
(Dir
'Last - 1) := ASCII
.NUL
;
65 -- Try to lock the file Retries times
67 for I
in 0 .. Retries
loop
68 if Try_Lock
(Dir
'Address, File
'Address) = 1 then
72 exit when I
= Retries
;
84 (Lock_File_Name
: Path_Name
;
85 Wait
: Duration := 1.0;
86 Retries
: Natural := Natural'Last)
89 for J
in reverse Lock_File_Name
'Range loop
90 if Lock_File_Name
(J
) = Dir_Separator
91 or else Lock_File_Name
(J
) = '/'
94 (Lock_File_Name
(Lock_File_Name
'First .. J
- 1),
95 Lock_File_Name
(J
+ 1 .. Lock_File_Name
'Last),
102 Lock_File
(".", Lock_File_Name
, Wait
, Retries
);
109 procedure Unlock_File
(Lock_File_Name
: Path_Name
) is
110 S
: aliased String := Lock_File_Name
& ASCII
.NUL
;
112 procedure unlink
(A
: System
.Address
);
113 pragma Import
(C
, unlink
, "unlink");
123 procedure Unlock_File
(Directory
: Path_Name
; Lock_File_Name
: Path_Name
) is
125 if Directory
(Directory
'Last) = Dir_Separator
126 or else Directory
(Directory
'Last) = '/'
128 Unlock_File
(Directory
& Lock_File_Name
);
130 Unlock_File
(Directory
& Dir_Separator
& Lock_File_Name
);