DIRECTORY CStrings, Rope, UnixSysCalls, UnixErrno, UnixTypes, UnixDirectory, UXStrings; UnixDirectoryImpl: CEDAR PROGRAM IMPORTS UnixErrno, UnixSysCalls, UXStrings EXPORTS UnixDirectory ~ BEGIN ROPE: TYPE ~ Rope.ROPE; CHARPtr: TYPE ~ UnixTypes.CHARPtr; FD: TYPE ~ UnixTypes.FD; RES: TYPE ~ UnixTypes.RES; DirPtr: TYPE ~ REF DirRep; DirRep: PUBLIC TYPE ~ RECORD [ buffer: CStrings.CString, -- character buffer where to place data -- bsize: INT, -- size of the buffer -- fd: FD, -- file descriptor of the directory -- loc: INT, -- the next directory entry in buffer -- size: INT, -- the first nonvalid character in buffer -- offset: INT -- the offset of DirEnt in the directory file -- ]; DirEnt: TYPE ~ UnixDirectory.DirEnt; DirEntPtr: TYPE ~ POINTER TO DirEnt; OpenDir: PUBLIC PROC [fileName: CHARPtr] RETURNS [dirp: DirPtr] ~ TRUSTED { flags: UnixTypes.FileFlags ~ [access: RDONLY]; mode: UnixTypes.Mode; fd: FD ~ UnixSysCalls.Open[path: fileName, flags: flags, mode: mode]; stat: UnixTypes.Stat; buf: UnixTypes.StatPtr ~ @stat; IF fd = error THEN RETURN [NIL]; IF UnixSysCalls.FStat[fd, buf] = failure THEN { [] ¬ UnixSysCalls.Close[fd]; RETURN [NIL]; }; IF buf.mode.fmt # dir THEN { UnixErrno.SetErrno[ENOTDIR]; [] ¬ UnixSysCalls.Close[fd]; RETURN [NIL]; }; dirp ¬ NEW [DirRep ¬ [ buffer: UXStrings.CreateSpace[buf.blksize], bsize: buf.blksize, fd: fd, size: 0, loc: 0, offset: 0]]; RETURN [dirp]; }; CloseDir: PUBLIC PROC [dirp: DirPtr] RETURNS [RES] ~ { fd: FD ~ dirp.fd; dirp.fd ¬ error; dirp.loc ¬ 0; RETURN [UnixSysCalls.Close[fd]]; }; ReadDir: PUBLIC PROC [dirp: DirPtr] RETURNS [DirEntPtr] ~ { dp: DirEntPtr; fd: FD ~ dirp.fd; buffer: CHARPtr ~ dirp.buffer; bsize: INT ~ dirp.bsize; saveloc: INT ¬ 0; recLen: CARD; fileNo: CARD; WHILE TRUE DO IF dirp.size # 0 THEN { saveloc ¬ dirp.loc; TRUSTED { dp ¬ LOOPHOLE[buffer + saveloc]; recLen ¬ dp.recLen; }; dirp.loc ¬ saveloc + recLen; }; IF dirp.loc >= dirp.size THEN { dirp.loc ¬ dirp.size ¬ 0; }; IF dirp.size = 0 THEN { TRUSTED {dirp.size ¬ UnixSysCalls.GetDEnts[fd, buffer, bsize]}; IF dirp.size = 0 THEN dirp.loc ¬ saveloc; IF dirp.size <=0 THEN RETURN [NIL]; }; TRUSTED { dp ¬ LOOPHOLE[buffer + dirp.loc]; recLen ¬ dp.recLen; fileNo ¬ dp.fileNo; }; IF recLen <= 0 THEN RETURN [NIL]; IF fileNo # 0 THEN EXIT; ENDLOOP; TRUSTED {dirp.offset ¬ dp.offset} ; RETURN [dp]; }; TellDir: PUBLIC PROC [dirp: DirPtr] RETURNS [INT] ~ { RETURN [dirp.offset]; }; SeekDir: PUBLIC PROC [dirp: DirPtr, loc: INT] ~ { currentLocation: INT ~ dirp.offset; fd: FD ~ dirp.fd; IF (currentLocation = loc) THEN RETURN; dirp.loc ¬ 0; dirp.size ¬ 0; [] ¬ UnixSysCalls.LSeek[d: fd, offset: loc, whence: set]; dirp.offset ¬ loc; }; RewindDir: PUBLIC PROC [dirp: DirPtr] ~ { startOffset: INT ~ 0; SeekDir[dirp, startOffset]; }; NameFromDirEntP: PUBLIC PROC [dp: DirEntPtr] RETURNS [name: ROPE] ~ TRUSTED { name ¬ UXStrings.ToRope[LOOPHOLE[@(dp.name)]]; }; END. ΐUnixDirectoryImpl.mesa Copyright Σ 1988, 1989, 1991 by Xerox Corporation. All rights reserved. Eduardo Pelegri-Llopart,November 29, 1988 12:19:27 pm PST Willie-Sue Orr, March 11, 1989 1:26 pm PST An implementation of some Unix (tm) directory functions using UnixSysCalls. Willie-s, August 13, 1991 1:27 pm PDT UnixSysCalls.GetDEnts: UNSAFE PROC [fd: FD, buf: CHARPtr, nBytes: INT] RETURNS [INT]; dirp.buffer.anchor _ NIL; -- free now -- Κ>–(cedarcode) style•NewlineDelimiter ˜™Icodešœ Οeœ=™HK™9Kšœ*™*K™K™KK™%—K˜K˜šΟk ˜ K˜ K˜Kšœ ˜ K˜ K˜ Kšœ˜Kšœ ˜ K˜—šΠlnœžœž˜ Kšžœ#˜*Kšžœ˜—šœž˜K˜Kšžœžœžœ˜Kšœ žœ˜"Kšžœžœ žœ˜Kšžœžœ žœ˜K˜Kšœžœžœ˜šœžœž˜KšœΟc*˜DKšœžœ ˜$Kšœžœ &˜.Kšœžœ Πce ˜2Kšœžœ #‘ ˜7Kšœžœ 0˜