From:	CSBVAX::CSBVAX::MRGATE::"SMTP::CRVAX.SRI.COM::RELAY-INFO-VAX" 10-FEB-1989 13:35
To:	MRGATE::"ARISIA::EVERHART"
Subj:	workaround for non-dying VAX LISP jobs from modem lines...


Received: From KL.SRI.COM by CRVAX.SRI.COM with TCP; Thu,  9 FEB 89 17:22:06 PDT
Received: from HCF06.HCF.JHU.EDU ([128.220.2.12]) by KL.SRI.COM with TCP; Thu, 9 Feb 89 17:19:56 PST
Received: from JHUVMS.BITNET by HCF06.HCF.JHU.EDU; Thu, 9 Feb 89 20:19 EST
Date: Thu, 9 Feb 89 20:12 EST
From: Tom O'Toole - HCF <ECF_STBO@JHUVMS.BITNET>
Subject: workaround for non-dying VAX LISP jobs from modem lines...
To: info-vax@kl.sri.COM
X-VMS-To: IN%"info-vax@kl.sri.com"

Here is a simple workaround for the problem of processes running VAX LISP
(v2.2 is my version, with V4.7 of VMS) NOT dying when the line is
disconnected. This can be a serious load problem since the processes in this
state use resources sporadically. It is also a security problem. On some of
our lines connected to terminals via a port switcher, the next person who
dials in will get the old session (yes, the lines are correctly connected for
modem control, but vms hasn't stopped the process). This next person comes up
in the lisp debugger (!), and as soon as lisp is exited will get logged out,
but I imagine it would be no problem to spawn out and use the other person's
account... DEC doesn't seem to want anything to do with fixing the problem...



Tom O'Toole
JHUVMS system programmer              No you CAN'T have any more chairs!
Homewood Computing Facilities        There's only one left and I need that
Johns Hopkins University                     to SIT on!
Balto. Md. 21218
ecf_stbo@jhuvms.bitnet


$! ...................... Cut between dotted lines and save. .....................
$!.............................................................................
$! VAX/VMS archive file created by VMS_SHARE V06.03 20-Oct-1988.
$!
$! VMS_SHARE was written by James Gray (Gray:OSBUSouth@Xerox.COM) from
$! VMS_SHAR by Michael Bednarek (U3369429@ucsvc.dn.mu.oz.au).
$!
$! To unpack, simply save, concatinate all parts into one file and
$! execute (@) that file.
$!
$! This archive was created by user ECF_STBO
$! on  9-FEB-1989 19:59:14.04.
$!
$! It contains the following 3 files:
$!        HNG.TXT
$!        HNG.LSP
$!        HNG_HANDLER.FOR
$!
$!==============================================================================
$ SET SYMBOL/SCOPE=( NOLOCAL, NOGLOBAL )
$ VERSION = F$GETSYI( "VERSION" )
$ IF VERSION .GES "V4.4" THEN GOTO VERSION_OK
$ WRITE SYS$OUTPUT "You are running VMS ''VERSION'; ", -
    "VMS_SHARE V06.03 20-Oct-1988 requires VMS V4.4 or higher."
$ EXIT 44 
$VERSION_OK:
$ GOTO START
$
$UNPACK_FILE:
$ WRITE SYS$OUTPUT "Creating ''FILE_IS'"
$ DEFINE/USER_MODE SYS$OUTPUT NL:
$ EDIT/TPU/COMMAND=SYS$INPUT/NODISPLAY/OUTPUT='FILE_IS'/NOSECTION -
    VMS_SHARE_DUMMY.DUMMY

b_part := CREATE_BUFFER( "{Part}", GET_INFO( COMMAND_LINE, "file_name" ) );
s_file_spec := GET_INFO( COMMAND_LINE, "output_file" );SET( OUTPUT_FILE
, b_part, s_file_spec ); 
b_errors := CREATE_BUFFER( "{Errors}" );i_errors := 0; 
pat_beg_1 := ANCHOR & "-+-+-+ Beginning";
pat_beg_2 := LINE_BEGIN & "+-+-+-+ Beginning";
pat_end := ANCHOR & "+-+-+-+-+ End";
pat_trail := " " & LINE_END;POSITION( BEGINNING_OF( b_part ) ); LOOP b 
:= SEARCH( pat_trail, FORWARD); EXITIF b=0; POSITION( END_OF( b ) )
; LOOP MOVE_HORIZONTAL( -1 ); EXITIF CURRENT_CHARACTER <> ' '; ERASE_CHARACTER
( 1 ); EXITIF CURRENT_OFFSET=0; ENDLOOP; ENDLOOP; POSITION( BEGINNING_OF
( b_part ) ); i_append_line := 0; LOOP EXITIF MARK( NONE ) = END_OF( b_part )
; s_x := ERASE_CHARACTER( 1 ); 
  IF s_x = "+" THEN r_skip := SEARCH( pat_beg_1, FORWARD, EXACT ); IF r_skip <
> 0 THEN 
      s_x := ""; MOVE_HORIZONTAL( -CURRENT_OFFSET ); ERASE_LINE; ENDIF; ENDIF; 
  IF s_x = "-" THEN r_skip := SEARCH( pat_end, FORWARD, EXACT ); IF r_skip <
> 0 THEN 
      s_x := ""; MOVE_HORIZONTAL( -CURRENT_OFFSET ); m_skip := MARK( NONE )
; r_skip := SEARCH( pat_beg_2, FORWARD, EXACT ); IF r_skip <> 0 THEN POSITION
( END_OF( r_skip ) ); MOVE_HORIZONTAL( -CURRENT_OFFSET ); MOVE_VERTICAL( 1 )
; MOVE_HORIZONTAL( -1 ); ELSE POSITION( END_OF( b_part ) ); ENDIF; ERASE
( CREATE_RANGE( m_skip, MARK( NONE ), NONE ) ); ENDIF; ENDIF; 
  IF s_x = "V" THEN 
    s_x := ""; IF i_append_line <> 0 THEN APPEND_LINE; MOVE_HORIZONTAL
( -CURRENT_OFFSET ); ENDIF; i_append_line := 1; MOVE_VERTICAL( 1 ); ENDIF; 
  IF s_x = "X" THEN 
    s_x := ""; IF i_append_line <> 0 THEN APPEND_LINE; MOVE_HORIZONTAL
( -CURRENT_OFFSET ); ENDIF; i_append_line := 0; MOVE_VERTICAL( 1 ); ENDIF; 
  IF s_x <> "" THEN i_errors := i_errors + 1; s_text := CURRENT_LINE; POSITION
( b_errors ); 
    COPY_TEXT( "The following line could not be unpacked properly:" )
; SPLIT_LINE; COPY_TEXT( s_x ); COPY_TEXT( s_text ); POSITION( b_part )
; MOVE_VERTICAL( 1 ); ENDIF; ENDLOOP; POSITION( BEGINNING_OF( b_part ) ); LOOP 
  r_x := SEARCH( "`", FORWARD, EXACT ); EXITIF r_x = 0; POSITION( r_x )
; ERASE_CHARACTER( 1 ); 
  IF CURRENT_CHARACTER = "`" THEN MOVE_HORIZONTAL( 1 ); ELSE COPY_TEXT( ASCII
( INT( ERASE_CHARACTER( 3 ) ) ) ); ENDIF; ENDLOOP; IF i_errors = 0 THEN SET
( NO_WRITE, b_errors, ON ); ELSE POSITION( BEGINNING_OF( b_errors ) ); 
  COPY_TEXT( FAO( "The following !UL errors were detected while unpacking !AS"
, i_errors, s_file_spec ) ); SPLIT_LINE; 
  SET( OUTPUT_FILE, b_errors, "SYS$COMMAND" );ENDIF; EXIT; 
$ DELETE VMS_SHARE_DUMMY.DUMMY;*
$ CHECKSUM 'FILE_IS
$ WRITE SYS$OUTPUT " CHECKSUM ", -
  F$ELEMENT( CHECKSUM_IS .EQ. CHECKSUM$CHECKSUM, ",", "failed!,passed." )
$ RETURN
$
$START:
$ FILE_IS = "HNG.TXT"
$ CHECKSUM_IS = 875719720
$ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY
V  I had to write this program (described below), because I had a SERIOUS proble
Xm
Xwith processes which continued to stay on the system after their modem line had
Xbeen disconnected. DEC refuses to fix this problem. The whole interaction with
XDEC software support took several months. Every couple of weeks they would "get
Xback to me" and tell me that they had a "lot of information to help me solve
Xthis problem" and then tell me the SAME THING they told me before: "try and
Xfigure out the characteristics of these jobs and put that info into your job
Xkiller blah, blah..." (I don't have a "job killer")...
X
V  They said they knew this problem has been in VMS since anyone can remember an
Xd
Xthat they got about a call a month about this very problem. Yet they wouldn't
Xand still won't fix it! Maybe the main problem here was finger pointing between
Xdifferent groups within DEC: The terminal driver/vms people would say that the
Xapplication was badly behaved and the lisp people would say VMS should kill the
Xprocess. To me the obvious fix is to give the process a limited amount of time
Xto clean up in each access mode, like the EXTRACPU parameter was designed for.
XAt the time I got this simple fix going, we had several classes using lisp and
Vliterally doezens of processes getting hung up each week. It was taking a lot o
Xf
Xmy time to track down/stop/refund these processes and it was putting a drain on
Va very busy 28MB 8600. I told the DEC people that they couldn't publish/use thi
Xs
Xfix unless they put in some diatribe about how they wouldn't fix the basic
Xproblem (I guess that self-referential diatribe would be this...). This might
Xhave been stupid, but I was angry at the time. Anyway, they never called me
Xback. I still think that for the amount we pay, we deserve much, much better.
X-------------------------------------------------------------------------------
X
X
X   This is a condition handler for VAX LISP. With vanilla VAX lisp, if a user
Xhangs up a modem line, or hits break on an ISN port, or otherwise gets
Xabnormally disconnected without logging off, the LISP process will continue
Xto hang around (I guess it has some exit handler...). The especially bad part
Xof it is that while it hangs around, it occasionally uses cpu time, page
Xfaults and I/O. This type of process is difficult to identify with a standard
X"idle job killer" and I frankly dislike most automatic logger-offers anyway.
XWhen this condition handler is setup, it will get the first crack at any
Xexceptions (it becomes the primary exception vector). It will just resignal
Xall of these except the data set hangup event that needs to be handled. When it
Xgets one of these, it will delete the process. This fix is "discretionary" in
Vthe sense that the user must request that hng.lsp be loaded as an initializatio
Xn
Xfile (but the command lisp can be redefined to automatically include it).
X
XTo install:
X
X$for hng_handler
X$link /shar=hng hng_handler
XPut hng.exe in sys$share (or define a log name to point to it).
XFrom then on invoke lisp as follows
X$lisp/init=location:hng (I ended up putting hng.lsp in lisp$system)
X
XIf anyone knows of a better way to automatically include this handler as a
Xdefault when lisp is run, please let me know.
X
X
$ GOSUB UNPACK_FILE
$ FILE_IS = "HNG.LSP"
$ CHECKSUM_IS = 1516526549
$ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY
X(define-external-routine (hng_set_handler
X`009:file "HNG"
X`009:check-status-return NIL)
X())
X(call-out hng_set_handler)
$ GOSUB UNPACK_FILE
$ FILE_IS = "HNG_HANDLER.FOR"
$ CHECKSUM_IS = 661895045
$ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY
X! this routine is an attempt to get a file read error handler going in lisp.
X! this is the status you get when a break is hit on the ISN disconnecting
X! the virtual port through the ISN. We have a problem with lisp (and possibly
X! other programs as well) not dying when this event occurs. LISP jobs in this
X! state are especially bothersome, because they continue to use cpu and I/O
X! resources (hell if I know why!!). Of course lisp is a PIG anyway, so we need
X! to get these frigging processes *gone*. - TBO; 8-jan-1989
X
X
X! declare the handler...
X! It seems that lib$establish will be useless for our purposes, since that
X! only allows us to declare a handler for the CURRENT program unit. We need
X! sys$setexv, which will not only enable them for the entire lisp image, but
X! will give them the first shot (we need to find out which, if any, of these
X! lisp is using as well...
X`009subroutine hng_set_handler
X
X! declare all...
X`009implicit none
X
X
X! condition handler defs...
X`009integer*4 sys$setexv
X`009integer*4 hng_handler
X`009external hng_handler
X`009integer*4 old_vector,istat
X
X
X! establish our man as a condition handler... He gets the first shot.
X`009istat=sys$setexv(,hng_handler,,old_vector)
Xd`009write(1,2)
Xd2`009format(' Old exception vector...')
Xd1`009format(1x,z8.8)
Xd`009write(1,1)old_vector
X`009if(.not.istat) call lib$signal(%val(istat))
X
X! and vamanose...
X`009return
X`009end
X
X
X! The actual handler routine...
X`009integer*4 function hng_handler(sigargs,mechargs)
X
X! declare all...
X`009implicit none
X
X! args...
X`009integer sigargs(*),mechargs(*)
X
X! condition checking defs...
X`009include '($ssdef)'
X`009integer lib$match_cond
X
Xd`009integer id
Xd2`009format(' SIG array...')
Xd`009write(1,2)
Xd`009do id=2,sigargs(1)
Xd1`009format(1x,z8.8)
Xd`009write(1,1)sigargs(id)
Xd`009enddo
X
X
X! check if it is what we were afraid of...
X`009if(lib$match_cond(sigargs(4),ss$_hangup)) then
X!`009 we got a hangup error! hammer ourselves into the dirt...
Xd`009`009write(1,*)'OOOF!'
X`009`009call sys$delprc(,)
X`009`009hng_handler=ss$_resignal ! overkill...
X`009else
X!`009 something else, just resignal it...
X`009`009hng_handler=ss$_resignal
X`009endif
X
X`009return
X`009end
$ GOSUB UNPACK_FILE
$ EXIT

