BlackCherryPFSImpl.mesa
Copyright Ó 1989, 1990, 1991, 1992 by Xerox Corporation. All rights reserved.
Bill Jackson (bj) July 19, 1989 6:38:17 pm PDT
Willie-sue, March 13, 1992 3:47 pm PST
DIRECTORY
BlackCherry,
Icons,
IO,
PFS,
PFSBackdoor,
PFSNames,
RefText,
Rope,
UnixSysCalls,
UnixTypes;
BlackCherryPFSImpl: CEDAR PROGRAM
IMPORTS
BlackCherry, Icons, IO, PFS, PFSBackdoor, PFSNames, RefText, Rope, UnixSysCalls
= BEGIN OPEN BlackCherry;
ROPE: TYPE ~ Rope.ROPE;
STREAM: TYPE ~ IO.STREAM;
Initial PCedar version
squirrelAwayMyStartingDir: PFS.PATH;
PFSFullName: PROC [ fileName: ROPE, wDir: ROPE ¬ NIL ] RETURNS [ fullName: ROPE ] ~ {
BEGIN ENABLE PFS.Error => {
Report["\n***PFS.Error: %g\n", [rope[error.explanation]] ];
IF error.code = $illegalName THEN GOTO tryAgain ELSE GOTO Bogus
};
fullNamePath: PFS.PATH ¬ PFSNames.ExpandName[PFS.PathFromRope[fileName], PFS.PathFromRope[wDir]];
fullName ¬ PFS.RopeFromPath[fullNamePath];
EXITS
Bogus => { ERROR BadName };
tryAgain => NULL;
END;
try getting rid of spaces and tabs in the name
BEGIN
BEGIN ENABLE PFS.Error => { Report["\n***PFS.Error: %g (%g)\n",
[rope[error.explanation]], [rope[fileName]] ]; GOTO Bogus2 };
temp: REF TEXT ¬ RefText.ObtainScratch[RefText.line];
temp.length ¬ 0;
FOR i: INT IN [0..fileName.Length[]) DO
c: CHAR ~ fileName.Fetch[i];
IF (c = ' ) OR ( c = '\t ) THEN LOOP;
[] ¬ RefText.AppendChar[temp, c];
ENDLOOP;
fileName ¬ Rope.FromRefText[temp];
RefText.ReleaseScratch[temp];
fullName ¬ PFS.RopeFromPath[ PFSNames.ExpandName[PFS.PathFromRope[fileName], PFS.PathFromRope[wDir]] ];
EXITS
Bogus2 => { ERROR BadName };
END;
END;
};
PFSFileOpenOrCreate: PROC [ name: ROPE, how: ATOM ]
RETURNS [ fileData: BCFileData] ~ {
ENABLE PFS.Error => {
Report["\n***PFS.Error: %g (%g)\n", [rope[error.explanation]], [rope[name]] ];
GOTO cant;
};
retry: BOOL ¬ FALSE;
fullFName: PFS.PATH;
ownerOnlyMode: UnixTypes.Mode ~ [ owner: [true, true, false] ];
readOnly: BOOL ~ how = $openRO;
ro: REF BOOL ~ NEW[BOOL ¬ readOnly];
clientData: REF ANY ~ ro;
DoCreate: PROC = {
strm: STREAM ¬ PFS.StreamOpen[PFS.PathFromRope[fileData.name], $create ];
fd: UnixTypes.FD ¬ PFSBackdoor.FDFromOpenStream[strm];
[] ¬ UnixSysCalls.FChMod[fd, ownerOnlyMode];
strm.Close[];
IF retry THEN fullFName ¬ PFS.FileInfo[PFS.PathFromRope[fileData.name]].fullFName;
};
fileData ¬ NEW[BCFileDataRec ¬ [name: name, clientData: clientData] ];
IF how = $create THEN DoCreate[];
fullFName ¬ PFS.FileInfo[PFS.PathFromRope[fileData.name] ! PFS.Error =>
IF ( error.code = $unknownFile ) THEN
SELECT TRUE FROM
( how = $openOrCreate ) => { retry ¬ TRUE; DoCreate[]; CONTINUE };
( how = $openRO ) => {
Report["\n*** ReadOnly requested but %g doesn't exist\n", [rope[name]] ];
GOTO cant;
};
ENDCASE => REJECT;
].fullFName;
fileData.name ¬ PFS.RopeFromPath[fullFName];
IF NOT readOnly THEN fileData.writeStream ¬ PFS.StreamOpen[fullFName, $write ! PFS.Error =>
IF ( error.code = $unknownFile ) AND ( how = $openOrCreate ) THEN
{ retry ¬ TRUE; DoCreate[]; CONTINUE } ELSE REJECT
];
IF retry THEN fileData.writeStream ¬ PFS.StreamOpen[fullFName, $write ! PFS.Error =>
Report["\n**** PFS.Error: %g, during PFSFileOpenOrCreate\n", [rope[error.explanation]]] ];
fileData.readStream ¬ PFS.StreamOpen[ fullFName ! PFS.Error =>
Report["\n**** PFS.Error: %g, during PFSFileOpenOrCreate\n", [rope[error.explanation]]] ];
EXITS cant => ERROR OpenFailed;
};
PFSSetByteCount: PROC [ fileData: BCFileData, bytes: INT ] ~ {
ro: REF BOOL ~ NARROW[fileData.clientData];
IF ro­ THEN RETURN;
fileData.writeStream ¬ PFS.StreamOpen[PFS.PathFromRope[fileData.name], $write ];
fileData.writeStream.SetLength[bytes];
fileData.writeStream.Close[];
fileData.writeStream ¬ NIL;
};
PFSIconSetter: PROC[iconFileName: ROPE] = {
iconFile: PFS.PATH ¬ PFSNames.ExpandName[PFS.PathFromRope[iconFileName], squirrelAwayMyStartingDir];
iconFileRope: ROPE ~ PFS.RopeFromPath[iconFile];
BlackCherry.msgSetIcon ¬ Icons.NewIconFromFile[iconFileRope, 1];
IF BlackCherry.msgSetIcon = unInit THEN BlackCherry.msgSetIcon ¬ tool
ELSE BlackCherry.msgIcon ¬ Icons.NewIconFromFile[iconFileRope, 2];
};
Init: PROC = {
procs: BlackCherry.FileProcs ¬ NEW[BlackCherry.FileProcsRec ¬ [
fullName: PFSFullName,
openOrCreate: PFSFileOpenOrCreate,
setByteCount: PFSSetByteCount,
iconSetter: PFSIconSetter
] ];
BlackCherry.RegisterFileProcs[procs];
squirrelAwayMyStartingDir ¬ PFS.GetWDir[];
};
Init[];
END.