-
+ 4747969B6DF8AA268419F3259A757D1FEE33B8B4A7D440B8ADFE07C7F6335060B533791908FF1F5022ECFB51708277A59B0876812C4343E17DF1F3F0DE0EA767vtools/src/temporary_file.adb(0 . 0)(1 . 71)
13 with Bits; use Bits;
14 with System; use System;
15 with SMG_Keccak; use SMG_Keccak;
16
17 package body Temporary_File is
18 -- Create a new file or exit when the file with specified name exists.
19 -- Use fopen(3) with "x" mode to create the file or error out if it
20 -- already exists.
21 subtype File_Ptr is System.Address;
22 subtype C_String is System.Address;
23
24 function fopen (Path: C_String;
25 Mode: C_String) return File_Ptr;
26 pragma Import (C, fopen);
27
28 procedure fclose (Stream: File_Ptr);
29 pragma Import (C, fclose);
30
31 function Create_File_Exclusive(Path: String) return Boolean is
32 Fptr: File_Ptr;
33 begin
34 declare
35 XP : aliased String := Path & ASCII.NUL;
36 XM : aliased String := "wx" & ASCII.NUL;
37 begin
38 Fptr := fopen(XP'Address, XM'Address);
39 end;
40 if Fptr = System.Null_Address then
41 return False;
42 end if;
43 fclose(Fptr);
44 return True;
45 end Create_File_Exclusive;
46
47 -- Create a temporary file with a randomly generated name;
48 -- if the file with random component F exists, retry with
49 -- H(F) as a new random component.
50 Function Temporary_File(Path_Prefix: String;
51 Seed: Bitstream) return String is
52 Hash: Bitstream(1..64*8);
53 Name_Ctx: Keccak_Context;
54
55 procedure Hash_Bitstream(Input: Bitstream) is
56 begin
57 KeccakBegin(Name_Ctx);
58 KeccakHash(Name_Ctx, Input);
59 KeccakEnd(Name_Ctx, Hash);
60 end Hash_Bitstream;
61 begin
62 Hash_Bitstream(Seed);
63 loop
64 declare
65 File_Name: String := Path_Prefix & ToHex(Hash);
66 begin
67 if Create_File_Exclusive(File_Name) then
68 return File_Name;
69 end if;
70 end;
71 Hash_Bitstream(Hash);
72 end loop;
73 end Temporary_File;
74
75 function Temporary_File(Path_Prefix: String;
76 Seed: String) return String is
77 B: Bitstream(1..Seed'Length*8);
78 begin
79 ToBitstream(Seed, B);
80 return Temporary_File(Path_Prefix, B);
81 end Temporary_File;
82
83 end Temporary_File;