.title fel ; ; ; this program is used to kill all subprocesses hanging off of ; the shell invoked from MCR via the shl [args] command. ; It may also be used to fel a background process tree when ; invoked via ; ; fel taskname ; ; it is called fell since it fells the process tree. ; ; it works by sending a message to $Tnn.1, which propagates the ; message to its child, and so on. If for some reason $Tnn.1 ; is not installed and running, fell prints an error message ; with the directive status word value ; ; this program should be installed as ...fel for efficient ; use by the user ; ; This program has been rewritten in assembler due to ; large memory requirements of its predecessor. ; ; .mcall alun$s,glun$s,sdat$s,exit$s,qiow$s,gmcr$,dir$ ; ; local constants ; ttylun=1 ; lun for terminal io qioefn=1 ; event flag for qios blank=40 ; ASCII code for blank cr=15 ; ASCII code for carriage return lf=12 ; ASCII code for line feed esc=33 ; ASCII code for escape ; ; ; local impure storage ; ; gmcrpb: gmcr$ ; get MCR block lunbuf: .blkw 6 ; buffer for GLUN$ octnum: .blkb 4 ; 6 byte buffer for $cbomg unit: .blkb 2 ; these 2 bytes will have the unit # outbuf: .byte cr,lf ; formatting buffer for error processor obuf: .blkb 132. ; remainder of buffer buf: .blkb 132. ; buffer for formatting number: .blkb 10. ; buffer for error status ; ; ; local pure storage ; ; ermsg1: .asciz "Error interrupting " ermsg2: .asciz ", status = " ; ; buffer for child taskname follows ; tfil: .ascii "$" devc: .blkb 1 ; will have the device character (T) tnum: .blkb 2 .asciz ".1" .even ; ; task name for send data invocation ; task: .rad50 " " ; ; start of fel code ; ; ; ; now we must generate the task name for the child - $Tnn.1 ; ; start: alun$s #ttylun,#"TI,#0 ; assign lun to terminal dir$ #gmcrpb ; get MCR command line bcs nocmd ; none to fetch mov @#$dsw,r0 ; length of command line mov #gmcrpb+g.mcrb,r1 ; address of command 10$: cmpb (r1)+,#' ; BLANK? beq 20$ ; YES sob r0,10$ ; try again br nocmd ; just invoked as FEL 20$: dec r0 ; account for blank beq nocmd ; trailing blank in command line? mov #6,r2 ; need six characters in task name mov #tfil,r3 ; output buffer 30$: movb (r1)+,(r3)+ ; copy next character dec r2 ; decrement counter beq 40$ ; done sob r0,30$ ; do again 35$: movb #' ,(r3)+ ; fill with blanks sob r2,35$ ; do again 40$: clrb (r2) ; EOS terminate br cvt ; convert to rad50 nocmd: glun$s #ttylun,#lunbuf ; get lun info mov #octnum,r0 ; string to format into movb lunbuf+g.lunu,r1 ; value to format mov #1,r2 ; desire leading zeroes call $cbomg ; convert to octal magnitude movb lunbuf+g.luna,devc ; overwrite devc with ch movb unit,tnum ; copy first number of unit movb unit+1,tnum+1 ; copy second number of unit ; ; ; the next few lines convert the ascii task name to rad50 ; cvt: mov #tfil,r0 ; address of ascii string mov #1,r1 ; period doesn't terminate call $cat5b ; convert first word mov r1,task ; save first word mov #1,r1 ; period doesn't terminate call $cat5b ; convert second word mov r1,task+2 ; save second word sdat$s #task,#obuf mov $dsw,r1 ; get status blt errsnd ; send error done: exit$s errsnd: mov #number,r0 clr r2 call $cbdsg clrb (r0) mov #ermsg1,r1 mov #buf,r0 call scopy mov #tfil,r1 call scopy mov #ermsg2,r1 call scopy mov #number,r1 call scopy mov #buf,r0 jmp errmsg ; ; ; routine to calculate the length of the zero byte terminated ; string pointed to by r1. length returned in r0, r1 is left ; unmodified ; ; length: clr r0 ; initialize count mov r1,-(sp) ; save r1 1$: tstb (r1)+ ; see if 0 byte beq 2$ ; yes, done inc r0 br 1$ 2$: mov (sp)+,r1 ; restore r1 return ; ; ; routine to copy 0-byte terminated string pointed to by r1 ; to string pointed to by r0. r1 is left pointing to character ; after z byte, and r0 points to next available location ; scopy: movb (r1)+,(r0)+ ; copy byte bne scopy ; try again tstb -(r0) ; backup one byte return ; ; ; routine to display error message on terminal. address of ; zero byte terminated message is passed in r0 ; ; errmsg: mov r0,r1 ; going to scopy into buffer mov #obuf,r0 ; destination call scopy ; copy string mov #outbuf,r1 ; calculate length call length ; length in r0 qiow$s #io.wlb,#ttylun,#qioefn,,,, br done ; exit .end start