.title NOCONTROL_Y Disable CLI image wind down .ident "031084" ;++ ; Author : Nick de Smith (be nice and leave my name on it somewhere!) ; Creation Date : 3 November 1984 ; ;***************************************************************************** ; ; If the symbol MODEM_ONLY is not defined, running this program will disable ; all control-y handling by DCL (for the current process). ; If the symbol MODEM_ONLY is defined, running this program will disable all ; control-y handling by DCL on MODEM lines only. ; ; MODEM_ONLY = 1 ; ;***************************************************************************** ; ; Environment : VAX/VMS native mode ; Requirements : Needs process CMEXEC privs, or should be INSTALLed ; ; Function: ; ; If the CLI input device is a terminal, and the terminal has modem ; control enabled, then disable all supervisor mode ASTs. This prevents ; the CLI from being notified about line hangup, and thus prevents the ; executing images from being deleted. However, note the side effects ; discussed below. Virtual terminals do not provide this facility. ; ; Discussion: ; ; The CLI input channel is first assigned by LOGINOUT when the process is ; created. This is done in supervisor mode, and the channel characteristics ; are then stored in the process permenant data segment. ; On entry, the CLI checks the process type, and if its interactive, it ; enables a supervisor mode CTRL/Y AST dispatching to an internal handler. ; When a CTRL/Y is typed, the CLI first gains control and re-enables the ; supervisor mode CTRL/Y AST. It then (in DCL's case) checks to see if ; CLI handling of CTRL/Y ("set [no]control=y") has been enabled, and if it ; has, then the handler just exits; if not, then the CLI returns to its ; prompt such that commands such as "CONTINUE", "EXAMINE", "STOP" etc can ; be used. ; When the line drops on a modem port, all outstanding CTRL/Y ASTs are ; delivered with a parameter of SS$_HANGUP. When the DCL CTRL/Y handler ; receives such an AST, it does not re-enable the AST, but just winds down ; the image and the process. ; Therefore, in order to prevent a process being deleted when a modem line ; drops, the AST to the CLI must be disabled. Setting "nocontrol=y" is not ; sufficient as this just sets a flag in the CLI saying that you don't want ; the CLI to act on CTRL/Y. In fact the CLI still checks for SS$_HANGUP and ; acts in the above described way, although any other sort of CTRL/Y is ; ignored. ; ; Usage of this program removes the CLI declared AST on the terminal, such ; that CTRL/Y will no longer work, and so that the CLI cannot wind down ; the executing image. This means that hanging up a modem line will not ; cause immediate image wind down - It is up to the image to detect that the ; line has gone. ; Because of this, executing images should have a CTRL/Y AST declared which ; tests for the parameter being SS$_HANGUP, and which then acts accordingly. ; ; A typical flow for a program using this technique would be: ; ; Start_Of_Program: ; if (terminal_line_is_a_modem) then ; Check TT$M_MODEM ; if (state_of_line = local) then ; Check TT$M_REMOTE ; line_is_up = FALSE ; line is local = down ; else ; line_is_up = TRUE ; Line is remote = up ; end if ; declare_control_y_ast ; Set program AST ; else ; line_is_up = TRUE ; Unconditional (non-modem) ; ; while (line_is_up) do ; begin ; ... ; Program code ; end ; ; Control_Y_AST: ; AST routine called ; declare_control_y_ast ; Re-declare AST NOW! ; if (ast_parameter = SS$_HANGUP) then ; If its a hangup.. ; line_is_up = FALSE ; Say line is down ; else ; Else... ; ordinary/some other control/y ; User typed CTRL/Y ; end if ; return ; ; How to build NOCONTROL_Y: ; ; $ Macro NOCONTROL_Y ; $ Link NOCONTROL_Y ; $ Install ; INSTALL> Create dev:[dir]NOCONTROL_Y.EXE /Open /Shar /Head /Prot /Priv=CMEXEC ; INSTALL> Exit ; $ ;-- ;+ ; Call in system wide definitions ;- .link "SYS$SYSTEM:DCLDEF.STB" /Selective_Search .link "SYS$SYSTEM:SYS.STB" /Selective_Search $devdef ; Define DEV$xxxxx $iodef ; Define IO$xxxxxx $psldef ; Define PSL$xxxxx .if defined MODEM_ONLY $ttdef ; Define TT$xxxxxx .psect $DATA Pic, NoShr, Wrt, Noexe, Long ;+ ; Terminal characteristics from sense mode ;- TERMINAL_CHAR: .blkq 1 ; 8 bytes needed .endc .psect $CODE Pic, Shr, Nowrt, Exe, Long ;+ ; NO_CLI_HANGUP - Disable CLI image wind down on hangup ; ; Check to see if the process declared input channel is a terminal, and ; if so, try to remove all CTRL/Y ASTs declared for it. A change mode to ; executive mode is needed as the channel was declared in supervisor mode. ; ; Outputs: ; ; R0 = Final request status ;- .entry NO_CLI_HANGUP, ^m movab G^CTL$AG_CLIDATA, r10 ; R10 -> PPD area bbc #DEV$V_TRM,PPD$L_INPDEV(r10),90$; If clr, 'INPUT' not from terminal $cmexec_s ,- ; Need exec mode to... routin = CANCEL_CONTROL_Y,- ; Cancel supervisor CTRL/Y ASTs arglst = #0 ; No args for this change 90$: ret ;+ ; CANCEL_CONTROL_Y - Cancel the SYS$INPUT CTRL/Y AST ; ; This routine is called to disable control Y ASTs on the input channel ; The routine executes in executive mode to clear the supervisor mode ; ASTs on the command input channel declared by the controling CLI. ; This routine should not be called unless the channel under inspection is ; a terminal device. This MUST be done by the caller ; This routine does nothing if the line is not a modem line. ; ; Inputs: ; ; R10 = Base address of process permenant data area ; ; Outputs: ; ; R0 = Final request status ;- .entry CANCEL_CONTROL_Y, ^m<> .if defined MODEM_ONLY $qiow_s ,- ; Sense mode efn = #31 ,- ; Event flag chan = PPD$W_INPCHAN(r10),- ; Input channel func = #IO$_SENSEMODE,- ; Function code p1 = TERMINAL_CHAR ; Address of chars buffer blbc r0, 90$ ; Exit on error bbc #TT$V_MODEM, TERMINAL_CHAR+4, 90$ ; Skip this if not a modem .endc $qiow_s - ; Remove AST efn = #31 ,- ; Event flag chan = PPD$W_INPCHAN(r10),- ; Input channel func = #IO$_SETMODE!IO$M_CTRLYAST,- ; Function code p1 = 0 ,- ; AST routine address p3 = #PSL$C_SUPER ; Access mode = supervisor ; Blbc r0, 90$ ; Exit on error 90$: ret .end NO_CLI_HANGUP