DataMuseum.dk

Presents historical artifacts from the history of:

Rational R1000/400

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about Rational R1000/400

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download

⟦6943c01b4⟧ Ada Source

    Length: 11264 (0x2c00)
    Types: Ada Source
    Notes: 03_class, FILE, R1k_Segment, e3_tag, package body Os_Files, seg_05098c

Derivation

└─⟦8527c1e9b⟧ Bits:30000544 8mm tape, Rational 1000, Arrival backup of disks in PAM's R1000
    └─ ⟦cfc2e13cd⟧ »Space Info Vol 2« 
        └─⟦this⟧ 

E3 Source Code




-- 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;

E3 Meta Data

    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