|
|
DataMuseum.dkPresents historical artifacts from the history of: Rational R1000/400 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Rational R1000/400 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 11264 (0x2c00)
Types: Ada Source
Notes: 03_class, FILE, R1k_Segment, e3_tag, package body Os_Files, seg_05098c
└─⟦8527c1e9b⟧ Bits:30000544 8mm tape, Rational 1000, Arrival backup of disks in PAM's R1000
└─⟦cfc2e13cd⟧ »Space Info Vol 2«
└─⟦this⟧
-- for UNIX versions
with Io_Exceptions;
use Io_Exceptions;
with File_Support;
use File_Support;
with Os_Variant;
with Unix;
with Libc;
with Unchecked_Conversion;
with Unchecked_Deallocation;
with Strlen;
with A_Strings;
with C_Strings;
with V_I_Bits;
package body Os_Files is
type File_Id_Type is new Os_Variant.File_Id_Type;
Last_Dir_Id : File_Id_Type := (others => 16#FF#);
Last_Dir : C_Strings.C_String_Buf;
Last_Dir_Len : Integer := 0;
Max_Fails : constant Integer := 30;
function To_File_Ptr is new Unchecked_Conversion
(System.Long_Address, File_Ptr);
function "+" (Left, Right : Open_Flags) return Open_Flags is
L : Integer := Integer (Left);
R : Integer := Integer (Right);
T : Integer := 1;
begin
T := V_I_Bits.Bit_Or (L, R);
return Open_Flags (T);
end "+";
function "-" (Left, Right : Open_Flags) return Open_Flags is
L : Integer := Integer (Left);
R : Integer := Integer (Right);
T : Integer := 1;
begin
T := V_I_Bits.Bit_And (L, V_I_Bits.Bit_Neg (R));
return Open_Flags (T);
end "-";
function At_End_Of_File (Fd : File_Descriptor) return Boolean is
Offset : Integer;
Size : Integer := Os_Variant.Get_File_Size (Fd);
begin
Offset := Unix.Lseek (Fd, 0, Unix.L_Incr); -- get current offset
if Offset < 0 then
raise Device_Error;
end if;
return Offset >= Size;
end At_End_Of_File;
function Get_File_Id (Fd : File_Descriptor) return File_Id_Ptr is
begin
return new File_Id_Type'(File_Id_Type
(Os_Variant.Get_File_Id (Fd, "")));
end Get_File_Id;
function Same_Id (F1, F2 : File_Id_Ptr) return Boolean is
begin
if F1 = null or F2 = null then
return False;
end if;
return F1.all = F2.all;
end Same_Id;
function File_Size
(Fd : File_Descriptor; Elem_Size : Integer) return Integer is
begin
return ((Os_Variant.Get_File_Size (Fd) + Elem_Size - 1) / Elem_Size);
end File_Size;
function Is_Interactive (Fd : File_Descriptor) return Boolean is
begin
return Os_Variant.Is_A_Tty (Fd);
end Is_Interactive;
procedure Position_File (Fd : File_Descriptor; To, Size : Integer) is
Result : Unix.Offset;
begin
Result := Unix.Lseek (Fd, (To - 1) * Size, Unix.L_Set);
end Position_File;
procedure Skip_In_File (Fd : File_Descriptor; To : Integer) is
Result : Unix.Offset;
begin
Result := Unix.Lseek (Fd, To, Unix.L_Incr);
end Skip_In_File;
function Read (Fd : File_Descriptor;
Addr : System.Long_Address;
Cnt : Integer) return Integer is
Count : Integer;
Local_Addr : System.Address := System.Localize
(Addr, Cnt * System.Storage_Unit);
begin
loop
Count := Unix.Read (Fd, Local_Addr, Cnt);
exit when Count /= Unix.Error;
exit when Unix."/=" (Unix.Errnum, Unix.Eintr);
end loop;
return Count;
end Read;
procedure Sleep (Seconds : Integer);
pragma Interface (C, Sleep);
procedure Write (Fd : File_Descriptor;
Addr : System.Long_Address;
Cnt : Integer) is
Max_Fails : constant Integer := 30;
Actual : Integer;
Remaining : Integer := Cnt;
Buf : System.Address := System.Localize
(Addr, Cnt * System.Storage_Unit);
Fails : Integer := 0;
begin
loop
loop
Actual := Unix.Write (Fd, Buf, Remaining);
exit when Actual /= Unix.Error;
exit when Unix."/=" (Unix.Errnum, Unix.Eintr);
end loop;
exit when Actual = Remaining or else Remaining <= 0;
Os_Variant.Try_Waiting (Fails, Fd);
if not Is_Interactive (Fd) or Fails > Max_Fails then
raise Device_Error;
end if;
Remaining := Remaining - Actual;
Buf := Buf + Actual;
end loop;
end Write;
procedure Open (File : System.Long_Address;
Style : File_Styles;
Mode : Open_Flags) is
This_File : File_Ptr := To_File_Ptr (File);
Fd : File_Descriptor;
C_Name : C_Strings.C_String_Buf;
C_File_Name : C_Strings.C_String;
Cvt_Mode : Os_Variant.Open_Flags := Os_Variant.Cvt_Open_Flags (Mode);
begin
if Style = Special then
if This_File.Name.S = "stdin" then
Fd := File_Descriptor (0);
Os_Variant.Condition_Stdin (Stdin_Fd, Cvt_Mode);
elsif This_File.Name.S = "stdout" then
Fd := File_Descriptor (1);
else
Fd := File_Descriptor (2);
end if;
else
C_File_Name := C_Strings.To_C (This_File.Name, C_Name'Address);
loop
Fd := Unix.Open (C_File_Name, Cvt_Mode);
exit when Fd /= File_Descriptor (-1);
case Unix.Errnum is
when Unix.Eintr =>
null; -- try again.
when Unix.Enoent | Unix.Enotdir | Unix.Enametoolong =>
raise Name_Error;
when others =>
raise Use_Error;
end case;
end loop;
end if;
This_File.Fd := Fd;
This_File.File_Id :=
new File_Id_Type'(File_Id_Type (Get_File_Id (Fd, This_File.Name.S))); end Open;
procedure Close (Fd : File_Descriptor) is
Ignore : Unix.Status_Code;
begin
Ignore := Unix.Close (Fd);
end Close;
procedure Truncate (Fd : File_Descriptor) is
begin
if Unix.Ftruncate (Fd, 0) /= 0 then
raise Device_Error;
end if;
end Truncate;
procedure Delete (Fd : File_Descriptor; Name : A_Strings.A_String) is
Ignore : Unix.Status_Code;
C_Name : String (1 .. 1024);
begin
Ignore := Unix.Unlink (C_Strings.To_C (Name, C_Name'Address));
end Delete;
procedure Getdir (Path : in out String; Length : out Integer) is
Cwd_Id : Os_Variant.File_Id_Type;
begin
-- check to see if we're in the same dir, so no heap will be used
Cwd_Id := Os_Variant.Get_File_Id
(File_Descriptor (-1), "." & Ascii.Nul);
if File_Id_Type (Cwd_Id) /= Last_Dir_Id then
Last_Dir_Id := File_Id_Type (Cwd_Id);
Unix.Getcwd (Last_Dir);
Last_Dir_Len := Strlen (Last_Dir'Address) + 1;
Last_Dir (Last_Dir_Len) := '/';
end if;
if Last_Dir_Len > Path'Length then
Length := -1;
else
Length := Last_Dir_Len;
Path (1 .. Last_Dir_Len) := Last_Dir (1 .. Last_Dir_Len);
end if;
end Getdir;
function Get_Tempname (Root : String) return A_Strings.A_String is
Tname : constant String := Unix.Get_Temp_Name ("/tmp/" & Root);
begin
return A_Strings.To_A (Tname (Tname'First .. Tname'Last - 1));
end Get_Tempname;
function Get_Full_Name (Name : String; Style : File_Styles)
return A_Strings.A_String is
Name_Length : Integer := Name'Length;
Length : Integer;
Temp : Name_String;
Result : A_Strings.A_String;
begin
if Name_Length = 0 then
return Get_Tempname ("adatmp");
elsif Name (Name'First) /= '/' and then Style /= Special then
Getdir (Temp, Length);
Temp (Temp'First + Length ..
Temp'First + Length + Name_Length - 1) := Name;
Length := Length + Name_Length;
else
Temp (1 .. Name_Length) := Name;
Length := Name_Length;
end if;
Result := new A_Strings.String_Rec (Length);
Result.S (1 .. Length) := Temp (1 .. Length);
return Result;
end Get_Full_Name;
function Std_Input_Name return String is
begin
return "stdin";
end Std_Input_Name;
function Std_Output_Name return String is
begin
return "stdout";
end Std_Output_Name;
function Std_Error_Name return String is
begin
return "stderr";
end Std_Error_Name;
procedure Fix_End_Of_Record
(File : System.Long_Address; Actual : in out Integer) is
begin
null;
end Fix_End_Of_Record;
function Ok_To_Write (File : System.Long_Address) return Boolean is
begin
return True;
end Ok_To_Write;
procedure Free is new Unchecked_Deallocation (File_Id_Type, File_Id_Ptr);
procedure Free_File_Id (Id_Ptr : in out File_Id_Ptr) is
begin
Free (Id_Ptr);
end Free_File_Id;
function Flushable (Fd : File_Descriptor) return Boolean is
begin
return True;
end Flushable;
begin
Stdin_Fd := File_Descriptor (0);
Stdout_Fd := File_Descriptor (1);
Stderr_Fd := File_Descriptor (2);
Always_Flush_Files := False;
end Os_Files;
nblk1=a
nid=0
hdr6=14
[0x00] rec0=28 rec1=00 rec2=01 rec3=066
[0x01] rec0=1d rec1=00 rec2=02 rec3=034
[0x02] rec0=1f rec1=00 rec2=03 rec3=012
[0x03] rec0=1c rec1=00 rec2=04 rec3=028
[0x04] rec0=19 rec1=00 rec2=05 rec3=004
[0x05] rec0=18 rec1=00 rec2=06 rec3=002
[0x06] rec0=1d rec1=00 rec2=07 rec3=04c
[0x07] rec0=1b rec1=00 rec2=08 rec3=03a
[0x08] rec0=1f rec1=00 rec2=09 rec3=08c
[0x09] rec0=1b rec1=00 rec2=0a rec3=000
tail 0x217580150878e792a8f64 0x42a00088462060003