DIRECTORY Basics: TYPE USING [LongNumber], BasicTime: TYPE USING [GMT, Now, nullGMT], BcdDefs: TYPE USING [VersionStamp], FS: TYPE USING [Create, Delete, Error, Lock, Open, OpenFile, Rename], Loader: TYPE USING [BCDBuildTime], OSMiscOps: TYPE USING [Address, FileAccess], PrincOpsUtils: TYPE USING [BITXOR, CodeBase], ProcessorFace: TYPE USING [processorID], Rope: TYPE USING [ROPE], VM: TYPE USING [AddressForPageNumber, Allocate, Free, Interval, PageNumber, PageNumberForAddress]; OSMiscOpsImpl: PROGRAM IMPORTS BasicTime, FS, Loader, PrincOpsUtils, ProcessorFace, VM EXPORTS OSMiscOps SHARES ProcessorFace = { intervals: LIST OF VM.Interval; Pages: PUBLIC PROC [n: CARDINAL] RETURNS [base: OSMiscOps.Address] = { IF n = 0 THEN base _ NIL ELSE { interval: VM.Interval = VM.Allocate[count: n]; intervals _ CONS[interval, intervals]; base _ VM.AddressForPageNumber[interval.page]}; RETURN}; FreePages: PUBLIC PROC [base: OSMiscOps.Address] = { page: VM.PageNumber; last: LIST OF VM.Interval; IF base = NIL THEN RETURN; page _ VM.PageNumberForAddress[base]; FOR list: LIST OF VM.Interval _ intervals, list.rest WHILE list # NIL DO IF list.first.page # page THEN {last _ list; LOOP}; VM.Free[list.first]; IF last = NIL THEN intervals _ intervals.rest ELSE last.rest _ list.rest; EXIT; ENDLOOP}; GetTableBase: PUBLIC PROC [p: PROGRAM] RETURNS [LONG POINTER] = { RETURN [PrincOpsUtils.CodeBase[LOOPHOLE[p]]]}; GetNetAndHost: PROC RETURNS [net, host: CARDINAL] = { sum: WORD = PrincOpsUtils.BITXOR[ ProcessorFace.processorID.a, PrincOpsUtils.BITXOR[ProcessorFace.processorID.b, ProcessorFace.processorID.c]]; net _ sum/256; host _ sum MOD 256}; lastTime: BasicTime.GMT _ BasicTime.nullGMT; GenerateUniqueId: PUBLIC PROC RETURNS [BcdDefs.VersionStamp] = { net, host: CARDINAL; time: BasicTime.GMT; [net, host] _ GetNetAndHost[]; DO time _ BasicTime.Now[]; IF lastTime = BasicTime.nullGMT OR time # lastTime THEN EXIT; ENDLOOP; lastTime _ time; RETURN [[net: net, host: host, time: LOOPHOLE[time, LONG CARDINAL]]]}; BcdCreateTime: PUBLIC PROC RETURNS [time: BasicTime.GMT] = { RETURN [Loader.BCDBuildTime[]]}; StampSize: NAT = 3; Stamp: PUBLIC TYPE = RECORD [word: ARRAY [0..StampSize) OF CARDINAL]; AddStamps: PROC [s1, s2: Stamp] RETURNS [sum: Stamp] = { carry: [0..1] _ 0; i: NAT; FOR i DECREASING IN [0..StampSize) DO t: Basics.LongNumber _ [lc[LONG[s1.word[i]] + LONG[s2.word[i]] + LONG[carry]]]; sum.word[i] _ t.lowbits; carry _ t.highbits; ENDLOOP; FOR i DECREASING IN [0..StampSize) WHILE carry # 0 DO t: Basics.LongNumber _ [lc[LONG[sum.word[i]] + LONG[carry]]]; sum.word[i] _ t.lowbits; carry _ t.highbits; ENDLOOP}; RotateStamp: PROC [s: Stamp] RETURNS [Stamp] = INLINE {RETURN [AddStamps[s, s]]}; MergeStamps: PUBLIC PROC [sum, item: Stamp] RETURNS [Stamp] = { RETURN [AddStamps[RotateStamp[sum], item]]}; SignalArgs: PUBLIC PROC RETURNS [signal, message: UNSPECIFIED] = { RETURN [0, 0]}; FileError: PUBLIC ERROR [name: Rope.ROPE] = CODE; FindFile: PUBLIC PROC [name: Rope.ROPE, access: OSMiscOps.FileAccess] RETURNS [FS.OpenFile] = { file: FS.OpenFile; old: BOOL _ access = $read; lock: FS.Lock _ IF access = $read THEN read ELSE write; IF ~old THEN { file _ FS.Create[name ! FS.Error => { IF error.code = alreadyExists THEN GOTO fileExists ELSE GOTO fileProblem}]; EXITS fileExists => old _ TRUE}; IF old THEN file _ FS.Open[name: name, lock: lock ! FS.Error => {GO TO fileProblem}]; RETURN [file] EXITS fileProblem => ERROR FileError[name]}; RenameFile: PUBLIC PROC [newName, oldName: Rope.ROPE] = { DeleteFile[newName]; -- in case one already exists FS.Rename[oldName, newName ! FS.Error => {GOTO fileProblem}] EXITS fileProblem => ERROR FileError[oldName]}; UnnameFile: PUBLIC PROC [oldName: Rope.ROPE, file: FS.OpenFile] = {}; DeleteFile: PUBLIC PROC [name: Rope.ROPE] = { IF name # NIL THEN { failed: BOOL _ FALSE; file: FS.OpenFile; file _ FS.Open[name, write ! ANY => {failed _ TRUE; CONTINUE}]; IF ~failed THEN FS.Delete[name ! ANY => CONTINUE]}}; }. ¢file OSMiscOpsImpl.Mesa last modified by Satterthwaite, December 10, 1982 10:53 am Last Edited by: Maxwell, August 11, 1983 8:23 am bulk free storage management binary table management version stamp management ImageId: PUBLIC PROC RETURNS [TimeStamp.Stamp] = { RETURN [[0, 0, BcdCreateTime[]]]}; new version stamp operations exception processing file interface -- this is an enormously robust delete routine! ÊŘJšœ™Jšœ:™:Jšœ0™0J™šÏk ˜ Jšœœœ˜ Jšœ œœœ˜*Jšœ œœ˜#Jšœœœ7˜EJšœœœ˜"Jšœ œœ˜,Jšœœœœ ˜-Jšœœœ˜(Jšœœœœ˜JšœœœT˜bJ˜—šœ˜Jšœ œ(˜?Jšœ ˜Jšœ˜J˜J˜Jšœ™J™Jšœ œœœ ˜J˜š Ïnœœœœœ˜FJšœœ˜šœ˜Jšœ œ œ˜.Jšœ œ˜&Jšœœ&˜/—Jšœ˜J˜—šž œœœ˜4Jšœœ ˜Jšœœœœ ˜Jšœœœœ˜Jšœœ˜%š œœœœ!œœ˜HJšœœœ˜3Jšœ˜Jšœœœœ˜IJšœœ˜J˜J˜——Jšœ™˜šž œœœœœœœ˜AJšœœ˜.J˜J˜——Jšœ™˜šž œœœ œ˜6šœœœ˜!J˜Jšœœ<˜P—Jšœœ˜$J˜J˜—Jšœœ˜,J˜šžœœœœ˜@Jšœ œ˜Jšœœ˜J˜š˜J˜Jšœœœœ˜=Jšœ˜—J˜Jšœœœœ˜FJ˜J˜—š ž œœœœœ˜