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: 25478 (0x6386) 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 Buffering; with Os_Dependent_Io; with Semaphore; with Unchecked_Conversion; with Unchecked_Deallocation; -- with Primitive_Io; -- For debugging only (e.g., List_All_Open_Files) package body Device_Independent_Io is type Double_Link is record Prev : File_Type := null; Next : File_Type := null; end record; type File_Descriptor is record The_Mode : File_Mode := Closed; The_Kind : File_Kind := Normal; Exclusive_Access : Semaphore.Lock_State := Semaphore.Initial_Lock_State; Os_Block : Os_Dependent_Io.Os_Control_Block; Protocol_Block : System.Address := System_Types.Null_Address; Data_Buffer : Buffering.Data_Buffer := Buffering.No_Buffer; Connections : Double_Link; end record; -- All open files are threaded on this list: All_Open_Files : File_Type := null; -- These three objects are logically constants, but we want all fields -- to take the implicit default values and Ada requires that if an -- object is declared constant it must have an explicit initialization. A_Closed_Input_File : File_Descriptor; A_Closed_Output_File : File_Descriptor; A_Closed_Error_File : File_Descriptor; function To_File_Type is new Unchecked_Conversion (System.Address, File_Type); -- Dio_Absorb_Output : constant Boolean := Primitive_Io.Global_Absorb_Output; -- procedure Pput (S : in String; -- Absorb_Output : Boolean := Dio_Absorb_Output) -- renames Primitive_Io.Put_Line; procedure Free is new Unchecked_Deallocation (File_Descriptor, File_Type); function Is_Open (File : File_Type) return Boolean is begin return File /= null and then File.The_Mode /= Closed; end Is_Open; procedure Check_Open (File : File_Type) is begin -- if not Is_Open (File) then -- raise Status_Error; -- end if; if File = null or else File.The_Mode = Closed then raise Status_Error; end if; end Check_Open; pragma Inline (Check_Open); procedure Acquire (File : File_Type) is begin if File /= null then Semaphore.Acquire (File.Exclusive_Access); end if; -- exception -- when Constraint_Error => -- -- If file was already closed, for example -- null; end Acquire; procedure Release (File : File_Type) is begin if File /= null then Semaphore.Release (File.Exclusive_Access); end if; -- exception -- when Constraint_Error => -- -- If file was already closed, for example -- null; end Release; procedure Acquire_If_Needed (File : File_Type; Already_Locked : Boolean) is begin if not Already_Locked then begin Semaphore.Acquire (File.Exclusive_Access); exception when Constraint_Error => -- If file was already closed, for example null; end; end if; end Acquire_If_Needed; procedure Release_If_Grabbed (File : File_Type; Already_Locked : Boolean) is begin if not Already_Locked then begin Semaphore.Release (File.Exclusive_Access); exception when Constraint_Error => -- If file was already closed, for example null; end; end if; end Release_If_Grabbed; pragma Inline (Acquire_If_Needed, Release_If_Grabbed); -- Used to implement program termination procedure Add_To_Open_Files (File : File_Type) is begin File.Connections.Next := All_Open_Files; if All_Open_Files /= null then All_Open_Files.Connections.Prev := File; end if; All_Open_Files := File; end Add_To_Open_Files; procedure Remove_From_Open_Files (File : File_Type) is begin if File.Connections.Prev /= null then File.Connections.Prev.Connections.Next := File.Connections.Next; if File.Connections.Next /= null then File.Connections.Next.Connections.Prev := File.Connections.Prev; end if; end if; if All_Open_Files = File then All_Open_Files := File.Connections.Next; end if; end Remove_From_Open_Files; -- File is known to be null or Closed. procedure Real_Open (File : in out File_Type; 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 := Unknown) is begin File := new File_Descriptor; begin Os_Dependent_Io.Open (File, File.Os_Block, Mode, Kind, Name, Form, Recommended_Buffer_Size, Actual_Buffer_Size, Client); exception when others => Free (File); raise; end; File.The_Mode := Mode; File.The_Kind := Kind; Add_To_Open_Files (File); end Real_Open; procedure Open (File : in out File_Type; 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 := Unknown) is begin if Is_Open (File) then raise Status_Error; end if; if Kind = Temporary then -- Can't Open a temporary file, must Create it raise Name_Error; end if; Real_Open (File, Mode, Kind, Name, Form, Recommended_Buffer_Size, Actual_Buffer_Size, Client); end Open; procedure Append (File : in out File_Type; 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 if Is_Open (File) then raise Status_Error; end if; if Kind = Temporary then -- Can't Append to a temporary file, must Create it raise Name_Error; end if; Real_Open (File, Mode, Kind, Name, Form, Recommended_Buffer_Size, Actual_Buffer_Size, Unknown); -- ??? Ok wiseguy, now position to the end -- ??? When is check made that OS permits append on files -- ??? of this Mode and Kind? raise Program_Error; end Append; procedure Create (File : in out File_Type; 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 if Is_Open (File) then raise Status_Error; end if; File := new File_Descriptor; begin Os_Dependent_Io.Create (File, File.Os_Block, Mode, Kind, Name, Form, Recommended_Buffer_Size, Actual_Buffer_Size); exception when others => Free (File); raise; end; File.The_Mode := Mode; File.The_Kind := Kind; Add_To_Open_Files (File); end Create; procedure Close (File : in out File_Type; Already_Locked : Boolean := True) is begin Acquire_If_Needed (File, Already_Locked); if Is_Open (File) then begin Os_Dependent_Io.Close (File, File.Os_Block); Buffering.Free (File.Data_Buffer); File.The_Mode := Closed; Remove_From_Open_Files (File); -- When closing the file we release the lock unconditionally Release (File); Free (File); -- File := null; exception when others => -- When closing the file we release the lock unconditionally Release (File); raise; end; end if; end Close; procedure Save (File : File_Type; Immediate_Effect : Boolean := True; Already_Locked : Boolean := True) is begin Acquire_If_Needed (File, Already_Locked); if Is_Open (File) then begin Os_Dependent_Io.Save (File, File.Os_Block, Immediate_Effect); Release_If_Grabbed (File, Already_Locked); exception when others => Release_If_Grabbed (File, Already_Locked); raise; end; end if; end Save; procedure Delete (File : in out File_Type; Already_Locked : Boolean := True) is begin Acquire_If_Needed (File, Already_Locked); if Is_Open (File) then begin Os_Dependent_Io.Delete (File, File.Os_Block); Buffering.Free (File.Data_Buffer); File.The_Mode := Closed; Remove_From_Open_Files (File); -- When deleting the file, we release the lock unconditionally Release (File); Free (File); -- File := null; exception when others => -- ??? Should the file be closed ??? -- Since here the file is not deleted, and not -- closed, we release the lock conditionally. Release_If_Grabbed (File, Already_Locked); raise; end; else Release_If_Grabbed (File, Already_Locked); raise Status_Error; end if; end Delete; procedure Reset (File : in out File_Type; Mode : File_Mode; Already_Locked : Boolean := True) is begin if Mode = Closed then raise Status_Error; end if; Acquire_If_Needed (File, Already_Locked); if Is_Open (File) then begin Os_Dependent_Io.Reset (File, File.Os_Block, Mode); File.The_Mode := Mode; Release_If_Grabbed (File, Already_Locked); exception when others => Release_If_Grabbed (File, Already_Locked); raise; end; else Release_If_Grabbed (File, Already_Locked); raise Status_Error; end if; end Reset; procedure Reset (File : in out File_Type; Already_Locked : Boolean := True) is begin Acquire_If_Needed (File, Already_Locked); if Is_Open (File) then begin Os_Dependent_Io.Reset (File, File.Os_Block, File.The_Mode); Release_If_Grabbed (File, Already_Locked); exception when others => Release_If_Grabbed (File, Already_Locked); raise; end; else Release_If_Grabbed (File, Already_Locked); raise Status_Error; end if; end Reset; function Mode (File : File_Type; Already_Locked : Boolean := True) return File_Mode is Mode : File_Mode; begin Acquire_If_Needed (File, Already_Locked); if Is_Open (File) then Mode := File.The_Mode; Release_If_Grabbed (File, Already_Locked); return Mode; else Release_If_Grabbed (File, Already_Locked); raise Status_Error; end if; end Mode; function Kind (File : File_Type; Already_Locked : Boolean := True) return File_Kind is Kind : File_Kind; begin Acquire_If_Needed (File, Already_Locked); if Is_Open (File) then Kind := File.The_Kind; Release_If_Grabbed (File, Already_Locked); return Kind; else Release_If_Grabbed (File, Already_Locked); raise Status_Error; end if; end Kind; function Name (File : File_Type; Already_Locked : Boolean := True) return String is begin Acquire_If_Needed (File, Already_Locked); if Is_Open (File) then declare Name : constant String := Os_Dependent_Io.Name (File, File.Os_Block); begin Release_If_Grabbed (File, Already_Locked); return Name; end; else Release_If_Grabbed (File, Already_Locked); raise Status_Error; end if; end Name; function Form (File : File_Type; Already_Locked : Boolean := True) return String is begin Acquire_If_Needed (File, Already_Locked); if Is_Open (File) then declare Form : constant String := Os_Dependent_Io.Form (File, File.Os_Block); begin Release_If_Grabbed (File, Already_Locked); return Form; end; else Release_If_Grabbed (File, Already_Locked); raise Status_Error; end if; end Form; procedure Set (File : File_Type; Buffer : Buffering.Data_Buffer) is begin File.Data_Buffer := Buffer; end Set; function Get (File : File_Type) return Buffering.Data_Buffer is begin return File.Data_Buffer; end Get; function Buffer_Size (File : File_Type; Already_Locked : Boolean := True) return Natural is N : Natural := 0; begin Acquire_If_Needed (File, Already_Locked); if Is_Open (File) then if Buffering.Is_Allocated (File.Data_Buffer) then N := Buffering.Max_Length (File.Data_Buffer); else N := 0; end if; Release_If_Grabbed (File, Already_Locked); return N; else Release_If_Grabbed (File, Already_Locked); raise Status_Error; end if; end Buffer_Size; function End_Of_File (File : File_Type; Already_Locked : Boolean := True) return Boolean is Eof : Boolean; begin Acquire_If_Needed (File, Already_Locked); if Is_Open (File) then Eof := Os_Dependent_Io.End_Of_File (File, File.Os_Block); Release_If_Grabbed (File, Already_Locked); return Eof; else Release_If_Grabbed (File, Already_Locked); raise Status_Error; end if; end End_Of_File; function Is_Interactive (File : File_Type; Already_Locked : Boolean := True) return Boolean is Ii : Boolean; begin Acquire_If_Needed (File, Already_Locked); if Is_Open (File) then Ii := Os_Dependent_Io.Is_Interactive (File, File.Os_Block); Release_If_Grabbed (File, Already_Locked); return Ii; else Release_If_Grabbed (File, Already_Locked); raise Status_Error; end if; end Is_Interactive; procedure Read (File : in File_Type; Item : in out Byte_String; Count : out Natural; Line_Terminator_Detected : out Boolean; Line_Last_Data_Index : out Natural; Line_Terminator_Present : out Boolean; Already_Locked : Boolean := True) is begin Acquire_If_Needed (File, Already_Locked); if Is_Open (File) then if File.The_Mode = In_File then -- Data is always read into the user's buffer directly. In case -- of error his buffer could be trashed. This seems reasonable. Os_Dependent_Io.Read (File, File.Os_Block, Item, Count, Line_Terminator_Detected, Line_Last_Data_Index, Line_Terminator_Present); Release_If_Grabbed (File, Already_Locked); else raise Mode_Error; end if; else raise Status_Error; end if; exception when others => Release_If_Grabbed (File, Already_Locked); raise; end Read; procedure Read (File : File_Type; Item : in out Byte_String; Count : out Natural; Already_Locked : Boolean := True) is Db, Dc : Boolean; Dn : Natural; begin Read (File, Item, Count, Db, Dn, Dc, Already_Locked); end Read; procedure Write (File : in File_Type; Item : in Byte_String; Line_Terminator_Present : in Boolean; Already_Locked : Boolean := True) is begin Acquire_If_Needed (File, Already_Locked); if Is_Open (File) then if File.The_Mode = Out_File then -- With this call, which writes a record at a time, we -- don't go through the file's buffer. (In fact, maybe -- we shouldn't allocate the buffer?) Because even with -- asynchronous I/O the task which has the data can't -- continue until the I/O is complete. begin Os_Dependent_Io.Write (File, File.Os_Block, Item, Line_Terminator_Present); Release_If_Grabbed (File, Already_Locked); end; else raise Mode_Error; end if; else raise Status_Error; end if; exception when others => Release_If_Grabbed (File, Already_Locked); raise; end Write; function Is_Empty (File : File_Type; Already_Locked : Boolean := True) return Boolean is Ie : Boolean; begin Acquire_If_Needed (File, Already_Locked); if Is_Open (File) then Ie := Os_Dependent_Io.Is_Empty (File, File.Os_Block); Release_If_Grabbed (File, Already_Locked); return Ie; else Release_If_Grabbed (File, Already_Locked); raise Status_Error; end if; end Is_Empty; function Closed_Input_File return File_Type is begin return To_File_Type (A_Closed_Input_File'Address); end Closed_Input_File; function Closed_Output_File return File_Type is begin return To_File_Type (A_Closed_Output_File'Address); end Closed_Output_File; function Closed_Error_File return File_Type is begin return To_File_Type (A_Closed_Error_File'Address); end Closed_Error_File; procedure Close_All_Open_Files is begin -- The big problem, of course, is how (in Ada) to call the -- protocol-level Close ?!??! -- One way: The protocol routine will provide the 'Address -- of the routine to call to be put in the file control -- block to be called through a special assembly language -- routine. raise Program_Error; end Close_All_Open_Files; procedure Identical_Files (File : in File_Type; Open_In : out Natural; Open_Out : out Natural; Open_In_Out : out Natural) is Files : File_Type; O_In, O_Out, O_In_Out : Natural := 0; begin Files := All_Open_Files; loop exit when Files = null; if Os_Dependent_Io.Identical_File (File, File.Os_Block, Files, Files.Os_Block) then case Files.The_Mode is when In_File => O_In := O_In + 1; when Out_File => O_Out := O_Out + 1; when Inout_File => O_In_Out := O_In_Out + 1; when Closed => null; end case; end if; Files := Files.Connections.Next; end loop; Open_In := O_In; Open_Out := O_Out; Open_In_Out := O_In_Out; end Identical_Files; procedure List_All_Open_Files is -- Files : File_Type; -- Debugging : constant Boolean := not Dio_Absorb_Output; begin -- if not Debugging then return; -- end if; -- if All_Open_Files = null then -- Pput ("Device_Independent_Io: No open files"); -- else -- Pput ("Device_Independent_Io: Currently open files:"); -- Files := All_Open_Files; -- loop -- begin -- Pput (" " & Name (Files)); -- exception -- when others => -- Pput -- (" << File open but name can't be determined >>"); -- end; -- Files := Files.Connections.Next; -- exit when Files = null; -- end loop; -- end if; end List_All_Open_Files; package body Client_Specific is procedure Set (File : File_Type; Control : Pointer) is begin raise Program_Error; end Set; function Get (File : File_Type) return Pointer is begin raise Program_Error; return null; end Get; end Client_Specific; procedure Set (File : File_Type; Control : System.Address) is begin File.Protocol_Block := Control; end Set; function Get (File : File_Type) return System.Address is begin return File.Protocol_Block; end Get; function Get_Os_Dependent_Control (File : File_Type) return System.Address is begin if File /= null then return Os_Dependent_Io.Address_For_Control (File.Os_Block); else return System.Address_Zero; end if; end Get_Os_Dependent_Control; package body File_Type_Conversions is function To_Derived is new Unchecked_Conversion (File_Type, Derived_File_Type); function From_Derived is new Unchecked_Conversion (Derived_File_Type, File_Type); function From_Standard (File : File_Type) return Derived_File_Type is begin return To_Derived (File); end From_Standard; function To_Standard (File : Derived_File_Type) return File_Type is begin return From_Derived (File); end To_Standard; end File_Type_Conversions; end Device_Independent_Io;