Trailing-Edge
-
PDP-10 Archives
-
decuslib10-08
-
43,50512/main.b36
There are no other files named main.b36 in the archive.
MODULE MAIN=
!The buck starts here
BEGIN
!
! Table of Contents
!
FORWARD ROUTINE
MAIN,
SAYCMD, !Type out "(Processing commands)"
NETCMD, !Process string as NETSPL commands
NETCMHANDLE, !Condition handler for NETCMD
HANDLE; !Condition handler for MAIN
!
! LIBRARY & REQUIRE files
!
REQUIRE 'INTR.REQ';
LIBRARY 'NODTBL'; !Need NODTBL defs too
!
THIS_IS[MAIN] VERSION [1] EDIT [7] DATE [19,DEC,79]
![7] Set DSKFUL ERROR, since PAUSE stops us dead!
!
!
! Builtin
!
BUILTIN MACHSKIP,MACHOP;
!
!External routines
!
EXTERNAL ROUTINE
GETTAB,
FAL,
SPL,
MOVEAZ,
GETVRS,
TERROR,
SCALLI,
CLKCHK,
FSTACK,
QUEFLS,
STOP,
ATTACH_TTY,
DOCMDS, !Process commands
IRESTART, !Code for if somebody trys to restart us
QUIT,
! FSIGNL,
UNWIND,
TTYINI,
ERTEXT,
TTYIN;
!
!External data
!
EXTERNAL
HIMSG: QSR$HI,
MJOBS, !Total # of simultaneous jobs allowed
MAXDRQ, !Max # of data requests we can set
MLEVEL: BLOCK FIELD(MLEVEL_FIELDS), !Message level
COMTAB, !Table of operator commands
TTYBLK: FILE_BLOCK, !File block for TTY
TTYINTBLK: INT_BLOCK, !Interrupt block for TTY
DETINTBLK: INT_BLOCK, !Interrupt for DETACH & ATTACH interrupts
QSRSTINT: INT_BLOCK, !Interrupt block for status change to QUASAR
TERMINAL, !Designator for terminal
PRIOUT, !Designator for primary output device
RUN:REF PROCESS_BLOCK;
!
!Literals
!
LITERAL INITIAL_NXFERS=1; !MJOB starts out as this value
LITERAL CNDVN=XWD(%O'71',%O'11'); !GETTAB for Monitor version #
LITERAL DSKFUL_ERROR=XWD(%O'21',1); !DSKFUL PAUSE blows us away!
LITERAL INITIAL_MAXDRQ=14; !Initial value of MAXDRQ
!
!Macros
!
MACRO PREFIX='CMD'%; !For MSG macro
MACRO SETUUO(ARG)=SCALLI(%O'75',ARG) %;
MACRO SETUWP(ARG)=SCALLI(%O'36',ARG) %;
MACRO MERGE(DEV,FILE,EXT,PPN)=
BEGIN
EXTERNAL ROUTINE GETSEG;
GETSEG(UPLIT(%SIXBIT%STRING(DEV),
%SIXBIT%STRING(FILE),0,0,0,0))
END%;
!
! Global Data
!
GLOBAL MONVER; !Monitor version we are using
!
!Routines
!
GLOBAL ROUTINE MAIN=
BEGIN
REGISTER T;
GLOBAL CMDPBLOCK: PROCESS_BLOCK;
GLOBAL CMDTMO: INT_BLOCK;
OWN LINE: VECTOR[CH$ALLOCATION(81)], PTR: INITIAL(CH$PTR(LINE));
ESTABLISH(HANDLE); !Condition handler
(EXTERNAL INTENC;INTENC=1); !Save interrupts 'till not busy
MONVER=((GETTAB(CNDVN)^-18) AND %O'77777');
!Get the current monitor version
MAXDRQ=(IF .MONVER GEQ %O'70000' THEN INITIAL_MAXDRQ ELSE 1);
!Never more than 1 drq for 6.03 or 6.03A
SETUUO(DSKFUL_ERROR); ![7] DSKFUL PAUSE blows us away!
MLEVEL[MLEVEL$ALL]=-1; !Set the message level to ALL
RUN=CMDPBLOCK; !We are the current process
CMDPBLOCK[P$STK]=FSTACK(); !The current stack is ours
CMDPBLOCK[P$FREE]=CMDPBLOCK[P$STKL]=0; !Never free anything
CMDPBLOCK[P$NAME]=%SIXBIT'CMD';
CMDPBLOCK[P$INFERIORS]=CMDPBLOCK[P$LINK]=0; !No inferiors or peers
CMDPBLOCK[P$SUPERIOR]=0; !There is no superior
CMDPBLOCK[P$DISPLAY]=SAYCMD; !Say what CMD process is doing
T=INTVEC; !Start of 4 word blocks
CALLI(T,%O'135'); !PIINI.
TTYINI(); !Initialize TTY interrupts
MERGE('SYS','NODTBL'); !Get the node table
WHILE SETUWP(0) EQL 0 DO !Write-enable the high segment
BEGIN
MSG('?',CRLF,'No write access to SYS:NODTBL.EXE');
STOP()
END;
!Now flush the IPCF queue
QUEFLS();
!Now initialize MJOB
MJOBS=(HIMSG[QSR$HI_MJOB]=INITIAL_NXFERS);
!Now initialize the QUASAR status change interrupt block
QSRSTINT[INT$SIGNAL_ARGS]=1;
QSRSTINT[INT$STSCODE]=QSRSTC;
QSRSTINT[INT$SEVERITY]=SS$_NORMAL;
QSRSTINT[INT$NEXT]=0;
!Now identify ourself
BEGIN
LOCAL PTR, STR: VECTOR[CH$ALLOCATION(132)];
EXTERNAL ROUTINE MOVEAZ,GETVRS;
PTR=CH$PTR(STR);
MOVEAZ(%REF(CH$PTR(UPLIT(%ASCIZ
'[NETRUN NETSPL version '))),PTR);
PTR=CH$PLUS(.PTR,GETVRS(.PTR,35)); !Get our version number
MOVEAZ(%REF(CH$PTR(UPLIT(%ASCIZ%STRING(
' running]',CRLF)))),PTR);
TSTR(STR);
END;
IRESTART(); !Handle restarts
!Initialization is now complete
!Command loop
WHILE 1 DO
BEGIN
LOCAL TI; !Index of timeout request
!!! TYPE('NETSPL>'); !Prompt
CLEARV(CMDTMO); !Zero out interrupt block
!No condition to signal, just wake up
TTYIN(.PTR,80); !Get a line of input
NETCMD(.PTR); !Process as commands
END;
END;
ROUTINE SAYCMD=
!Type out info about CMD process for WHAT command
!i.e. " --- (Processing commands)"
!
! Formal Parameters
!
!None
!
! Implicit inputs
!
!None
!
! Returned value
!
!None
!
! Implicit outputs
!
!None
BEGIN
TYPE(' --- (Processing commands)');
END; !SAYCMD
GLOBAL ROUTINE NETCMD(PTR)=
!Process a string as NETSPL commands
!PTR: Byte pointer (if .PTR<LH> NEQ {0,-1}) or address of string (otherwise)
BEGIN
EXTERNAL ROUTINE ERTEXT;
EXTERNAL ROUTINE DOCMDS;
LITERAL DELIMITERS=%C';'+%O'7600'; !Accept ";" & the usual line delimiters
LOCAL R;
ESTABLISH(NETCMHANDLE,.PTR); !Set up condition handler
SELECTONE .PTR<LH> OF SET
[0,%O'777777']: PTR=CH$PTR(.PTR); !Set up byte pointer
[OTHERWISE]: ;
TES;
IF (R=DOCMDS(COMTAB,PTR,DELIMITERS,%REF(0))) GTR 1^16
THEN (TSTR(ERTEXT(.R));TYPE(CRLF));
!Process commands & type error msg if needed
END; !NETCMD
ROUTINE NETCMHANDLE(SIGNAL_ARGS,MECH_ARGS,ENABLE_ARGS)=
!Condition handler for NETCMD (command processing routine)
BEGIN
MAP SIGNAL_ARGS: REF VECTOR,
MECH_ARGS: REF VECTOR,
ENABLE_ARGS: REF VECTOR;
!These are all argument lists of the form:
!length,arg1,arg2,arg3,arg4,... (words)
!length does not include the length word itself
EXTERNAL ROUTINE
FSIGNL, !Force a signal to another process
UNWIND, !Crawl back up the stack
ERTEXT; !Get text of error message
LOCAL
C, !Code
S; !Severity
S=.(SIGNAL_ARGS[SA_CODE])<SEVERITY>;
SELECT (C=.(SIGNAL_ARGS[SA_CODE])<STSCODE>) OF SET
!Fill in conditions here
[FILERR TO FILOPN,CMDERR TO CMDERR+%O'77',FPAERR TO FPAERR+%O'17']:
BEGIN
EXTERNAL ROUTINE TERROR;
TERROR(.SIGNAL_ARGS,.ENABLE_ARGS,.MECH_ARGS);
SELECT .S OF SET !Check severity
[SS$_WARN,SS$_NORMAL]:
BEGIN
RETURN SS$_CONTINUE
END;
[SS$_SEVEREERROR]:
BEGIN
CRASH(CRLF);
END;
[SS$_ERROR]:
BEGIN
UNWIND(.MECH_ARGS[MA_DEPTH]+1); !Unwind thru establisher
END;
TES
END;
[OTHERWISE]: RETURN SS$_RESIGNAL; !Pass the buck
TES;
END; !NETCMHANDLE
ROUTINE HANDLE(SIGNAL_ARGS,MECH_ARGS,ENABLE_ARGS)=
!Condition handler for MAIN
BEGIN
MAP SIGNAL_ARGS: REF VECTOR,
MECH_ARGS: REF VECTOR,
ENABLE_ARGS: REF VECTOR;
!These are all argument lists of the form:
!length,arg1,arg2,arg3,arg4,... (words)
!length does not include the length word itself
EXTERNAL ROUTINE
FSIGNL, !Force a signal to another process
ERTEXT; !Get text of error message
EXTERNAL RUN: REF PROCESS_BLOCK;
LOCAL
C, !Code
S; !Severity
S=.(SIGNAL_ARGS[SA_CODE])<SEVERITY>;
SELECT (C=.(SIGNAL_ARGS[SA_CODE])<STSCODE>) OF SET
!Fill in conditions here
[INFQIT]: !One of our inferiors just died
BEGIN
BIND RFORK=.SIGNAL_ARGS[2]: PROCESS_BLOCK;
EXTERNAL ROUTINE REMINF;
BIND RFORK_NAME=.RFORK[P$NAME]; !Save process name
BIND REASON=.(SIGNAL_ARGS[3])<STSCODE>; !and error code
REMINF(RFORK); !Out of linked lists, etc.
!Note that we cannot access RFORK or SIGNAL_ARGS now
SELECTONE REASON OF SET
[OPRABO,QSRNRN]:;
[OTHERWISE]:
BEGIN !Try to restart it
UNDECLARE %QUOTE PREFIX;
OWN MAXRESTART: INITIAL(100);
SELECT RFORK_NAME OF SET
[PNAME(FAL)]:
BEGIN
OWN FALCR: INITIAL(0);
IF (FALCR=.FALCR+1) GTR .MAXRESTART
THEN BEGIN
MACRO PREFIX='FCH'%;
WRN('FAL crash rate too high')
END
ELSE BEGIN
MACRO PREFIX='FRS'%;
INFO('Restarting FAL');
FORK(FAL);
END;
END;
[PNAME(SPL)]:
BEGIN
OWN SPLCR: INITIAL(0);
IF (SPLCR=.SPLCR+1) GTR .MAXRESTART
THEN BEGIN
MACRO PREFIX='SCH'%;
WRN('SPL crash rate to high');
END
ELSE BEGIN
MACRO PREFIX='SRS'%;
INFO('Restarting SPL');
FORK(SPL);
END;
END;
TES;
END;
TES;
RETURN SS$_CONTINUE !On our way
END;
[FRKEND]:
RETURN SS$_CONTINUE;
[REATTA]:
BEGIN !We got attached or detached
LOCAL TTY; !TTY # of new TTY
IF (TTY=.SIGNAL_ARGS[SA_STATUS]) EQL _PCDAT_DETACH
THEN BEGIN
TERMINAL=0;
END
ELSE BEGIN
UNDECLARE %QUOTE PREFIX;
MACRO PREFIX='ATT'%; !For MSG Macro
IF .TTY EQL 0 THEN RETURN SS$_CONTINUE;
!Ignore spurious interrupts!!!
PRIOUT=TERMINAL=(.TTY<0,9> + TTYDESIG);
!Set up terminal designator for new TTY
NOINTS ((
ATTACH_TTY(.TERMINAL);
MSG('[','','NETSPL re-attached to TTY');
TNUM(.TERMINAL<0,9>,8);
TYPE(']',CRLF);
TTYINI();
))
END;
RETURN SS$_CONTINUE;
END;
[OTHERWISE]:
BEGIN
EXTERNAL ROUTINE TERROR;
TERROR(.SIGNAL_ARGS,.MECH_ARGS,.ENABLE_ARGS);
SELECT .S OF SET !Check severity
[SS$_NORMAL,SS$_WARN]: BEGIN
RETURN SS$_CONTINUE
END;
[SS$_SEVEREERROR]: CRASH();
[SS$_ERROR]: BEGIN
LOCAL PQUIT: VECTOR[4];
IF .RUN[P$SUPERIOR] EQL 0
THEN CRASH(' at top level');
!Boy, are we in trouble!
QUIT(.SIGNAL_ARGS[SA_CODE]);
END;
TES
END;
TES
END; !HANDLE
END ELUDOM