Hi Pierre-Marie, is this really a good idea? If a directory has millions of
files in it (rare, but I've seen it) this may consume a lot of memory. Also, if
using a slow medium like a network file system, reading the entire directory
contents may take a long time. Finally, you aren't really solving the race
condition, you're just making the window smaller, right? After all, if I
understand right you are still using readdir, you just use it during a shorter
time period.
Best wishes, Duncan.
On 07/01/2022 17:27, Pierre-Marie de Rodat via Gcc-patches wrote:
The Ada.Directories directory search function is changed so the contents
of the directory is now read in Start_Search instead of in
Get_Next_Entry. Start_Search now stores the result of the directory
search in the search object, with Get_Next_Entry returning results from
the search object. This differs from the prior implementation where
Get_Next_Entry would query the directory directly for the next item
using the POSIX readdir function.
The problem with building Get_Next_Entry around the readdir function is
POSIX does not specify the behavior of readdir when files are added or
removed from the directory being read. For example: on most systems,
deleting files from the folder being read does not impact readdir.
However, some systems, like RTEMS and HFS+ volumes on macOS, will return
NULL instead of the next item in the directory if the current item
returned by readdir is deleted.
To avoid this issue, the contents of the directory is read in
Start_Search and the user is given a copy of these results.
Consequently, any subsequent modification to the directory does not
affect the ability to iterate through the results. This approach is the
same taken by the popular fts C functions.
Tested on x86_64-pc-linux-gnu, committed on trunk
gcc/ada/
* libgnat/a-direct.adb (Search_Data): Remove type.
(Directory_Vectors): New package instantiation.
(Search_State): New type.
(Fetch_Next_Entry): Remove.
(Close): Remove.
(Finalize): Rewritten.
(Full_Name): Ditto.
(Get_Next_Entry): Return next entry from Search results vector
rather than querying the directory directly using readdir.
(Kind): Rewritten.
(Modification_Time): Rewritten.
(More_Entries): Use Search state cursor to determine if more
entries are available for users to read.
(Simple_Name): Rewritten.
(Size): Rewritten.
(Start_Search_Internal): Rewritten to load the contents of the
directory that matches the pattern and filter into the search
object.
* libgnat/a-direct.ads (Search_Type): New type.
(Search_Ptr): Ditto.
(Directory_Entry_Type): Rewritten to support new Start_Search
procedure.
* libgnat/s-filatt.ads (File_Length_Attr): New function.