DCL1.

How do I run a program with arguments?

The RUN command does not accept arguments. To pass arguments to a program, you must use what is called a "foreign command". For example:
   	$ uudecode :== $disk:[dir]uudecode.exe
   	$ uudecode filespec
The leading $ in the symbol definition is what makes it a foreign command. If the device and directory is omitted, SYS$SYSTEM: is assumed.

Under OpenVMS V6.2 and later, DCL supports automatic foreign command definition via the logical name DCL$PATH:. An example of a definition of this logical name is:

    $ DEFINE DCL$PATH SYS$DISK:[],ddcu:[mytooldir],SYS$SYSTEM:
DCL will first look for a command in the DCL command table, and if no match is found and if DCL$PATH is defined, it will then look for command procedures and executable images with filenames matching the command specified, in the directories specified via DCL$PATH. The first match found is invoked, and under OpenVMS, the DCL$PATH support will cause a command procedure to be activated in preference to an executable image.

For more information on foreign commands or on automatic foreign command support, see the OpenVMS User's Manual.

See also question PROG2.

If you want to create a detached process that takes arguments from a command line, it must be run under the control of a command line interpreter (CLI) (typically DCL). This is done by placing the command line in a file, specifying SYS$SYSTEM:LOGINOUT.EXE as the image to run and the command file as the input. For example:

	$ OPEN/WRITE CMD TEMP_INPUT.COM
	$ WRITE CMD "$ MYCOMMAND arguments"
	$ CLOSE CMD
	$ RUN/DETACHED SYS$SYSTEM:LOGINOUT /INPUT=TEMP_INPUT.COM
Various OpenVMS library calls (such as lib$spawn(), cli$dcl_parse(), and the C library system() call) require access to a command line interpreter such as DCL to perform requested actions, and will not operate if a CLI is not available.

When a CLI is not available, these calls typically return the error status SS$_NOCLI. And as mentioned above, invoke the image LOGINOUT to cause a CLI (such as DCL) to be mapped into and made available in the context of the target process.

                                        [Steve Hoffman]
For examples of how TCP/IP Services sets up its foreign commands (which includes tools such as uuencode and uudecode), please see the DCL command procedure SYS$STARTUP:TCPIP$DEFINE_COMMANDS.COM.
Also see DCL11.



DCL2.

How can I redefine control keys in DCL?

The DCL DEFINE/KEY command allows you to define function and keypad keys, but not control keys. Also, keys you define with DEFINE/KEY are not recognized inside applications. Many applications which use the SMG$ routines for input have a similar DEFINE/KEY feature.

The terminal driver line-editing control keys, including the use of DEL for delete, are not modifiable.



DCL3.

How can I clear the screen in DCL?

The simplest way is TYPE/PAGE NLA0:
You can set up a symbol to clear the screen in you LOGIN.COM
      $ CLS :== TYPE/PAGE NLA0:



DCL4.

Using REPLY/LOG from DCL? Disabling Console OPCOMs?

Your terminal must be enabled as an operator terminal before doing the REPLY/LOG, but a DCL procedure (batch command file, system startup, etc) does not have an associated terminal. To make this work, use the following sequence to enable the OPA0: console as the operator terminal; then the REPLY/LOG will be accepted:
  $ DEFINE/USER SYS$COMMAND _OPA0:
  $ REPLY/LOG
  $ DEFINE/USER SYS$COMMAND _OPA0:
  $ REPLY/ENABLE
To disable the system console terminal (OPA0:) as an operator terminal, use the following command:
  $ DEFINE/USER SYS$COMMAND _OPA0:
  $ REPLY/DISABLE
Also see SYLOGICALS.COM (and SYLOGICALS.TEMPLATE) for information on configuring the behaviour of OPCOM, including the use (default) of the system console (OPA0:) as an operator terminal and the specific contents and behaviour of the system operator log file OPERATOR.LOG.

						[Stephen Hoffman]
						[Arne Vajhøj] 



DCL5.

How do I generate a random number in DCL?

Here's my random number generator for inclusion into the OVMS FAQ; just do a GOSUB RAND and the global symbol RANDOM will contain a randomly generated number. The user/programmer can feed the generator a ceiling value (__CEIL) or a new seed (__SEED).
$! RAND - returns a positive random number ("RANDOM") between 0 and 
$!        __CEIL - 1.
$ RAND:
$
$ IF F$TYPE(__SEED) .EQS. ""
$ THEN
$     ! seed the random number generator, ...
$     __NOW = F$CVTIME()
$     __HOUR = 'F$EXTRACT(11,2,__NOW)'
$     __MINUTE = 'F$EXTRACT(14,2,__NOW)'
$     __SECOND = 'F$EXTRACT(17,2,__NOW)'
$     __TICK = 'F$EXTRACT(20,2,__NOW)'
$
$     __SEED == __TICK + (100 * __SECOND) + (6000 * __MINUTE) + -
         (360000 * __HOUR)
$     ! the generator tends to do better with a large, odd seed, ...
$     __SEED == (__SEED .OR. 1)
$     ! clean up, ...
$     DELETEX/SYMBOL __NOW
$     DELETEX/SYMBOL __HOUR
$     DELETEX/SYMBOL __MINUTE
$     DELETEX/SYMBOL __SECOND
$     DELETEX/SYMBOL __TICK
$ ENDIF
$
$ IF F$TYPE(__CEIL) .EQS. "" THEN __CEIL = %X3FFFFFFF
$
$ __SEED == __SEED * 69069 + 1
$
$ RANDOM == (__SEED.AND.%X3FFFFFFF)/(%X40000000/__CEIL)
$
$ RETURN
					[sharris@sdsdmvax.fb3.noaa.gov]



DCL6.

What does the MCR command do?

