From: carl@SOL1.GPS.CALTECH.EDU (Carl J Lydick)
Newsgroups: comp.os.vms
Subject: Re: mailboxes with DCL?
Date: 23 Jan 1993 00:19:48 GMT
Organization: HST Wide Field/Planetary Camera
Distribution: world
Reply-To: carl@SOL1.GPS.CALTECH.EDU
NNTP-Posting-Host: sol1.gps.caltech.edu

In article <22JAN199315351392@robot.nuceng.ufl.edu>, sysop@robot.nuceng.ufl.edu (Shawn A. Clifford) writes:
>>You can't create mailboxes from DCL.  You've got to write a program to create
>>them (and, since you're probably restricted to creating temporary mailboxes,
>>they go away, by default, at image rundown).  What you need to do is:
>
>Not  necessarily.  If you post a read to the mailbox, the mailbox lives after
>the program exits.  For an example of this, look in PUBLIC$:[DCL] at
>robot.nuceng.ufl.edu for the obvious files.

I just looked.  You shouldn've have contradicted me.  I'm the author of both
the LIFEMBX and the PAGINATE programs.  I wrote them back in the mid-80s when I
was managing a system called CITHEX for the high energy physics people here at
Caltech.  You're wrong.  It's not the fact that the program issued a READ on
the mailbox before exiting that keeps the mailbox around.  It's the fact that
the parent process has OPENed the mailbox.  In fact, the LIFEMBX.C and
LIFEMBX.COM files you reffered to are an implementation of exactly the strategy
I outlined and you deleted in your response:
	1)  Spawn a subprocess which runs an executable which:
	    A)  Uses $CREMBX to create a temporary mailbox;
	    B)  Issues a (synchronous) READ on the mailbox;
	    C)  Exits after the read completes;
	2)  From the parent process,
	    A)  Use the DCL OPEN command to assign a channel to the mailbox;
	    B)  Use the WRITE command to write a record to the mailbox.
So the sequence of actions is:
	1)  Parent spawns subprocess;
	2)  Subprocess creates mailbox;
	3*) Subprocess issues READ on mailbox;
	4*) Parent process OPENs mailbox;
	5*) Parent process WRITEs to mailbox;
	6)  Subprocess's READ completes;
	7)  Subprocess exits.
Note:  Step 3 can occur either between steps 2 and 4, between steps 4 and 5, or
between steps 5 and 6.

>One for creating the mailbox in a high level language,

Correct.

>one for defining the mailbox logical and buffer size as a startup for other
>routines written in DCL,

Incorrect.  Take another look at LIFEMBX.COM:

	$! LIFEMBX.COM -- create a semi-permanent mailbox, with an entry
	$!		             for it in the job logical name table
	$! Copyright (C) 1986, The Caltech Odd Hack Committee, no rights reserved
	$ verify = 'f$verify(0)'
	$ on error then goto fail
	$ on control_y then goto fin
	$ _status = 1
	$ if p1 .eqs. ""
	$ then
	$ 	write SYS$ERROR "Usage: @lifembx [size] name [size2]"
	$	goto fail
	$ endif
	$ if p2 .eqs. "" then p2 = p1
	$ if p2 .eqs. p1 then p1 = 132
	$ if p3 .eqs. "" then p3 = p1
	$ lifembx = f$search("TOOLS:lifembx.exe")
	$ if lifembx .eqs. ""
	$ then
	$	write SYS$ERROR "Can't find TOOLS:lifembx.exe"
	$ 	goto fail
	$ endif
	$ spawn/nowait/nolog/nosym/nokey/nologi mcr 'lifembx' 'p1' 'p2' 'p3'

Note:  This is *NOT* "defining the mailbox logical and buffer size as a startup
for other routines written in DCL."  This is simply taking the mailbox logical
name SPECIFIED BY THE USER and either taking user-specified values for the
"maxmsg" and "bufquo" arguments to $CREMBX or using a default value of 132
characters for both.
	$wait:	wait 00:00:01.0
	$ open/read/write/share=write/err=wait TMPFILE 'p2':
