<> <> <> <> <> <> DIRECTORY Basics USING [DoubleShiftRight], Rope USING [ROPE]; File: CEDAR DEFINITIONS IMPORTS Basics = BEGIN <> <> <<>> <> <<>> <> <> RC: TYPE = { -- extension of "Reason" for internal use. ok, wentOffline, -- volume is not accessible (some drive has been offline) nonCedarVolume, -- the operation is not possible on a non-cedar (Pilot?) volume. inconsistent, -- the volume's (or file's) permanent data structures look inconsistent software, -- i.e. label-check. The page on disk is not the one the software expected. hardware, -- the disk hardware/microcode detected a hard disk error unknownFile, -- the file does not exist (possibly deleted since it was opened) unknownPage, -- the page would be beyond the end of the file volumeFull, -- the volume has no free pages (and one is needed!) fragmented, -- the file requires too many non-contiguous areas of disk ( > 84 today ) mixedDevices -- a bootable file is not entirely on one device, or not on correct device }; Reason: TYPE = RC[SUCC[ok]..LAST[RC]]; -- error reason Error: ERROR [why: Reason, diskPage: INT _ -1]; <> <> VolumeID: TYPE[5]; <> NullVolumeRep: PRIVATE TYPE = RECORD[a,b,c,d,e:CARDINAL]; nullVolumeID: VolumeID = LOOPHOLE[NullVolumeRep[a:0,b:0,c:0,d:0,e:0]]; <> Volume: TYPE = REF VolumeObject; VolumeObject: TYPE; <> VolumeFile: TYPE = MACHINE DEPENDENT { -- root files of a volume checkpoint(0), microcode(1), germ(2), bootFile(3), debugger(4), -- outload file -- debuggee(5), -- outload file -- VM(6), -- virtual memory backing file -- VAM(7), -- volume allocation map -- client(8), -- client directory system root file -- alpine(9), -- for use by Alpine file servers -- (15) -- spare root page slots -- }; FP: TYPE = MACHINE DEPENDENT RECORD[ <> id(0): FileID, da(2): DA ]; FileID: TYPE[2]; DA: TYPE[2]; NullFileIDRep: PRIVATE TYPE = RECORD[a,b:CARDINAL]; NullDARep: PRIVATE TYPE = RECORD[a,b:CARDINAL]; nullDA: PRIVATE DA = LOOPHOLE[NullDARep[0,0]]; nullFP: FP = [id: nullFileID, da: nullDA]; <> nullFileID: FileID = LOOPHOLE[NullFileIDRep[0,0]]; <> PageNumber: TYPE = RECORD[INT]; <> PageCount: TYPE = INT; <> Add: PROC[p: PageNumber, n: PageCount] RETURNS[PageNumber] = INLINE { RETURN[ [p+n] ] }; -- "n" may be negative -- wordsPerPage: NAT = 256; logWordsPerPage: NAT = 8; <> PagesForWords: PROC[w: INT] RETURNS[PageCount] = INLINE { RETURN[Basics.DoubleShiftRight[[li[w+(wordsPerPage-1)]], logWordsPerPage].li]; }; Handle: TYPE = REF Object; Object: TYPE; <> PropertyStorage: TYPE = LONG POINTER TO RECORD[SEQUENCE COMPUTED CARDINAL OF WORD]; <> <> NextVolume: PROC[volume: Volume, wait: BOOL _ FALSE] RETURNS[Volume]; <> LogicalInfo: PROC[volume: File.Volume] RETURNS[ id: VolumeID, size: INT, rootStatus: RC, <> name: Rope.ROPE, vamStatus: RC, <> free: INT, freeboard: INT ]; <> GetVolumeID: PROC[volume: Volume] RETURNS[id: VolumeID]; <> <> GetVolumeName: PROC[volume: Volume] RETURNS[Rope.ROPE]; <> <> FindVolumeFromID: PROC[id: VolumeID] RETURNS[Volume]; <> FindVolumeFromName: PROC[name: Rope.ROPE] RETURNS[Volume]; <> SystemVolume: PROC RETURNS[Volume]; <> SetSystemVolume: PROC[Volume]; <> FindSystemVolume: PROC RETURNS[found: BOOL]; <> FindVM: PROC RETURNS[found: BOOL]; <> <> Open: PROC[volume: Volume, fp: FP] RETURNS[Handle]; <> <> Create: PROC[volume: Volume, size: PageCount, report: PROC[FP, PropertyStorage, File.PageCount] _ NIL] RETURNS[Handle]; <> <> Delete: PROC[file: Handle]; <> <> Info: PROC[file: Handle] RETURNS[volume: Volume, fp: FP, size: PageCount]; <> <> SetSize: PROC[file: Handle, size: PageCount]; <> <> Read: UNSAFE PROC[file: Handle, from: PageNumber, nPages: PageCount, to: LONG POINTER]; <> <> Write: PROC[file: Handle, to: PageNumber, nPages: PageCount, from: LONG POINTER]; <> <> GetProperties: PROC[file: Handle] RETURNS[prop:PropertyStorage, nPages: File.PageCount]; <> <> SetPropertiesSize: PROC[file: Handle, nPages: File.PageCount]; <> <<>> WriteProperties: PROC[file: Handle]; <> <> END. <<>> <> <> <> <<>> <> <> <> <> <<>> <<>>