The MCR command runs the specified image, with a default filespec of SYS$SYSTEM:.EXE, and passes any (optional) command line arguments in the same manner as a foreign command. In other words:
	$ MCR FOO BAR
is equivalent to:
	$ FOO :== $FOO
	$ FOO BAR
It derives from the RSX operating system from which VMS evolved and is still often used as a shortcut for activating images. The MCR command is different from the MCR command line interpreter, which is provided as part of the optional VAX-11 RSX product that provides RSX emulation under VMS.



DCL7.

How do I change the OpenVMS system prompt?

You can use the SET PROMPT command for this purpose. SET PROMPT sets the DCL prompt to the specified string.

When you want to display variable information, you will need to establish a tie-in that provides the information to the SET PROMPT command as required.

If you wish to display the default directory for instance, you will have to establish a tie between the SET DEFAULT command and the SET PROMPT commands, as there is no direct way to get the default directory as the DCL prompt. You can easily acquire or create a set of DCL command procedures that perform the SET DEFAULT and SET PROMPT for you. These DCL command procedures often use a command such as:

  $ set prompt='f$env("default")'
More advanced users could implement a system service or other intercept, and use these tools to intercept the directory change and reset the prompt accordingly. (This approach likely involves some kernel-mode programming, and requires write access to various undocumented OpenVMS data structures.)

There are related tools available from various sources, including the following web sites:


Information in this section has been acquired from various postings that have discussed this topic in the comp.os.vms newsgroup in the past, and examples from Arne Vajhoej, Brian Schenkenberger, James Duff, and others.

				[Steve Hoffman]



DCL8.

Can I do DECnet task-to-task communication with DCL?

Yes, you can do this with DCL.

The OpenVMS DECnet documentation shows various simple examples using the task object and the TYPE command to trigger the execution of a DCL command procedure on a remote node. A slightly more advanced example of using DCL for DECnet task-to-task - a procedure that acts as both the client and as the server as appropriate, and that uses a basic form of half-duplex communications - is included:

        $! x.com
        $
        $! This procedure must be in the user's login directory.
        $! Requires a self-referential (not reverential :-) proxy:
        $!    UAF> add/prox <LocalNode>::<CurrentUser> <CurrentUser>/default
        $! Author: Stephen Hoffman, OpenVMS Engineering, Compaq
        $
        $ goto 'f$mode()'
        $INTERACTIVE:
        $ open/read/write chan 0::"task=x"
        $ write chan "Hello"
        $ read chan parameter
        $ close chan
        $ write sys$output parameter
        $ exit
        $BATCH:
        $OTHER:
        $NETWORK:
        $ open/read/write chan sys$net
        $ read chan parameter
        $ write chan "''parameter' yourself!"
        $ close chan
        $ exit
An example of a run of the above procedure:
        $ @x
        Hello yourself!
        $
DCL does not include support asynchronous I/O, thus a predetermined protocol or a predetermined "turn-around" command sequence must be implemented in order to avoid protocol deadlocks - cases where both tasks are trying to write or both tasks are trying to read. The task that is writing messages to the network must write (or write and read) a predetermined sequence of messages, or it must write a message that tells the reader that it can now start writing messages. (This is the essence of a basic half-duplex network protocol scheme.)
					[Steve Hoffman]



DCL9.

How can I get the width setting of a terminal?

$ width = f$getdvi(terminal,"DEVBUFSIZ")



DCL10.

How can I substitute symbols in a PIPE?

Use ampersand substitution, not apostrophe substitution.
    $ pipe show system | search sys$input opcom | (read sys$input pid ;
           pid=f$element(0," ",pid) ; define/system opcom_pid &pid)
    $ show log opcom_pid
       "OPCOM_PID" = "0000020B" (LNM$SYSTEM_TABLE)



                                           [Norm Lastovica]




DCL11.

Use of RUN/DETACH, LOGINOUT, and logical names?

With a command to create a detached process such as:
    $ RUN/DETACHED SYS$SYSTEM:LOGINOUT /INPUT=TEMP_INPUT.COM
If you are trying to use a logical name as the /INPUT, /OUTPUT or /ERROR on a RUN/DETACH command, then you must translate the logical name specifications to physical references before passing them, or the definitions must reside in a logical name table that is visible to the newly-created process.

Also note that LOGINOUT only creates the SYS$LOGIN, SYS$LOGIN_DEVICE, and SYS$SCRATCH logical names if it is processing a login that is based on the contents of a SYSUAF record -- without access to the associated SYSUAF record, this information is not available to LOGINOUT. (If you want to see these particular logical names created, then please specify the /AUTHORIZE qualifier on the RUN/DETACHED command.)

If you do not specify LOGINOUT as the image, then there is no easy way to get these logical names. Also, any logical names that are used in the target image file specification must also be in a logical name table accessable (by default) by the newly-created detached process. Shared tables include the group (if the process is in the same UIC group) and the system table. (If the target process is to be in another UIC group, a suitablly privileged user or application can create the necessary logical name(s) directly in the other group logical name table.)

When in doubt, create a short DCL command file as input, and use a SHOW LOGICAL and similar commands to examine the context. (And use physical device and directory references on the RUN/DETACH of the LOGINOUT image, when specifying this command file as /INPUT.) Also remember to check both security auditing and system accounting when troubleshooting problems with the RUN/DETACH.

Also see DCL1.



DCL12.

How to use escape and control characters in DCL?

To write a message and then the bell character, use:
    $ bell[0,7] = 7
    $ write sys$output "Hello''bell'"
To write blinking text, use:
    $ esc[0,7] = 27
    $ text = "Blinking Text"
    $ write sys$output "''esc'[5m''text'''esc'[m"
Also see sections DECW9, MISC2.

Next Back