File: PupErrors.mesa, Last Edit: BLyon January 16, 1981 2:50 PM
DIRECTORY
Rope USING [Fetch, Length, ROPE],
StatsDefs USING [StatIncr],
PupRouterDefs USING [SneakySendUnlocked],
PupStream USING [CloseReason],
PupDefs,
CommFlags USING [doStats, doDebug],
DriverDefs USING [
Glitch, Network, PutOnGlobalDoneQueue, GetDeviceChain],
BufferDefs, -- SHARES
PupTypes USING [allHosts, PupErrorCode, PupSocketID],
DriverTypes USING [bufferSeal];
PupErrors: PROGRAM
IMPORTS StatsDefs, PupRouterDefs, DriverDefs, PupDefs, Rope
EXPORTS BufferDefs, PupRouterDefs, PupStream, PupDefs
SHARES BufferDefs =
BEGIN OPEN DriverDefs, PupDefs;
Network: PUBLIC TYPE = DriverDefs.Network;
PktStream/ByteStream SIGNALs live here so they are defined only once
StreamClosing: PUBLIC ERROR [why: PupStream.CloseReason, text: Rope.ROPE] = CODE;
RejectThisRequest: PUBLIC ERROR [error: Rope.ROPE] = CODE;
suppressErrors: BOOLEANFALSE;
suppressBufferFull: BOOLEANFALSE;
BufferSealBroken: PUBLIC ERROR = CODE;
BufferDidntArrive: PUBLIC ERROR = CODE;
SetErrorSuppression: PUBLIC PROCEDURE [dontSendErrors: BOOLEAN] =
BEGIN suppressErrors ← dontSendErrors; END;
SetBufferFullSuppression: PUBLIC PROCEDURE [dontSend: BOOLEAN] =
BEGIN suppressBufferFull ← dontSend; END;
RejectPupWithBadChecksum: PUBLIC PROCEDURE [b: PupBuffer] =
BEGIN Reject[b, badChecksumPupErrorCode]; END;
Reject: PUBLIC PROCEDURE [b: PupBuffer, code: PupTypes.PupErrorCode] =
BEGIN
IF BuildErrorPup[b, code, NIL] THEN PupRouterDefs.SneakySendUnlocked[b];
END;
SendErrorPup: PUBLIC PROCEDURE [
b: PupBuffer, code: PupTypes.PupErrorCode, text: Rope.ROPE] =
BEGIN IF BuildErrorPup[b, code, text] THEN PupRouterSendThis[b]; END;
BuildErrorPup: PUBLIC PROCEDURE [
b: PupBuffer, code: PupTypes.PupErrorCode, text: Rope.ROPE]
RETURNS [ok: BOOLEAN] =
BEGIN
p: LONG POINTER TO ARRAY [0..9] OF WORD = LOOPHOLE[@b.pupLength];
temp: PupTypes.PupSocketID;
network: Network ← b.network;
IF CommFlags.doDebug AND b.seal # DriverTypes.bufferSeal THEN Glitch[BufferSealBroken];
IF suppressErrors OR
(suppressBufferFull AND code = resourceLimitsPupErrorCode) OR b.pupType =
error OR b.dest.host = PupTypes.allHosts THEN
BEGIN DriverDefs.PutOnGlobalDoneQueue[b]; RETURN[FALSE]; END;
IF CommFlags.doDebug AND network= NIL THEN Glitch[BufferDidntArrive];
IF network.netNumber.b > 377B THEN network ← DriverDefs.GetDeviceChain[];
FOR i: CARDINAL IN [0..9] DO b.errorHeader[i] ← p[i]; ENDLOOP;
b.pupType ← error;
b.errorCode ← code;
b.errorOptions ← 0;
temp ← b.dest.socket;
b.dest ← b.source;
b.source ← [[network.netNumber.b], [network.hostNumber], temp];
IF text = NIL THEN
SELECT code FROM
badChecksumPupErrorCode => text ← "Bad Software Checksum";
noProcessPupErrorCode => text ← "No such Port";
resourceLimitsPupErrorCode => text ← "Buffers full";
ENDCASE => NULL;
IF text # NIL THEN
BEGIN
length: INT = text.Length[];
FOR i: INT IN [0..length) DO b.errorText[i] ← text.Fetch[i]; ENDLOOP;
SetPupContentsBytes[b, 2*(10 + 1 + 1) + length];
END
ELSE SetPupContentsBytes[b, 2*(10 + 1 + 1) + 0];
IF CommFlags.doStats THEN StatsDefs.StatIncr[statErrorPupsSent];
RETURN[TRUE];
END;
END.