DIRECTORY CachedSpace USING [Desc], Environment USING [wordsPerPage], File USING [ Capability, Delete, GetAttributes, GetSize, ID, nullID, PageCount, Permissions, Unknown], Hierarchy USING [GetDescriptor], Inline USING [LowHalf], IO USING [int, Handle, NewLine, PutChar, PutF, PutRope], KernelFile USING [GetRootFile], PilotFileTypes USING [tTempFileList], Rope USING [ROPE], Space USING [ CopyIn, Create, Delete, GetAttributes, Handle, LongPointer, Map, nullHandle, PageCount, virtualMemory], SpaceImplInternal USING [EnterSpace], UserExec USING [CommandProc, Confirm, GetExecHandle, GetStreams, RegisterCommand], Volume USING [systemID]; FlushUnneededTempFiles: PROGRAM IMPORTS File, Hierarchy, Inline, IO, KernelFile, Space, SpaceImplInternal, UserExec, Volume SHARES File = BEGIN FlushTempFiles: UserExec.CommandProc = TRUSTED { out: IO.Handle; tempFiles, recoverableFiles, tempPages, recoverablePages: INT _ 0; CheckSpace: PROC [space: Space.Handle] = { IF Space.GetAttributes[space].mapped THEN { CheckIfThisFile: PROC [file: File.Capability] RETURNS [stop, zap: BOOL _ FALSE] = { CheckBackingFile: PROC = { desc: CachedSpace.Desc; validSpace, validSwapUnit: BOOL; [validSpace, validSwapUnit] _ Hierarchy.GetDescriptor[@desc, LOOPHOLE[space]]; IF ~(validSpace OR validSwapUnit) THEN RETURN; IF desc.window.file.fID = file.fID THEN stop _ zap _ TRUE; }; SpaceImplInternal.EnterSpace[CheckBackingFile]; }; EnumerateTempFiles[CheckIfThisFile]; } ELSE EnumerateChildren[space, CheckSpace]; }; GetBeforeStats: PROC [file: File.Capability] RETURNS [stop, zap: BOOL _ FALSE] = { size: File.PageCount = File.GetSize[file ! File.Unknown => GO TO notInteresting]; IF File.GetAttributes[file].temporary THEN { tempFiles _ tempFiles + 1; tempPages _ tempPages + size; } ELSE GO TO notInteresting; EXITS notInteresting => zap _ TRUE; }; GetAfterStats: PROC [file: File.Capability] RETURNS [stop, zap: BOOL _ FALSE] = { size: File.PageCount = File.GetSize[file ! File.Unknown => GO TO notAFile]; recoverableFiles _ recoverableFiles + 1; recoverablePages _ recoverablePages + size; EXITS notAFile => NULL; }; DoOneFile: PROC [file: File.Capability] RETURNS [stop, zap: BOOL _ FALSE] = { File.Delete[file ! File.Unknown => GO TO notAFile]; out.PutChar['#]; EXITS notAFile => NULL; }; [out: out] _ UserExec.GetStreams[exec]; out.PutRope["Enumerating temp files..."]; EnumerateTempFiles[GetBeforeStats]; out.PutRope["enumerating spaces..."]; EnumerateChildren[Space.virtualMemory, CheckSpace]; out.PutRope["done\N"]; EnumerateTempFiles[GetAfterStats]; out.PutF[ "There are %g temporary files comprising %g total pages.\NOf these, %g can be deleted to recover %g pages.\N", IO.int[tempFiles], IO.int[tempPages], IO.int[recoverableFiles], IO.int[recoverablePages] ]; IF recoverableFiles > 0 AND UserExec.Confirm[msg: "Shall I delete them", exec: exec] THEN { out.PutRope["Deleting..."]; EnumerateTempFiles[DoOneFile]; out.NewLine[]; }; Cleanup[]; }; idsPerPage: NAT = Environment.wordsPerPage/SIZE[File.ID]; TempsPage: TYPE = MACHINE DEPENDENT RECORD [ ids: ARRAY [0..idsPerPage) OF File.ID, fill: ARRAY [0..Environment.wordsPerPage-idsPerPage*SIZE[File.ID]) OF WORD ]; TempsFile: TYPE = RECORD [pages: SEQUENCE COMPUTED Space.PageCount OF TempsPage]; tempFile: File.Capability; tempFilePages: File.PageCount; tempsSpace: Space.Handle; temps: LONG POINTER TO TempsFile _ NIL; EnumerateTempFiles: PROC [proc: PROC [File.Capability] RETURNS [stop, zap: BOOL]] = { IF temps = NIL THEN { tempFile _ KernelFile.GetRootFile[PilotFileTypes.tTempFileList, Volume.systemID]; tempFilePages _ File.GetSize[tempFile]; tempsSpace _ Space.Create[size: Inline.LowHalf[tempFilePages], parent: Space.virtualMemory]; temps _ Space.LongPointer[tempsSpace]; Space.Map[tempsSpace]; Space.CopyIn[tempsSpace, [tempFile, 0]]; }; FOR page: Space.PageCount IN [0..tempFilePages) DO tempPage: LONG POINTER TO TempsPage = @temps.pages[page]; FOR i: [0..idsPerPage) IN [0..idsPerPage) DO id: File.ID = tempPage.ids[i]; IF id ~= File.nullID THEN { stop, zap: BOOL; [stop, zap] _ proc[[id, LAST[File.Permissions]]]; IF zap THEN tempPage.ids[i] _ File.nullID; IF stop THEN EXIT; }; ENDLOOP; ENDLOOP; }; Cleanup: PROC = { Space.Delete[tempsSpace]; temps _ NIL; }; EnumerateChildren: PROC [space: Space.Handle, proc: PROC [Space.Handle]] = { FOR child: Space.Handle _ Space.GetAttributes[space].lowestChild, Space.GetAttributes[child].nextSibling UNTIL child = Space.nullHandle DO proc[child]; ENDLOOP; }; UserExec.RegisterCommand[ name: "FlushUnneededTempFiles", proc: FlushTempFiles, briefDoc: "Eliminates unnecessary temporary files from the local disk." ]; [] _ FlushTempFiles[event: NIL, exec: UserExec.GetExecHandle[]]; END. ÜFlushUnneededTempFiles.mesa last edited by Levin on November 21, 1982 10:32 am We copy the temp file to avoid messing up Pilot. There is no danger of a race, but even if there were, the subsequent checking would. Ê$˜J˜Jšœ™Jšœ2™2J˜šÏk ˜ Jšœ œ˜Jšœ œ˜!šœœ˜ Jšœ,œ+˜Y—Jšœ œ˜ Jšœœ ˜Jšœœ0˜8Jšœ œ˜Jšœœ˜%Jšœœœ˜šœœ˜ J˜LJ˜—Jšœœ˜%Jšœ œD˜RJšœœ ˜J˜—šœ˜š˜Jšœœ'˜BJ˜—Jšœ˜ J˜—Jš˜J˜šœ'œ˜0Jšœ˜Jšœ:œ˜BšÏn œœ˜*šœ#œ˜+š žœœœ œœ˜Sšžœœ˜J˜Jšœœ˜ Jšœ=œ ˜NJšœœœœ˜.Jšœ!œœ˜:J˜—J˜/J˜—J˜$J˜—Jšœ&˜*J˜—š žœœœ œœ˜RJšœ;œœ˜Qšœ$œ˜,J˜J˜J˜—Jšœœœ˜š˜Jšœœ˜—J˜—š ž œœœ œœ˜QJšœ;œœ ˜KJ˜(J˜+š˜Jšœ œ˜—J˜—š ž œœœ œœ˜MJšœ#œœ ˜3J˜š˜Jšœ œ˜—J˜—J˜'J˜)J˜#J˜%J˜3J˜J˜"˜ J˜nJšœœœœ˜XJ˜—šœ˜šœ9œ˜?J˜J˜J˜J˜——J˜ J˜J˜—Jšœ œœœ˜9š œ œœ œœ˜,Jšœœœœ˜&Jš œœ)œœœ˜JJ˜—Jš œ œœ œœœ ˜QJ˜J˜J˜Jš œœœœ œ˜'J˜š žœœœœ œ˜Ušœ œœ˜J˜QJ˜'J˜\J˜&JšœW™WJšœ-™-J˜J˜(J˜—šœœ˜2Jšœ œœœ ˜9šœœ˜,Jšœ œ˜šœœ˜Jšœ œ˜Jšœœ˜1Jšœœ˜*Jšœœœ˜J˜—Jšœ˜—Jšœ˜—J˜J˜—šžœœ˜J˜Jšœœ˜ J˜J˜—šžœœœ˜LJšœe˜hJšœœœ˜7J˜J˜—˜J˜J˜J˜GJ˜J˜—J˜@J˜J˜Jšœ˜J˜J˜—…—\\