.TITLE CATSPN - Catchall Spawn Routines .IDENT /2.0/ .ENABL LC ;+ ; ; Free software BY ; Project Software & Development, Inc. ; ; This software is furnished for free and may be used and copied as ; desired. This software or any other copies thereof may be provided or ; otherwise made available to any other person. No title to and ; ownership of the software is hereby transferred or allowed. ; ; The information in this software is subject to change without notice ; and should not be construed as a commitment by PROJECT SOFTWARE ; AND DEVELOPMENT, INC. ; ; PROJECT SOFTWARE assumes no responsibility for the use or reliability ; of this software on any equipment whatsoever. ; ; Project Software & Development, Inc. ; 14 Story St. ; Cambridge, Ma. 02138 ; 617-661-1444 ; ; ; Title: CATSPN.MAC ; Author: Robin Miller ; Date: July 19, 1982 ; ; Description: ; ; This module contains the spawn routines for Catchall. ; ;- .NLIST BEX .MCALL DIR$, GIN$, RPOI$S, SPWN$S, STSE$S .SBTTL Modification History ;+ ; ; Modification History: ; ; September 17, 1984 by Robin Miller. ; Rename our task name from xxxTnn to CATTnn when spawning a ; privileged task from a non-privileged terminal to avoid a ; task name conflict. ; ; September 11, 1984 by Robin Miller. ; Use the Request and Pass Offspring Information (RPOI$) directive ; if we're spawning a non-privileged task, a privileged task from ; a privileged terminal, or not spawning multiple command lines. ; ; September 10, 1984 by Robin Miller. ; Spawn the command directly to DCL (if a DCL command) instead of ; spawning to MCR via "DCL command_line". ; ;- ; Local definitions: RE.NAM = 4 ; Offset to GI.REN task name. ; Local/global storage area: MCRNAM: .RAD50 /MCR.../ ; Radix-50 for MCR dispatcher. DCLNAM: .RAD50 /...DCL/ ; Radix-50 for DCL dispatcher. DORPOI: .WORD 0 ; Use RPOI$ directive flag. DOREN: .WORD 0 ; Need to rename the task name. GINREN: GIN$ GI.REN,0,0 ; GIN$ directive to rename task. SPNEST::.BLKW 8. ; SPAWNED EXIT STATUS BLOCK SPWAIT::.WORD 0 ; WAIT FOR SPAWNED TASK -1/0 = YES/NO .SBTTL SPAWN -- Spawn MCR Command Line. ;+ ; ; SPAWN - Spawn a command line to the MCR. ; ; This subroutine spawns a command to the MCR dispatcher. ; ; If CAT has the "MCR prompt on exit bit" cleared, a presumption is made ; that the command was spawned from indirect (@). It could also be cleared ; if the command was terminated by an . A normal command should be ; terminated by which sets T3.MCR. If it is clear, we will wait for ; the spawned task to complete so that indirect doesn't continue before the ; spawned task exits. If CAT doesn't wait, indirect continues with the next ; command as soon as CAT spawns and exits (this is usually undesirable). ; ; The Request & Pass Offspring Information (RPOI$) directive is used if the ; command is non-privileged, the terminal is privileged, and a single line ; is being spawned. This allows catchall to exit in more cases than before. ; ; Inputs: ; SPNBUF = the command line to spawn. ; SAVTBL = the address of the command table entry. ; ; Outputs: ; R0 = Exit status of spawned task (if wait requested). ; If the Spawn directive is refused for any reason, the ; task will exit using $DSW as the exit status. ; ; All registers are preserved. ; ;- SPAWN:: CALL $SAVAL ; SAVE R0 - R5 MOV SAVTBL,R5 ; COPY THE TABLE ENTRY ADDRESS ; Determine if this command requires the terminal to be privileged. CLR SPWAIT ; PRESUME NOT WAITING FOR SPAWN BIT #B.PRIV,O.STAT(R5) ; IS THIS A PRIVILEGED COMMAND ? BEQ 5$ ; IF EQ, NO CALL SETPRV ; YES, SET THE TERMINAL PRIVILEGED 5$: BIT #B.MULT,O.STAT(R5) ; MULITPLE COMMAND LINES ? BEQ 10$ ; IF EQ, NO MOV #-1,SPWAIT ; ELSE, SHOW WE MUST WAIT ; Determine which CLI (MCR or DCL) to spawn to. 10$: MOV #SPNBUF,R0 ; PRESUME MCR COMMAND ;*** BIT #B.DCL,O.STAT(R5) ; IS IT A DCL COMMAND ? ;*** BEQ 20$ ; IF EQ, NO ;*** MOV #DCLBUF,R0 ; ELSE SPAWN DCL TO MCR ; Find the end of the command line to spawn. 20$: MOV R0,R1 ; COPY THE BUFFER ADDRESS 30$: TSTB (R1)+ ; END OF COMMAND LINE ? BNE 30$ ; IF NE, NO (LOOP) DEC R1 ; POINT TO THE NULL TERMINATOR ; Set DORPOI flag if we don't have to wait for command. BIT #B.MULT,O.STAT(R5) ; Spawning multiple command lines ? BNE 40$ ; If NE, yes (we must wait). BIT #S.SPRV,STATUS ; Was the terminal set privileged ? BNE 40$ ; If NE, yes (wait to set non-priv). INC DORPOI ; We can use the RPOI$ directive. BR 50$ ; And continue ... ; ; If not exiting to the MCR, presume the command came from the ; indirect command processor (ICP) and wait for the task. This ; is only needed if executing the command via SPWN$ directive. ; 40$: BIT #S.EMCR,STATUS ; ARE WE EXITING TO THE MCR ? BNE 50$ ; IF NE, YES MOV #-1,SPWAIT ; NO, WE MUST WAIT THEN ; If waiting on the spawned command, inhibit an MCR prompt. 50$: TST STATUS ; IS DEBUGGING OUTPUT ON ? BMI 60$ ; IF MI, YES (APPEND ) TST SPWAIT ; WAITING FOR SPAWNED TASK ? BEQ 60$ ; IF EQ, NO MOVB #ESC,(R1)+ ; TERMINATE COMMAND WITH ESCAPE BR 70$ ; AND CONTINUE ... ; Append the original command terminator. 60$: MOVB TBYTE,(R1)+ ; Append the original terminator. ; MOVB #CR,(R1)+ ; APPEND TO FORCE MCR PROMPT ; Ensure the command line isn't too long for the MCR. 70$: SUB R0,R1 ; CALCULATE THE BYTE COUNT CMP R1,#80. ; IS THE COMMAND TOO LONG ? BLE 80$ ; IF LE, NO (CONTINUE) JMP ERR4 ; TAKE ERROR EXIT IF IT IS ; If debugging is on, write the command line to the terminal. 80$: TST STATUS ; IS DEBUGGING OUTPUT ENABLED ? BPL 85$ ; IF PL, NO CALL WRITE ; OUTPUT THE COMMAND LINE MOV $DSW,R0 ; COPY THE DIRECTIVE STATUS BR 110$ ; AND CONTINUE ... ; Finally, spawn the command line to the MCR or DCL. 85$: MOV #MCRNAM,R2 ; Presume spawning to MCR dispatcher. BIT #B.DCL,O.STAT(R5) ; Is this a DCL command ? BEQ 87$ ; If EQ, no. MOV #DCLNAM,R2 ; Yes, spawn to DCL dispatcher. ; Spawn the command line via RPOI$ or SPWN$ directives. 87$: TST DORPOI ; Can be use the RPOI$ directive ? BEQ 88$ ; IF EQ, no (we must use SPAWN). RPOI$S R2,,,,,,R0,R1,#RP.OEX!RP.ONX ; Shouldn't return from this. MOV $DSW,R0 ; Copy the directive error code. CMP R0,#IE.SDP ; Is error "No RPOI$ directive" ? BNE 100$ ; If NE, no (exit with error code). ; Else, use the spawn directive. 88$: CALL RENTSK ; Rename our task name to "CATTnn". ;*** BCS 89$ ; If CS, the rename failed. SPWN$S R2,,,,,#SPNEFN,,#SPNEST,R0,R1,, ; SPAWN CLI WITH COMMAND BCC 90$ ; IF CC, DIRECTIVE OK 89$: MOV $DSW,R0 ; SAVE $DSW FOR EXIT STATUS BR 100$ ; AND RETURN WITH THE STATUS 90$: MOV #EX$SUC,R0 ; DEFAULT EXIT STATUS TST SPWAIT ; SHOULD WE WAIT ON THE COMMAND ? BNE 95$ ; IF NE, YES BIT #S.SPRV,STATUS ; WAS THE TERMINAL SET PRIVILEGED ? BEQ 100$ ; IF EQ, NO ; ELSE, WE WAIT ON SPAWNED COMMAND ; SO THE PRIVILEGE CAN BE RESET) ; Wait for the command just spawned. 95$: STSE$S #SPNEFN ; STOP FOR THE SPAWNED TASK MOV SPNEST,R0 ; GET SPAWNED EXIT STATUS ; Determine if we should exit immediately. 100$: CALL NOPRIV ; RESET THE TERMINAL PRIVILEGE CALL QUIET ; ELSE, SET TO EXIT QUIETLY 110$: MOV R0,2(SP) ; PASS BACK THE STATUS IN R0 RETURN ; RETURN WITH C/SET-C/CLR .SBTTL RENTSK - Rename Our Task Name. ;+ ; ; RENTSK - Rename our task name. ; ; This routine is used to rename our task name when we're spawning a ; privileged command. This must be done to avoid a task name confict with ; the command being spawned. On RSX-11M+, catchall is started with the ; task name xxxTnn where 'xxx' is the first three characters of the command. ; On RSX-11M, catchall is started under the name CATTnn which is desirable ; when spawning multiple or privileged commands. ; ; Inputs: ; None. ; ; Outputs: ; C bit clear/set = success/failure. ; ; All registers are preserved. ; ;- RENTSK: JSR R2,$SAVVR ; Save R0 - R2. TST DOREN ; Has the rename already be done ? BNE 10$ ; If NE, yes (do only once). MOV #GINREN,R0 ; Set $GIN DPB address. MOV #^RCAT,RE.NAM(R0) ; Set first part of task name. MOV TSKBUF+G.TSTN+2,RE.NAM+2(R0) ; Set last part of task name. DIR$ R0 ; Rename our task name. 10$: RETURN .END