In this loop, the parent process waits until the mailbox is created.  I really
should've put a counter in this loop;  if the subprocess fails to create the
mailbox, then the parent goes into an infinite loop.  No real problem if you're
doing this from a terminal, since it'll quickly become obvious that you're in a
loop, and a control-Y will get you out of it, but if you execute this procedure
in a batch job, the job hangs until killed.  So you really ought to change
those lines to:
	$	loopcount = 0
	$ wait:	wait 00:00:01.00
	$	if loopcount .ge. 30 then goto fail
	$	loopcount = loopcount + 1
	$	open/read/write/share=write/err=wait TMPFILE 'p2':
This way, the procedure will fail after 30 seconds if no mailbox has been
created.  If the open succeeds, then we've got a channel assigned to the
mailbox by the parent process.  This means that the mailbox will stick around
when the LIFEMBX image running in the subprocess deassigns its channel to the
mailbox and exits.

	$	write TMPFILE ""

This WRITE satisfies the READ on the mailbox issued by the subprocess, allowing
the subprocess to deassign its channel to the mailbox, exit from the image, and
then exit.

	$ deassign TMPFILE

This is to prevent you from accidentally CLOSEing  TMPFILE, which would make
the mailbox go away.

	$ goto fin
	$fail:
	$ _status = 2
	$fin:
	$ exit _status + 0*f$verify(verify)

So what the file LIFEMBX.COM is really doing is:  Spawning a subprocess to run
the image to create the mailbox, then assigning a channel to it from the parent
process, issuing a write to the mailbox to allow the subprocess to exit, and
then DEASSIGNing the logical name associated with the channel, so that the
mailbox can't be accidentally deleted.

If you want to be able to delete the mailbox, you should remove the command:

	$ deassign TMPFILE

from the procedure.  Then you can delete the mailbox via the command:
	$	CLOSE TMPFILE
If you HAVE DEASSIGNed the logical name TMPFILE, then you'll have to use a
program that uses $DASSGN to deassign the channel associated with the mailbox.
Even finding the channel number take privs (or perhaps just a detailed
knowledge of VMS internals;  I always find the channel numbers associated with
processes via the ANALYZE/SYSTEM command), so if you plan to delete the mailbox
(other than by logging out the process from which you issued the @LIFEMBX
command), you really SHOULD comment out the DEASSIGN command.


>and a DCL comfile that makes use of mailboxes by paging output from any other
>program to your screen

PAGINATE.COM does this by using LIFEMBX to create a 132-character-wide mailbox
called PAGEPIPE (unless the logial name PAGEPIPE already exists), then treating
its command-line arguments as a command to be spawned.  It spawns that command,
then TYPE/PAGEs PAGEPIPE.  After you exit from TYPE, PAGINATE:
	1)  Attempts to STOP the subprocess it created (in case you exited from
	    the TYPE command before reading everything the subprocess wanted to
	    output;
	2)  OPENs PAGEPIPE for read;
	3)  READs from PAGEPIPE until it reaches and end-of-file or a timeout;
	4)  CLOSEs PAGEPIPE
thus cleaning up after itself.  Actually, I wrote LIFEMBX and PAGINATE mainly
in order to be able to TYPE/PAGE the output of a DUMP command without having to
set my terminal to 132 character width.  DUMP bases the format of its output on
the buffer size of the output device.  When it dumps to a terminal, this means
it bases it on the current terminal width.  When it dumps to a disk file, it
sees a buffer size of 512 bytes, and uses its widest output format.  When it
sees a mailbox, it sees a buffer size equal to the value specified in "maxmsg"
when the mailbox was created.  Thus, you can use LIFEMBX to create the mailbox
PAGEPIPE with a maxmsg of 80, then use PAGINATE to TYPE/PAGE the output from
the DUMP command on an 80-character-wide screen.
--------------------------------------------------------------------------------
Carl J Lydick | INTERnet: CARL@SOL1.GPS.CALTECH.EDU | NSI/HEPnet: SOL1::CARL

Disclaimer:  Hey, I understand VAXen and VMS.  That's what I get paid for.  My
understanding of astronomy is purely at the amateur level (or below).  So
unless what I'm saying is directly related to VAX/VMS, don't hold me or my
organization responsible for it.  If it IS related to VAX/VMS, you can try to
hold me responsible for it, but my organization had nothing to do with it.