[mod.computers.vax] Asynchronous subprocesses revisited

carl@CITHEX.CALTECH.EDU (03/15/87)

A while ago, I posted instructions for getting VMS to do the equivalent
of what a control-Z does for you under the C-SHELL in ULTRIX (places the
current foreground process in the background and continues it, giving the
user a fresh shell for the foreground process).  The instructions I gave
were to:
	1)  Type a control-Y.
	2)  Type the command
		$ SPAWN/NOWAIT/PROMPT=new-prompt
	3)  Type the command
		$ CONTINUE
At the same time, I posted a procedure which shows a problem with doing
such things, at least under VMS v4.5.  Such a procedure is:
    $       IF P1 .NES. "" THEN GOTO NEXT
    $       SET CONTROL=(T,Y)
    $       SPAWN/NOWAIT/INPUT='F$TRN("SYS$COMMAND") @'F$ENV("PROCEDURE")' X
    $ LOOP: WRITE SYS$OUTPUT "F$ENV(""CONTROL"") = """,f$env("CONTROL"),""""
    $       WAIT 00:00:10.00
    $       GOTO LOOP
    $       EXIT
    $ NEXT: SPAWN/INPUT='F$TRN("SYS$COMMAND")' ATTACH/ID='F$GETJPI("","PID")'
    $       WRITE SYS$OUTPUT "STOPPING JOB"
    $       STOP/ID=0
(Note:  Those of you who are a bit touchy about "SECURITY" issues, please note
that this procedure is NOT in any meaningful sense a demonstration of a security
breach, since the procedure:
    $       SET NOCONTROL=Y
    $ LOOP: WRITE SYS$OUTPUT "F$ENV(""CONTROL"") = ""T,Y"""
    $       WAIT 00:00:10.00
    $       GOTO LOOP
has the same detrimental effects, and everything it uses is clearly documented
in the on-line HELP facility). I claimed at the time that the problem was that
the terminal now effectively has control-T and control-Y disabled, despite the
fact that it reports them to be enabled.  I've since found out a little more
about the problem, and have happened upon an application which may be dear
to the hearts of many people who've had one particular gripe about DECnet
ever since it was invented.  The additional piece of information is that
the bug shown in the procedure above is somewhere in TTDRIVER.  It occurs
on terminals using this driver (e.g. VTAnnn:), but NOT on terminals using
either the driver OPERATOR (don't go looking in SYS$SYSTEM: for this one;
it's the console terminal driver and is buried somewhere in a startup file)
or DZDRIVER. Now to the other application:  For those of you who've always
chafed at the fact that if you CONTROL-Y out of a SET HOST session, you
log out of the remote job, here's a workaround:
$!******************************************************************************
$! REVOKABLE_SET_HOST.COM -- Allow an escape from the DCL SET HOST command
$! Copyright (C) 1987 Caltech Odd-Hack Committee, no rights reserved
$	set_host_control == f$env("CONTROL") 	!'f$verify(0)'
$	if p1 .eqs. "RETURN_TO_REMOTE" then goto LOOP
$	Copy sys$input: sys$output:
Warning: If you use this procedure, you won't be able to use control-Y on the
REMOTE node.  Once logged in on the remote node, to return to the local node,
type a control-Y.  To return to the remote node again, use the command REMOTE.
$	if p1 .eqs. "" then read/prompt="_Node: " sys$command p1
$	if p1 .eqs. "" then exit
$	set_host_node = f$edit(p1,"UPCASE")
$	REVOKABLE_PROMPT==-
		"Are you typing ^Y to abort the remote session on node "+-
		set_host_node+"? "
$	set_host_prompt==f$env("PROMPT")
$	set_host_process==f$getjpi("","PID")+"_"+set_host_node
$	REMOTE:==@'f$environment("procedure")' RETURN_TO_REMOTE
$	spawn/nowait/proc="''set_host_process'"/nolog-
		set host 'set_host_node'
$	set proc/susp 'set_host_process'
$	x = 0
$ pid:	set_host_pid == f$pid(x)
$	if f$getjpi(set_host_pid,"PRCNAM") .nes. set_host_process then goto pid
$ loop:	set prompt="SET_HOST: "
$	set control=(T,Y)
$	On control_y then goto ask
$	set proc/resume/id='set_host_pid'
$	wait 23:59:59.99
$	goto loop
$ ask:	SET NOCONTROL=(T,Y)
$	message=f$env("MESSAGE")
$	on warning then goto done
$	set message/noid/nosev/notext/nofac
$	if f$getjpi(set_host_pid,"PRCNAM") .nes. set_host_process then goto done
$	set message 'message'
$	Read/time=5/err=loop/prompt="''revokable_prompt'" sys$command yn
$	if .not. yn then goto warn
$ done:	set noon
$	del/sym/glo set_host_process
$	stop/id='set_host_pid'
$	del/sym/glo set_host_pid
$	set prompt="''set_host_prompt'"
$	del/sym/glo set_host_prompt
$	set control=('set_host_control')
$	del/sym/glo set_host_control
$	set message 'message'
$	exit
$ warn:	set proc/susp/id='set_host_pid'
$	write sys$output "Use the command REMOTE to continue remote session"
$	set control=('set_host_control')
$	write sys$output f$fao("Please type a carriage return!/")
$!******************************************************************************
The procedure is still rather crude in that the SET PROCESS/SUSPEND command
does not cancel I/O requests pending for the process in question, so when
you return to the local machine, the first line you type will typically
be read by the subprocess doing the set host.  Further, I suspect that the
procedure relies heavily on the TTDRIVER bug described above, though I'm
confident it could be doctored to work with a fixed driver.  The biggest
drawback, of course, is that CONTROL-Y and CONTROL-T are disabled for the
remote job.  Still, it DOES let you escape to the local machine, something
I've often heard people wishing for, doesn't require a compiler of any sort,
nor privs other than NETMBX and TMPMBX.  Improvements/generalizations/bugfixes
should be sent to CARL@CITHEX.CALTECH.EDU (or for those of you on BITnet,
simply CARL@CITHEX).  Also, just to keep tabs on what sort of use its getting,
I'd appreciated hearing from anybody who actually uses the thing.  Thanks.
							-Carl J Lydick