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 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 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]); SELECT (C=.(SIGNAL_ARGS[SA_CODE])) 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]); SELECT (C=.(SIGNAL_ARGS[SA_CODE])) 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]); !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