DataMuseum.dkPresents historical artifacts from the history of: Rational R1000/400 Tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Rational R1000/400 Tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - downloadIndex: ┃ B T ┃
Length: 36973 (0x906d) Types: TextFile Names: »B«
└─⟦afbc8121e⟧ Bits:30000532 8mm tape, Rational 1000, MC68020_OS2000 7_2_2 └─ ⟦77aa8350c⟧ »DATA« └─⟦f794ecd1d⟧ └─⟦4c85d69e2⟧ └─⟦this⟧
-- The use of this system is subject to the software license terms and -- conditions agreed upon between Rational and the Customer. -- -- Copyright 1988 by Rational. -- -- RESTRICTED RIGHTS LEGEND -- -- Use, duplication, or disclosure by the Government is subject to -- restrictions as set forth in subdivision (b)(3)(ii) of the Rights in -- Technical Data and Computer Software clause at 52.227-7013. -- -- -- Rational -- 3320 Scott Boulevard -- Santa Clara, California 95054-3197 -- -- PROPRIETARY AND CONFIDENTIAL INFORMATION OF RATIONAL; -- USE OR COPYING WITHOUT EXPRESS WRITTEN AUTHORIZATION -- IS STRICTLY PROHIBITED. THIS MATERIAL IS PROTECTED AS -- AN UNPUBLISHED WORK UNDER THE U.S. COPYRIGHT ACT OF -- 1976. CREATED 1988. ALL RIGHTS RESERVED. -- -- with Os2000_Io; with Buffering; with Primitive_Io; with Io_Exceptions; with Io_Exception_Flavors; with Unchecked_Deallocation; with Unchecked_Conversion; package body Os_Dependent_Io is package Dio renames Device_Independent_Io; function "=" (X, Y : File_Kind) return Boolean renames Dio."="; function "=" (X, Y : File_Mode) return Boolean renames Dio."="; function "=" (X, Y : Os2000_Io.Path_Number) return Boolean renames Os2000_Io."="; subtype Byte is System_Types.Byte; function "=" (X, Y : Byte) return Boolean renames System_Types."="; subtype User_Kind is File_Kind range Dio.Normal .. Dio.Temporary; subtype Standard_Kind is File_Kind range Dio.Standard_Input .. Dio.Standard_Error; subtype String_Ptr is System_Types.Acc_Str; function "=" (X, Y : String_Ptr) return Boolean renames System_Types."="; Ptr_To_Empty : constant String_Ptr := new String'(""); function Cnvt is new Unchecked_Conversion (Source => String_Ptr, Target => Integer); type A is array (1 .. 6) of Integer; type T is access A; function Revt is new Unchecked_Conversion (Source => Integer, Target => T); function Convert_Control_Block_To_Address is new Unchecked_Conversion (Source => Os_Control_Block, Target => System.Address); function Convert_Address_To_Control_Block is new Unchecked_Conversion (Source => System.Address, Target => Os_Control_Block); package User is type Id is private; function Get_Current_Key return Id; pragma Suppress (Elaboration_Check, Get_Current_Key); function Not_Current (Key : Id) return Boolean; pragma Suppress (Elaboration_Check, Not_Current); function Less_Than (X, Y : Id) return Boolean; pragma Suppress (Elaboration_Check, Less_Than); function "<" (X, Y : Id) return Boolean renames Less_Than; function Image (Key : Id) return String; pragma Suppress (Elaboration_Check, Image); private type Id is record Value1 : Integer; Value2 : Integer; Value3 : Integer; end record; end User; function "=" (X, Y : User.Id) return Boolean renames User."="; type User_Node; type User_Link is access User_Node; type User_Node is record Key : User.Id; Path : Os2000_Io.Path_Number; Next : User_Link; end record; type Control_Block (For_Kind : File_Kind := Device_Independent_Io.Normal) is record Path : Os2000_Io.Path_Number; Is_Interactive : Boolean; Last_Key : User.Id; Position : Os2000_Io.File_Position; User_List : User_Link; case For_Kind is when User_Kind => Name : String_Ptr; -- external name, null terminated Form : String_Ptr; -- external form Mode_Bits : Natural; when Standard_Kind => null; end case; end record; -- type Io_Operation is (Create_Op, Open_Op, Close_Op, Delete_Op, -- Read_Op, Readln_Op, Write_Op, Seek_Op, -- Get_Pos_Op, Eof_Op, Size_Op, Get_Option_Op); type Io_Operation is new Integer; Create_Op : constant Io_Operation := 0; Open_Op : constant Io_Operation := 1; Close_Op : constant Io_Operation := 2; Delete_Op : constant Io_Operation := 3; Read_Op : constant Io_Operation := 4; Readln_Op : constant Io_Operation := 5; Write_Op : constant Io_Operation := 6; Seek_Op : constant Io_Operation := 7; Get_Pos_Op : constant Io_Operation := 8; Eof_Op : constant Io_Operation := 9; Size_Op : constant Io_Operation := 10; Get_Option_Op : constant Io_Operation := 11; subtype Access_Op is Io_Operation range Create_Op .. Open_Op; Null_Path : constant Os2000_Io.Path_Number := Os2000_Io.Standard_Error; Interactive_Buffer_Size : constant Natural := 400; -- large enough to hold max size enum literal plus reasonable formatting package Unique_Temp_Name is function Get return String; pragma Suppress (Elaboration_Check, Get); end Unique_Temp_Name; procedure Convert_Error (Status : Os2000_Io.Stratus; In_Op : Io_Operation); pragma Suppress (Elaboration_Check, Convert_Error); package Form_Handling is type Option is (Non_Sharable, Sharable); -- The only values currently supported for the Form parameter are: -- -- NON_SHARABLE - Causes the file to be accessed in single-user -- mode; default for Out and Inout mode. -- SHARABLE - Causes the file to be accessed for sharable -- use; default for In mode. function Sharable (Form : String; Mode : Dio.File_Mode) return Boolean; function Default_Image (Form : String; Mode_Bits : Natural) return String; end Form_Handling; procedure Free is new Unchecked_Deallocation (Control_Block, Os_Control_Block); procedure Free is new Unchecked_Deallocation (User_Node, User_Link); procedure Free is new Unchecked_Deallocation (String, String_Ptr); -- procedure Trace -- (S : String; -- Absorb_Output : Boolean := Primitive_Io.Global_Absorb_Output) -- renames Primitive_Io.Put_Line; Delete_Temp_Files : Boolean renames Primitive_Io.Global_Absorb_Output; package body User is separate; package body Unique_Temp_Name is separate; package body Form_Handling is separate; procedure Convert_Error (Status : Os2000_Io.Stratus; In_Op : Io_Operation) is separate; procedure Release (Tree : in out User_Link) is Next : User_Link := Tree; Temp : User_Link; begin while Next /= null loop Temp := Next.Next; Free (Next); Next := Temp; end loop; end Release; procedure Release (Cb : in out Os_Control_Block) is begin if Cb /= null then -- Trace ("Odi.Release - release user tree"); Release (Cb.User_List); case Cb.For_Kind is when User_Kind => -- Trace ("Odi.Release - free name"); Free (Cb.Name); if Cb.Form /= Ptr_To_Empty then -- Trace ("Odi.Release - free form"); Free (Cb.Form); end if; when Standard_Kind => null; end case; Free (Cb); end if; end Release; function Compute_Mode_Bits (Mode : File_Mode; Form : String) return Natural is Bits : Natural; begin case Mode is when Dio.Closed => return 0; when Dio.In_File => Bits := Os2000_Io.Read_Mode; when Dio.Inout_File => Bits := Os2000_Io.Update_Mode; when Dio.Out_File => Bits := Os2000_Io.Write_Mode; end case; if Form_Handling.Sharable (Form, Mode) then return Bits; else -- Due to record locking in OS9 2.1, an attempts -- to use a file when another process has it open -- for write will hang; so making it Single_User will -- cause Use_Error when the second process opens it. return Bits + Os2000_Io.Single_User; end if; end Compute_Mode_Bits; function Compute_Attribute_Bits (Mode : File_Mode; Form : String) return Natural is begin return Os2000_Io.Updatable + Os2000_Io.Public_Updatable; end Compute_Attribute_Bits; function Initial_Control_Block (Name : String; Form : String; Kind : File_Kind; Mode_Bits : Natural) return Os_Control_Block is New_Cb : Os_Control_Block; My_Key : User.Id := User.Get_Current_Key; begin -- Trace ("Odi.Initial_Control_Block"); New_Cb := new Control_Block (For_Kind => Kind); New_Cb.Path := Null_Path; New_Cb.Last_Key := My_Key; New_Cb.User_List := new User_Node'(Key => My_Key, Path => Null_Path, Next => null); New_Cb.Position := Os2000_Io.Null_Position; case Kind is when User_Kind => -- Trace ("Odi.Initial_Control_Block - allocating name"); New_Cb.Name := new String'(Name & Ascii.Nul); if Form'Length > 0 then New_Cb.Form := new String'(Form); else New_Cb.Form := Ptr_To_Empty; end if; New_Cb.Mode_Bits := Mode_Bits; when Dio.Standard_Input => New_Cb.Path := Os2000_Io.Standard_In; when Dio.Standard_Output => New_Cb.Path := Os2000_Io.Standard_Out; when Dio.Standard_Error => New_Cb.Path := Os2000_Io.Standard_Error; end case; -- Trace ("Odi.Initial_Control_Block - successful"); return New_Cb; exception when Storage_Error => -- Trace ("Odi.Initial_Control_Block - Storage_Error"); Release (New_Cb); raise Storage_Error; end Initial_Control_Block; function Strip_Nul (S : String) return String is begin return S (S'First .. S'Last - 1); end Strip_Nul; procedure Set_Initial_Path (Ctrl : Os_Control_Block; Path : Os2000_Io.Path_Number) is begin Ctrl.Path := Path; Ctrl.User_List.Path := Path; end Set_Initial_Path; procedure Set_Interactive (Ctrl : Os_Control_Block) is Option_Buffer : Byte_String (1 .. 128); Result : Os2000_Io.Stratus; Class_Index : constant Natural := 1; -- device class is first byte of option table Scf_Class : constant Byte := 0; -- sequential character Rbf_Class : constant Byte := 1; -- random block Pip_Class : constant Byte := 2; -- pipes Sbf_Class : constant Byte := 3; -- sequential block Net_Class : constant Byte := 4; -- network begin -- Trace ("Odi.Set_Interactive"); Os2000_Io.Get_Options (Ctrl.Path, Option_Buffer (1)'Address, Result); if Result = Os2000_Io.E_Success then case Option_Buffer (Class_Index) is when Scf_Class | Pip_Class => Ctrl.Is_Interactive := True; when Rbf_Class | Sbf_Class | Net_Class => Ctrl.Is_Interactive := False; when others => -- unknown device type; best to treat as non-interactive Ctrl.Is_Interactive := False; end case; else Convert_Error (Result, In_Op => Get_Option_Op); end if; end Set_Interactive; procedure Access_File (Name : String; Form : String; Mode : File_Mode; Kind : File_Kind; For_Op : Access_Op; Ctrl : out Os_Control_Block) is New_Cb : Os_Control_Block; New_Path : Os2000_Io.Path_Number; Result : Os2000_Io.Stratus; begin -- Trace ("Odi.Access_File, name is " & Name); New_Cb := Initial_Control_Block (Name => Name, Form => Form, Kind => Kind, Mode_Bits => Compute_Mode_Bits (Mode, Form)); case For_Op is when Create_Op => Os2000_Io.Create (Name => New_Cb.Name.all (New_Cb.Name.all'First)'Address, Mode => New_Cb.Mode_Bits, Attributes => Compute_Attribute_Bits (Mode, Form), New_Path => New_Path, Result => Result); when Open_Op => Os2000_Io.Open (Name => New_Cb.Name.all (New_Cb.Name.all'First)'Address, Mode => New_Cb.Mode_Bits, New_Path => New_Path, Result => Result); end case; if Result = Os2000_Io.E_Success then Set_Initial_Path (New_Cb, New_Path); Set_Interactive (New_Cb); Ctrl := New_Cb; -- Trace ("Odi.Access_File - successful"); else Release (New_Cb); Convert_Error (Result, In_Op => For_Op); -- ^ will raise in Io_Exception end if; end Access_File; procedure Access_File_For_User (Ctrl : Os_Control_Block; New_Key : User.Id; User_Path : out Os2000_Io.Path_Number) is New_Path : Os2000_Io.Path_Number; Result : Os2000_Io.Stratus; function To_Int is new Unchecked_Conversion (Os2000_Io.Path_Number, Integer); begin -- Trace ("Odi.Access_File_For_User"); case Ctrl.For_Kind is when User_Kind => Os2000_Io.Open (Name => Ctrl.Name.all (Ctrl.Name.all'First)'Address, Mode => Ctrl.Mode_Bits, New_Path => New_Path, Result => Result); if Result /= Os2000_Io.E_Success then Convert_Error (Result, In_Op => Open_Op); -- ^ will raise in Io_Exception end if; -- Trace (" Opened file " & Strip_Nul (Ctrl.Name.all)); when Dio.Standard_Input => New_Path := Os2000_Io.Standard_In; when Dio.Standard_Output => New_Path := Os2000_Io.Standard_Out; when Dio.Standard_Error => New_Path := Os2000_Io.Standard_Error; end case; Ctrl.User_List := new User_Node'(Key => New_Key, Path => New_Path, Next => Ctrl.User_List); -- Trace (" New path is " & Integer'Image (To_Int (New_Path))); User_Path := New_Path; end Access_File_For_User; procedure Open (File : in out File_Type; Ctrl : in out Os_Control_Block; Mode : in File_Mode; Kind : in File_Kind; Name : in String; Form : in String; Recommended_Buffer_Size : in Natural; Actual_Buffer_Size : out Natural; Client : in Client_Kind := Device_Independent_Io.Unknown) is Result : Os2000_Io.Stratus; begin -- Trace ("Odi.Open, kind is " & File_Kind'Image (Kind)); case Kind is when Dio.Normal => Access_File (Name, Form, Mode, Kind, Open_Op, Ctrl); Dio.Set (File, Buffering.Allocate (Recommended_Buffer_Size)); Actual_Buffer_Size := Recommended_Buffer_Size; if (Mode = Device_Independent_Io.Out_File) and then Device_Independent_Io."=" (Client, Device_Independent_Io.Text_Io) then -- Set file size to zero. Os2000_Io.Set_File_Size (Path => Ctrl.Path, New_Size => 0, Result => Result); if Result /= Os2000_Io.E_Success then Convert_Error (Status => Result, In_Op => Open_Op); -- Will raise Constraint_Error or some flavor -- of Io_Exceptions. end if; end if; when Dio.Temporary => -- temporary files must be created, not opened raise Io_Exception_Flavors.Unsupported_Error; when Dio.Standard_Input => Ctrl := Initial_Control_Block (Name, Form, Dio.Standard_Input, 0); Set_Initial_Path (Ctrl, Os2000_Io.Standard_In); Set_Interactive (Ctrl); Dio.Set (File, Buffering.Allocate (Interactive_Buffer_Size)); Actual_Buffer_Size := Interactive_Buffer_Size; when Dio.Standard_Output | Dio.Standard_Error => raise Io_Exception_Flavors.Unsupported_Error; -- Standard_Output/_Error must be created, not opened end case; end Open; procedure Create (File : in out File_Type; Ctrl : in out Os_Control_Block; Mode : in File_Mode; Kind : in File_Kind; Name : in String; Form : in String; Recommended_Buffer_Size : in Natural; Actual_Buffer_Size : out Natural) is begin -- Trace ("Odi.Create, kind is " & File_Kind'Image (Kind)); case Kind is when Dio.Normal => Access_File (Name, Form, Mode, Kind, Create_Op, Ctrl); Dio.Set (File, Buffering.Allocate (Recommended_Buffer_Size)); Actual_Buffer_Size := Recommended_Buffer_Size; when Dio.Temporary => loop begin Access_File (Unique_Temp_Name.Get, Form, Mode, Kind, Create_Op, Ctrl); exit; exception when Io_Exceptions.Name_Error | Io_Exceptions.Use_Error => null; when others => Primitive_Io.Global_Absorb_Output := False; -- Trace -- ("Odi.Create temporary - unexpected exception", -- Absorb_Output => False); raise; end; end loop; Dio.Set (File, Buffering.Allocate (Recommended_Buffer_Size)); Actual_Buffer_Size := Recommended_Buffer_Size; when Dio.Standard_Input => raise Io_Exception_Flavors.Unsupported_Error; -- Standard_Input must be opened, not created when Dio.Standard_Output | Dio.Standard_Error => Ctrl := Initial_Control_Block (Name, Form, Kind, 0); if Kind = Dio.Standard_Output then Set_Initial_Path (Ctrl, Os2000_Io.Standard_Out); else Set_Initial_Path (Ctrl, Os2000_Io.Standard_Error); end if; Ctrl.Is_Interactive := True; -- Since standard files are not explicitly closed, it is -- necessary to treat as interactive in order to flush. Dio.Set (File, Buffering.Allocate (Interactive_Buffer_Size)); Actual_Buffer_Size := Interactive_Buffer_Size; end case; -- exception -- when others => -- Trace ("Odi.Create - got exception"); -- raise; end Create; function Current_Position (Path : Os2000_Io.Path_Number; Is_Interactive : Boolean) return Os2000_Io.File_Position is Result : Os2000_Io.Stratus; Position : Os2000_Io.File_Position; begin if not Is_Interactive then Os2000_Io.Current_Position (Path, Position, Result); if Result = Os2000_Io.E_Success then return Position; else Convert_Error (Result, In_Op => Get_Pos_Op); end if; else return 1; end if; end Current_Position; procedure Set_Position (Path : Os2000_Io.Path_Number; To : Os2000_Io.File_Position) is Result : Os2000_Io.Stratus; begin Os2000_Io.Seek (Path => Path, Position => Natural (To), Result => Result); if Result /= Os2000_Io.E_Success then Convert_Error (Result, In_Op => Seek_Op); end if; end Set_Position; procedure Check_And_Update_User_Data (Ctrl : Os_Control_Block) is begin if User.Not_Current (Ctrl.Last_Key) then -- Trace ("User_Data not current"); declare Current_Key : User.Id := User.Get_Current_Key; Next_User : User_Link := Ctrl.User_List; New_Path : Os2000_Io.Path_Number; begin while Next_User /= null and then Next_User.Key /= Current_Key loop Next_User := Next_User.Next; end loop; if Next_User /= null then -- Trace (" Found user data on list"); New_Path := Next_User.Path; else -- Trace (" Did not find user data on list"); -- Have to open the file for this user. Access_File_For_User (Ctrl, Current_Key, New_Path); end if; -- Trace (" Setting new position " & -- Integer'Image (Integer (Ctrl.Position))); Set_Position (New_Path, Ctrl.Position); Ctrl.Path := New_Path; Ctrl.Last_Key := Current_Key; end; end if; end Check_And_Update_User_Data; procedure Read (File : in File_Type; Ctrl : in Os_Control_Block; Item : in out Byte_String; Count : out Natural; Line_Terminator_Detected : out Boolean; Line_Last_Data_Index : out Natural; Line_Terminator_Present : out Boolean) is Bytes_Read : Natural; Result : Os2000_Io.Stratus; begin -- Trace ("Odi.Read"); Check_And_Update_User_Data (Ctrl); if Ctrl.Is_Interactive then Os2000_Io.Readln (Path => Ctrl.Path, Count => Item'Length, Buffer => Item (Item'First)'Address, Bytes_Read => Bytes_Read, Result => Result); Line_Terminator_Detected := True; Line_Terminator_Present := True; Line_Last_Data_Index := Item'First + Bytes_Read - 1; else Os2000_Io.Read (Path => Ctrl.Path, Count => Item'Length, Buffer => Item (Item'First)'Address, Bytes_Read => Bytes_Read, Result => Result); Line_Terminator_Detected := False; Line_Last_Data_Index := Item'First + Bytes_Read - 1; Line_Terminator_Present := False; end if; if Result = Os2000_Io.E_Success then Ctrl.Position := Current_Position (Ctrl.Path, Ctrl.Is_Interactive); Count := Bytes_Read; elsif Ctrl.Is_Interactive then Convert_Error (Result, In_Op => Readln_Op); else Convert_Error (Result, In_Op => Read_Op); end if; end Read; procedure Write (File : in File_Type; Ctrl : in Os_Control_Block; Item : in Byte_String; Line_Terminator_Present : in Boolean) is Bytes_Written : Natural; Result : Os2000_Io.Stratus; -- Data : String (1 .. Item'Length); Indx : Natural := 1; begin if Item'Length <= 0 then -- Trace ("Odi.Write zero length byte string"); return; end if; -- for J in Item'Range loop -- Trace ("Odi.Write item is " & Integer'Image (Integer (Item (J)))); -- Data (Indx) := Character'Val (Integer (Item (J))); -- Indx := Indx + 1; -- end loop; -- Trace ("Odi.Write " & Data); Check_And_Update_User_Data (Ctrl); Os2000_Io.Write (Path => Ctrl.Path, Count => Item'Length, Buffer => Item (Item'First)'Address, Bytes_Written => Bytes_Written, Result => Result); if Result /= Os2000_Io.E_Success then Convert_Error (Result, In_Op => Write_Op); end if; if Bytes_Written /= Item'Length then raise Io_Exceptions.Device_Error; end if; -- Trace ("Odi.Write - wrote " & Data); Ctrl.Position := Current_Position (Ctrl.Path, Ctrl.Is_Interactive); end Write; procedure Read_Bytes (Ctrl : in Os_Control_Block; Bytes_Addr : System.Address; Byte_Count : Natural; Bytes_Read : out Natural) is Result : Os2000_Io.Stratus; begin -- Trace ("Odi.Read_Bytes"); Check_And_Update_User_Data (Ctrl); Os2000_Io.Read (Path => Ctrl.Path, Count => Byte_Count, Buffer => Bytes_Addr, Bytes_Read => Bytes_Read, Result => Result); if Result = Os2000_Io.E_Success then Ctrl.Position := Current_Position (Ctrl.Path, Ctrl.Is_Interactive); else Convert_Error (Result, In_Op => Read_Op); end if; end Read_Bytes; procedure Write_Bytes (Ctrl : Os_Control_Block; Bytes_Addr : System.Address; Byte_Count : Natural) is Result : Os2000_Io.Stratus; Bytes_Written : Natural; begin if Byte_Count <= 0 then -- Trace ("Odi.Write_Bytes - zero bytes to write"); return; end if; -- Trace ("Odi.Write_Bytes"); Check_And_Update_User_Data (Ctrl); Os2000_Io.Write (Path => Ctrl.Path, Count => Byte_Count, Buffer => Bytes_Addr, Bytes_Written => Bytes_Written, Result => Result); if Result /= Os2000_Io.E_Success then Convert_Error (Result, In_Op => Write_Op); elsif Bytes_Written /= Byte_Count then raise Io_Exceptions.Device_Error; else Ctrl.Position := Current_Position (Ctrl.Path, Ctrl.Is_Interactive); end if; end Write_Bytes; function End_Of_File (File : in File_Type; Ctrl : in Os_Control_Block) return Boolean is At_End : Boolean; Result : Os2000_Io.Stratus; begin --Trace ("Odi.End_Of_File"); Check_And_Update_User_Data (Ctrl); Os2000_Io.End_Of_File (Path => Ctrl.Path, At_End => At_End, Result => Result); if Result = Os2000_Io.E_Success or else Result = Os2000_Io.E_Eof then return At_End; else Convert_Error (Result, In_Op => Eof_Op); end if; end End_Of_File; procedure Close (File : in out File_Type; Ctrl : in out Os_Control_Block) is Result : Os2000_Io.Stratus; begin -- Trace ("Odi.Close"); if Ctrl.For_Kind = Dio.Temporary and then Delete_Temp_Files then Delete (File, Ctrl); else Check_And_Update_User_Data (Ctrl); Os2000_Io.Close (Path => Ctrl.Path, Result => Result); if Result = Os2000_Io.E_Success then Release (Ctrl); else Convert_Error (Result, In_Op => Close_Op); end if; end if; end Close; procedure Reset (File : in out File_Type; Ctrl : in out Os_Control_Block; Mode : in File_Mode) is Current_Mode : File_Mode := Dio.Mode (File, Already_Locked => True); Result : Os2000_Io.Stratus; New_Ctrl : Os_Control_Block; begin -- Trace ("Odi.Reset"); Check_And_Update_User_Data (Ctrl); if Mode = Current_Mode then -- Trace ("Odi.Reset same mode"); Os2000_Io.Seek (Path => Ctrl.Path, Position => Os2000_Io.Null_Position, Result => Result); if Result /= Os2000_Io.E_Success then Convert_Error (Result, In_Op => Seek_Op); end if; elsif Ctrl.For_Kind in User_Kind then -- Trace ("Odi.Reset new mode"); Os2000_Io.Close (Path => Ctrl.Path, Result => Result); if Result /= Os2000_Io.E_Success then Convert_Error (Result, In_Op => Close_Op); end if; Access_File (Name => Strip_Nul (Ctrl.Name.all), Form => Ctrl.Form.all, Mode => Mode, Kind => Ctrl.For_Kind, For_Op => Open_Op, Ctrl => New_Ctrl); Release (Ctrl); Ctrl := New_Ctrl; -- if Mode = Dio.Out_File and then not Ctrl.Is_Interactive then -- -- Trace ("Setting file size to 0"); -- Os2000_Io.Set_File_Size (Ctrl.Path, 0, Result); -- -- if Result /= Os2000_Io.E_Success then -- Convert_Error (Result, In_Op => Size_Op); -- end if; -- end if; else -- can't change mode for standard_kinds raise Io_Exception_Flavors.Reset_Error; end if; Ctrl.Position := Current_Position (Ctrl.Path, Ctrl.Is_Interactive); end Reset; procedure Save (File : in File_Type; Ctrl : in Os_Control_Block; Immediate_Effect : in Boolean := True) is begin -- Trace ("Odi.Save"); Check_And_Update_User_Data (Ctrl); null; -- nothing to do??? end Save; procedure Delete (File : in out File_Type; Ctrl : in out Os_Control_Block) is Close_Result, Delete_Result : Os2000_Io.Stratus; begin -- Trace ("Odi.Delete"); Check_And_Update_User_Data (Ctrl); case Ctrl.For_Kind is when User_Kind => Os2000_Io.Close (Path => Ctrl.Path, Result => Close_Result); -- How should the paths for other tasks be reclaimed??? Os2000_Io.Delete (Name => Ctrl.Name (Ctrl.Name'First)'Address, Result => Delete_Result); if Close_Result = Os2000_Io.E_Success and then Delete_Result = Os2000_Io.E_Success then Release (Ctrl); elsif Delete_Result /= Os2000_Io.E_Success then Convert_Error (Delete_Result, In_Op => Delete_Op); end if; when Standard_Kind => raise Io_Exceptions.Use_Error; end case; end Delete; function Name (File : in File_Type; Ctrl : in Os_Control_Block) return String is begin -- Trace ("Odi.Name"); case Ctrl.For_Kind is when Dio.Normal | Dio.Temporary => return Strip_Nul (Ctrl.Name.all); when Dio.Standard_Input | Dio.Standard_Output | Dio.Standard_Error => -- OS9 provides no uniform way of obtaining a string -- name for the standard paths raise Io_Exception_Flavors.Unsupported_Error; end case; end Name; function Form (File : in File_Type; Ctrl : in Os_Control_Block) return String is begin -- Trace ("Odi.Form"); case Ctrl.For_Kind is when Dio.Normal | Dio.Temporary => return Form_Handling.Default_Image (Ctrl.Form.all, Ctrl.Mode_Bits); when Dio.Standard_Input | Dio.Standard_Output | Dio.Standard_Error => return ""; end case; end Form; function Is_Interactive (File : in File_Type; Ctrl : in Os_Control_Block) return Boolean is begin -- Trace ("Odi.Is_Interactive " & Boolean'Image (Ctrl.Is_Interactive)); return Ctrl.Is_Interactive; end Is_Interactive; function Size (Ctrl : Os_Control_Block) return Byte_Count is File_Size : Natural; Result : Os2000_Io.Stratus; begin -- Trace ("Odi.Size"); Check_And_Update_User_Data (Ctrl); Os2000_Io.File_Size (Path => Ctrl.Path, Size => File_Size, Result => Result); if Result = Os2000_Io.E_Success then return Byte_Count (File_Size); else Convert_Error (Result, In_Op => Size_Op); end if; end Size; function Is_Empty (File : in File_Type; Ctrl : in Os_Control_Block) return Boolean is begin -- Trace ("Odi.Is_Empty"); return Size (Ctrl) = 0; end Is_Empty; function Index (Ctrl : Os_Control_Block) return Byte_Index is File_Index : Natural; begin -- Trace ("Odi.Index"); Check_And_Update_User_Data (Ctrl); -- when Check_And_Update_User_Data sets postion for the user, then -- can just return Ctrl.Position; however, for now File_Index := Current_Position (Ctrl.Path, Ctrl.Is_Interactive); return Byte_Index (File_Index); end Index; procedure Set_Index (Ctrl : Os_Control_Block; To : Byte_Index) is begin -- Trace ("Odi.Set_Index"); Check_And_Update_User_Data (Ctrl); Set_Position (Ctrl.Path, Os2000_Io.File_Position (To)); end Set_Index; function Identical_File (File1 : in File_Type; Ctrl1 : in Os_Control_Block; File2 : in File_Type; Ctrl2 : in Os_Control_Block) return Boolean is begin -- Trace ("Odi.Identical_File"); if Ctrl1.For_Kind = Ctrl2.For_Kind then case Ctrl1.For_Kind is when User_Kind => return Ctrl1.Name.all = Ctrl2.Name.all; when Standard_Kind => return Ctrl1.Path = Ctrl2.Path; end case; else return False; end if; end Identical_File; function Address_For_Control (Ctrl : Os_Control_Block) return System.Address is begin return Convert_Control_Block_To_Address (Ctrl); end Address_For_Control; function Control_From_Address (Addr : System.Address) return Os_Control_Block is begin return Convert_Address_To_Control_Block (Addr); end Control_From_Address; end Os_Dependent_Io;