| 1 | ZJOB ;ISF/RWF - GT.M Job Exam ;8/15/07  16:28
 | 
|---|
| 2 |  ;;8.0;KERNEL;**349**;Jul 10, 1995;Build 2
 | 
|---|
| 3 |  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 | 
|---|
| 4 |  ; Various edits between Wally, Dave Whitten, Bhaskar,           ;
 | 
|---|
| 5 |  ; and Chris Richardson over a period of time.                   ;
 | 
|---|
| 6 |  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 | 
|---|
| 7 |  ;;
 | 
|---|
| 8 |  ;PID is decimal job number.
 | 
|---|
| 9 |  I $ZV'["GT.M" W !,"This is for GT.M only" Q
 | 
|---|
| 10 |  N PID,HEXPID,DTIME
 | 
|---|
| 11 |  S DTIME=600
 | 
|---|
| 12 | RPID ; Request the PID
 | 
|---|
| 13 |  F  D   Q:"^"[PID
 | 
|---|
| 14 |  . S PID=$$ASKJOB
 | 
|---|
| 15 |  . D:PID>0
 | 
|---|
| 16 |  . . N ACTION
 | 
|---|
| 17 |  . . S ACTION="L"
 | 
|---|
| 18 |  . . D DOIT
 | 
|---|
| 19 |  . . F  D ASK Q:ACTION="^"  D DOIT Q:ACTION="^"
 | 
|---|
| 20 |  . .Q
 | 
|---|
| 21 |  .Q
 | 
|---|
| 22 |  ; Single Exit
 | 
|---|
| 23 |  W !!
 | 
|---|
| 24 |  Q
 | 
|---|
| 25 |  ;
 | 
|---|
| 26 | ASK ; Ask for user input
 | 
|---|
| 27 |  R !,"Job Exam Action: L//",ACTION:DTIME
 | 
|---|
| 28 |  S:'$T ACTION="^"
 | 
|---|
| 29 |  S:ACTION="" ACTION="L"
 | 
|---|
| 30 |  I ACTION["^" Q  ;Exit
 | 
|---|
| 31 |  ;
 | 
|---|
| 32 |  ;first non-space, UPPER character
 | 
|---|
| 33 |  S ACTION=$TR($E($TR(ACTION," ")),"klsv","KLSV")
 | 
|---|
| 34 |  Q
 | 
|---|
| 35 |  ;
 | 
|---|
| 36 | DOIT ; Action Prompt
 | 
|---|
| 37 |  I ACTION="S" D ^ZSY  S ACTION="L" ;FALLTHRU
 | 
|---|
| 38 |  I ACTION="L"!(ACTION="V") D DISPLAY(PID,ACTION) Q
 | 
|---|
| 39 |  I ACTION="*" D LOAD^ZJOB1 S ACTION="^" Q
 | 
|---|
| 40 |  I ACTION="K" W !,"Sorry Kill Job not supported yet" Q  ;G ACTION
 | 
|---|
| 41 |  ; All Else
 | 
|---|
| 42 |  W:ACTION'="?" !,"Unknown Action received"
 | 
|---|
| 43 |  ;ACTION["?"
 | 
|---|
| 44 |  W !,"Enter '^' to choose another JOB "
 | 
|---|
| 45 |  W !,"Enter 'L' to display status information about other Job"
 | 
|---|
| 46 |  W !,"Enter 'S' to display current System Status"
 | 
|---|
| 47 |  W !,"Enter 'V' to display local variables of other job"
 | 
|---|
| 48 |  W !,"Enter '*' to load other job's symbol table into current job and Q"
 | 
|---|
| 49 |  W !,"Enter 'K' to send a Kill Job command to other job"
 | 
|---|
| 50 |  Q
 | 
|---|
| 51 |  ;
 | 
|---|
| 52 | ASKJOB() ;Ask for Job PID/Commands
 | 
|---|
| 53 |  N PID
 | 
|---|
| 54 |  W !!,"Examine Another JOB Utility "
 | 
|---|
| 55 |  F   S PID=$$RDJNUM  Q:PID="^"  Q:PID=+PID
 | 
|---|
| 56 |  Q PID
 | 
|---|
| 57 |  ;
 | 
|---|
| 58 | RDJNUM() ;
 | 
|---|
| 59 |  N INP,PID
 | 
|---|
| 60 |  S INP=""
 | 
|---|
| 61 |  R !,"Enter JOB number: ",INP:DTIME S:'$T INP="^"
 | 
|---|
| 62 |  S INP=$TR(INP,"hlsv","HLSV")
 | 
|---|
| 63 |  I "^"[INP Q "^"  ;abend
 | 
|---|
| 64 |  ;
 | 
|---|
| 65 |  I INP["?" D  Q " "
 | 
|---|
| 66 |  . W !,"To display information about another Job"
 | 
|---|
| 67 |  . W !,"   enter JOB number in Hexidecimal or Decimal"
 | 
|---|
| 68 |  . W !,"   Enter Hexadecimal with a leading/trailing 'h' "
 | 
|---|
| 69 |  . W !,"To display current System Status enter S"
 | 
|---|
| 70 |  . W !,"To exit enter ^"
 | 
|---|
| 71 |  .Q
 | 
|---|
| 72 |  I INP["S" D ^ZSY Q " " ;
 | 
|---|
| 73 |  ;
 | 
|---|
| 74 |  ; good hex or decimal number
 | 
|---|
| 75 |  S PID=$TR(INP,"abcdefh","ABCDEFH")
 | 
|---|
| 76 |  I $L($TR(PID,"0123456789ABCDEFH","")) D  Q " "
 | 
|---|
| 77 |  . W !,"Invalid character in JOB number."
 | 
|---|
| 78 |  .Q
 | 
|---|
| 79 |  ;
 | 
|---|
| 80 |  ;If in Hex, Convert PID to decimal
 | 
|---|
| 81 |  I PID["H" S PID=$$DEC($TR(PID,"H")) ; ...and continue
 | 
|---|
| 82 |  ; good job number but it is your own job.  Don't go there...
 | 
|---|
| 83 |  I PID=$JOB D  Q " "
 | 
|---|
| 84 |  . W !,"Can't EXAMINE your own process."
 | 
|---|
| 85 |  .Q
 | 
|---|
| 86 |  ;
 | 
|---|
| 87 |  ; VA check to see if a GTM job exists.
 | 
|---|
| 88 |  I $L($T(XUSCNT)),'$$CHECK^XUSCNT(PID) W !,"Not running thru VA kernel." ;decimal job
 | 
|---|
| 89 |  ;
 | 
|---|
| 90 |  ;W !,"JOB #",PID," does not exist"
 | 
|---|
| 91 |  ;Q " " ; bad job number so re-ask
 | 
|---|
| 92 |  Q PID
 | 
|---|
| 93 |  ;
 | 
|---|
| 94 | INTRPT(JOB) ;Send MUPIP intrpt
 | 
|---|
| 95 |  N $ET,$ES S $ET="D IRTERR^ZJOB"
 | 
|---|
| 96 |  ; shouldn't interrupt ourself
 | 
|---|
| 97 |  I JOB=$JOB Q 0
 | 
|---|
| 98 |  ;We need a LOCK to guarantee commands from two processes don't conflict
 | 
|---|
| 99 |  N X,OLDINTRPT,TMP,ZSYSCMD,ZPATH,%J
 | 
|---|
| 100 |  L +^XUTL("XUSYS","COMMAND"):10 Q:'$T 0
 | 
|---|
| 101 |  ;
 | 
|---|
| 102 |  S ^XUTL("XUSYS","COMMAND")="EXAM",^("COMMAND",0)=$J_":"_$H
 | 
|---|
| 103 |  K ^XUTL("XUSYS",JOB,"JE")
 | 
|---|
| 104 |  S OLDINTRP=$ZINTERRUPT,%J=$J
 | 
|---|
| 105 |  S TMP=0,$ZINTERRUPT="S TMP=1"
 | 
|---|
| 106 |  ;
 | 
|---|
| 107 |  I $ZV["VMS" S JOB=$$HEX(JOB),%J=$$HEX(%J)
 | 
|---|
| 108 |  S ZSYSCMD="mupip intrpt "_JOB ; interrupt other job
 | 
|---|
| 109 |  I $ZV["VMS" S ZPATH="@gtm$dist:"  ; VMS path
 | 
|---|
| 110 |  ;E  S ZPATH="sudo $gtm_dist" ;$ztrnlnm("gtm_dist") ;Unix path
 | 
|---|
| 111 |  E  S ZPATH="$gtm_dist/" ;Unix path
 | 
|---|
| 112 |  W !,"Send intrp to job. Any error means you don't have the privilege to intrpt.",!
 | 
|---|
| 113 |  ZSYSTEM ZPATH_ZSYSCMD ; System Request
 | 
|---|
| 114 |  ;Now send to self
 | 
|---|
| 115 |  ;
 | 
|---|
| 116 |  ;ZSYSTEM ZPATH_"mupip intrpt "_%J
 | 
|---|
| 117 |  ; wait is too long 60>>30
 | 
|---|
| 118 |  H 1 S TMP=1
 | 
|---|
| 119 |  ; wait for interrupt, will set TMP=1
 | 
|---|
| 120 |  ;F X=1:1:30 H 1 Q:TMP=1  ;ZINTERRUPT does not stop a HANG
 | 
|---|
| 121 |  ; Restore old $ZINTERRPT
 | 
|---|
| 122 |  S $ZINTERRUPT=OLDINTRP
 | 
|---|
| 123 |  K ^XUTL("XUSYS","COMMAND") ;Cleanup
 | 
|---|
| 124 |  L -^XUTL("XUSYS","COMMAND")
 | 
|---|
| 125 |  Q TMP  ;Report if we received interrupt
 | 
|---|
| 126 |  ;
 | 
|---|
| 127 | ITRERR ;Handle error during Interrupt
 | 
|---|
| 128 |  U $P W !,"Error: ",$ES
 | 
|---|
| 129 |  S $ET="Q:($ES&$Q) 0 Q:$ES  S $EC="""" Q 0"
 | 
|---|
| 130 |  Q
 | 
|---|
| 131 |  ;
 | 
|---|
| 132 | DISPLAY(JOB,ACTION) ;Display Job info, L is always the default.  No need to test for it.
 | 
|---|
| 133 |  ; The "L" header is part of the "V" Option
 | 
|---|
| 134 |  ;Send the interupt
 | 
|---|
| 135 |  I '$$INTRPT(JOB) W !,"Unable to Examine JOB, please retry later" Q
 | 
|---|
| 136 |  D DISPL ;Show Header
 | 
|---|
| 137 |  I ACTION="V" D DISPV ;Show symbol table
 | 
|---|
| 138 |  Q
 | 
|---|
| 139 |  ;
 | 
|---|
| 140 | DISPL ; ACTION="L" means single page info
 | 
|---|
| 141 |  ; Show short job info
 | 
|---|
| 142 |  ; Current Routine and Line Number  ;Current Line Executing
 | 
|---|
| 143 |  D GETINFO
 | 
|---|
| 144 |  S HEXJOB="" I $ZV["VMS" S HEXJOB=$$HEX(JOB)
 | 
|---|
| 145 |  W !,"JOB #: "_JOB W:$L(HEXJOB) " ("_HEXJOB_")" W ?40,"Process Name: "_$G(^XUTL("XUSYS",JOB,"NM"))
 | 
|---|
| 146 |  W !,"Device: "_$P($G(^XUTL("XUSYS",JOB,"JE","D",1))," ")
 | 
|---|
| 147 |  W !,"Process State: "_PS W:$L(IMAGE) ?40,"IMAGE: "_IMAGE_" ("_INAME_")"
 | 
|---|
| 148 |  W !,"JOB Type: "_JTYPE,?25,"CPU Time: "_CTIME,?50,"Login time: "_LTIME
 | 
|---|
| 149 |  W !!,"Routine line: <"_$G(^XUTL("XUSYS",JOB,"INTERRUPT"))_">"
 | 
|---|
| 150 |  W !,CODELINE
 | 
|---|
| 151 |  Q
 | 
|---|
| 152 |  ;
 | 
|---|
| 153 |  ; No Symbol Residue from this module.  The following are ephemeral
 | 
|---|
| 154 |  ; S - Information Type
 | 
|---|
| 155 |  ; I - Variable
 | 
|---|
| 156 | DISPV ; ACTION="V"  ; lookup how XTER is doing variable handling...
 | 
|---|
| 157 |  ; print $ZGBLDIR and $ZROUTINES
 | 
|---|
| 158 |  N C,I,S
 | 
|---|
| 159 |  F S="Stack","Locks","Devices","Intrinsic Variables","Variables"    D
 | 
|---|
| 160 |  . S C=$E(S),I=""
 | 
|---|
| 161 |  . D:$D(^XUTL("XUSYS",JOB,"JE",C))  W !
 | 
|---|
| 162 |  . . W !,"Section "_S
 | 
|---|
| 163 |  . . F  S I=$O(^XUTL("XUSYS",JOB,"JE",C,I)) Q:I=""  W !,^(I)
 | 
|---|
| 164 |  . . Q
 | 
|---|
| 165 |  . Q
 | 
|---|
| 166 |  Q
 | 
|---|
| 167 |  ;  ==============
 | 
|---|
| 168 | GETINFO ; Identify the Target Process's state.
 | 
|---|
| 169 |  ; Setup, process state > ps, Image name > iname, CPU time > ctime, Login time > ltime
 | 
|---|
| 170 |  S (PS,INAME,CTIME,LTIME,JTYPE,IMAGE,CODELINE)=""
 | 
|---|
| 171 |  S CODELINE=$G(^XUTL("XUSYS",JOB,"codeline"))
 | 
|---|
| 172 |  I $zv["VMS" D VSTATE  Q
 | 
|---|
| 173 |  ; Assume Unix as default
 | 
|---|
| 174 |  D USTATE
 | 
|---|
| 175 |  Q
 | 
|---|
| 176 |  ;
 | 
|---|
| 177 | VSTATE ; VMS get Process state
 | 
|---|
| 178 |  S TNAME=$ZGETJPI(JOB,"TERMINAL"),NM=$ZGETJPI(JOB,"prcnam")
 | 
|---|
| 179 |  S JTYPE=$ZGETJPI(JOB,"jobtype"),PS=$ZGETJPI(JOB,"state")
 | 
|---|
| 180 |  S LTIME=$$DATETIME($ZGETJPI(PID,"LOGINTIM")),CTIME=$$CPUTIME($ZGETJPI(JOB,"cputim"))
 | 
|---|
| 181 |  Q
 | 
|---|
| 182 |  ;
 | 
|---|
| 183 | DATETIME(HOROLOG) ;
 | 
|---|
| 184 |  Q $ZDATE(HOROLOG,"DD-MON-YY 24:60:SS","Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec")
 | 
|---|
| 185 |  ;
 | 
|---|
| 186 | CPUTIME(S) ; Calculate the VMS CPU time from first argument, S
 | 
|---|
| 187 |  N T,SS,M,H,D
 | 
|---|
| 188 |  S T=S#100,S=S\100 S:$L(T)=1 T="0"_T
 | 
|---|
| 189 |  S SS=S#60,S=S\60 S:$L(SS)=1 SS="0"_SS
 | 
|---|
| 190 |  S M=S#60,S=S\60 S:$L(M)=1 M="0"_M
 | 
|---|
| 191 |  S H=S#24,D=S\24 S:$L(H)=1 H="0"_H
 | 
|---|
| 192 |  Q D_" "_H_":"_M_":"_SS_"."_T
 | 
|---|
| 193 |  ;
 | 
|---|
| 194 | BLINDPID ;
 | 
|---|
| 195 |  N ZE S ZE=$ZS,$EC=""
 | 
|---|
| 196 |  I ZE["NOPRIV" S NOPRIV=1
 | 
|---|
| 197 |  Q
 | 
|---|
| 198 |  ; MAY BE REDUNDANT OR WRONG
 | 
|---|
| 199 | USTATE ;UNIX Process state.
 | 
|---|
| 200 |  N %FILE,%TEXT,U,%J,ZCMD,$ET,$ES
 | 
|---|
| 201 |  S $ET="D UERR^ZJOB",STATE="",U="^"
 | 
|---|
| 202 |  S %FILE="/tmp/_gtm_sy_"_$J_".tmp"
 | 
|---|
| 203 |  ;S ZCMD="ps ef -C mumps >"_%FILE ;| grep "_JOB_">"_%FILE
 | 
|---|
| 204 |  S ZCMD="ps eo pid,tty,stat,time,etime,cmd -C mumps >"_%FILE ;| grep "_JOB_">"_%FILE
 | 
|---|
| 205 |  ;W !,ZCMD
 | 
|---|
| 206 |  ZSYSTEM ZCMD
 | 
|---|
| 207 |  O %FILE:(readonly)
 | 
|---|
| 208 |  ; Get only line of text from temp file
 | 
|---|
| 209 |  U %FILE
 | 
|---|
| 210 |  F EXIT=0:0 R %TEXT Q:%TEXT=""  D  Q:EXIT
 | 
|---|
| 211 |  . Q:+%TEXT'=JOB
 | 
|---|
| 212 |  . S %TEXT=$$VPE(%TEXT," ",U) ; parse each line of the ps output
 | 
|---|
| 213 |  . S TNAME=$P(%TEXT,U,2),PS=$P(%TEXT,U,3),CTIME=$P(%TEXT,U,4),LTIME=$P(%TEXT,U,5),JTYPE=$P(%TEXT,U,7)
 | 
|---|
| 214 |  . S EXIT=1
 | 
|---|
| 215 |  .Q
 | 
|---|
| 216 |  ;
 | 
|---|
| 217 |  U $P C %FILE:DELETE
 | 
|---|
| 218 |  S PS=$S(PS="S":"hib",PS="D":"lef",PS="R":"run",1:PS)
 | 
|---|
| 219 |  Q
 | 
|---|
| 220 |  ;  ================
 | 
|---|
| 221 | UERR ;Error
 | 
|---|
| 222 |  S $EC=""
 | 
|---|
| 223 |  U $P W !,"Error: "_$ZS
 | 
|---|
| 224 |  Q:$Q -9
 | 
|---|
| 225 |  Q
 | 
|---|
| 226 |  ;
 | 
|---|
| 227 | HEX(D) ;Decimal to Hex
 | 
|---|
| 228 |  Q $$FUNC^%DH(D,8)
 | 
|---|
| 229 | DEC(H) ;Hex to Decimal
 | 
|---|
| 230 |  Q $$FUNC^%HD(H)
 | 
|---|
| 231 |  ;
 | 
|---|
| 232 | VPE(%OLDSTR,%OLDDEL,%NEWDEL) ; $PIECE extract based on variable length delimiter
 | 
|---|
| 233 |  N %LEN,%PIECE,%NEWSTR
 | 
|---|
| 234 |  S %STRING=$G(%STRING)
 | 
|---|
| 235 |  S %OLDDEL=$G(%OLDDEL) I %OLDDEL="" S %OLDDEL=" "
 | 
|---|
| 236 |  S %LEN=$L(%OLDDEL)
 | 
|---|
| 237 |  ; each %OLDDEL-sized chunk of %OLDSTR that might be delimiter
 | 
|---|
| 238 |  S %NEWDEL=$G(%NEWDEL) I %NEWDEL="" S %NEWDEL="^"
 | 
|---|
| 239 |  ; each piece of the old string
 | 
|---|
| 240 |  S %NEWSTR="" ; new reformatted string to return
 | 
|---|
| 241 |  F  Q:%OLDSTR=""  D
 | 
|---|
| 242 |  . S %PIECE=$P(%OLDSTR,%OLDDEL)
 | 
|---|
| 243 |  . S $P(%OLDSTR,%OLDDEL)=""
 | 
|---|
| 244 |  . S %NEWSTR=%NEWSTR_$S(%NEWSTR="":"",1:%NEWDEL)_%PIECE
 | 
|---|
| 245 |  . F  Q:%OLDDEL'=$E(%OLDSTR,1,%LEN)  S $E(%OLDSTR,1,%LEN)=""
 | 
|---|
| 246 |  .Q
 | 
|---|
| 247 |  Q %NEWSTR
 | 
|---|
| 248 |  ;
 | 
|---|