The OpenVMS Frequently Asked Questions(FAQ)


Previous Contents Index


Chapter 8
DCL Details

8.1 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:


$ unzip :== $disk:[dir]unzip.exe 
$ unzip -? 

The leading $ in the equivilence name for the symbol definition is what makes the DCL symbol a foreign command. If the device and directory are 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 Section 10.3.

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.

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 Section 8.10.

8.2 How can I clear the screen in DCL?

The simplest way is the TYPE/PAGE NLA0: command.

You can set up a symbol to clear the screen in your LOGIN.COM:


$ CLS :== TYPE/PAGE NLA0: 

8.3 Using REPLY/LOG from DCL? Disabling Console OPCOMs?

Your terminal must be enabled as an operator terminal before the REPLY/LOG command can be used, 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 command 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 (default) use of the system console (OPA0:) as an operator terminial and the specific contents and behaviour of the system operator log file OPERATOR.LOG.

8.4 How do I generate a random number in DCL?

Here is a random number generator, just do a GOSUB RAND and the global symbol RANDOM will contain a randomly generated number. You 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. 
$! sharris-at-sdsdmvax.fb3.noaa.gov 
$ 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 

8.5 What does the MCR command do?

The MCR is an artifact of RSX compatibility mode, the operating system from which OpenVMS is descended. MCR is the Monitor Console Routine, and the command is intended to activate RSX compatibility mode utilities. When used on OpenVMS, the command is most commonly used to run the specified image and---because the tool detects the image is not a compatibility-mode image---it acts as a form of RUN command with the default file specification of SYS$SYSTEM:.EXE. MCR passes any (optional) command line arguments in a fashion similar to a foreign command. In other words:


$ MCR FOO BAR 

is equivalent to:


 $ FOO :== $FOO 
 $ FOO BAR 

MCR is not documented. Use of a foreign command or the DCL$PATH mechanism is preferred. For details on this, see Section 8.1.

8.6 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$environment("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:

8.7 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. An example DCL command procedure that is rather more advanced than using the TYPE command as a trigger is included in the Ask The Wizard area:

For additional information on the OpenVMS Ask The Wizard (ATW) area and for a pointer to the available ATW Wizard.zip archive, please see Section 3.9.

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.)

8.8 How can I get the width setting of a terminal?


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

8.9 How can I substitute symbols in a PIPE?

Use DCL ampersand substitution, and 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) 

8.10 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 accessible (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 Section 8.1.

8.11 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 Section 11.7, Section 12.1.


Chapter 9
Files

9.1 How can I undelete a file?

OpenVMS doesn't have an "undelete" function. However, if you are quick to write-protect the disk or if you can guarantee that no new files get created or existing files extended, your data is still on the disk and it may be possible to retrieve it. The FLORIAN tool available from various websites can potentially recover the file, see question Section 13.1 for pointers. Other alternatives here include the DFU tool, available on the OpenVMS Freeware CD-ROM distribution.

If you are setting up a user environment for yourself or for others, it is quite easy to use DCL to intercept the DELETE command, using a symbol:


$ DEL*ETE :== @SYS$LOGIN:MYDELETE.COM 

The DELETE symbol will cause the procedure to be invoked whenever the user enters the DELETE command, and it can copy the file(s) to a "trashcan" subdirectory before issuing a "real" DELETE on the files. Other procedures can retrieve the file(s) from the "trashcan" subdirectory, and can (and should) clean out the "trashcan" as appropriate. (Realize that this DELETE symbol can interfere with DELETE/GLOBAL and other similar DCL commands.)

9.2 Why does SHOW QUOTA give a different answer than DIR/SIZE?

DIRECTORY/SIZE doesn't take into account the size of file headers which are charged to your quota. Also, unless you use DIRECTORY/SIZE:ALL, you will see only the "used" size of the file, not the allocated size which is what gets charged against your quota. Also, you may have files in other directories.


$ DIRECTORY/SIZE=ALL/GRAND [username...] 
Grand total of D1 directories, F1 files, B1/B2 blocks. 
$ DIRECTORY/SIZZ=ALL/GRAND [-]username.DIR 
Grand total of 1 directory, 1 file, B3/B4 blocks. 
$ SHOW QUOTA 
User [username] has B5 blocks used, B6 available 
of B7 authorized and permitted overdraft of B8 blocks on disk 

If the user has no files in other directories and all file-headers are only 1 block, then the following should apply:


  B5=B2+B4+F1+1 

If the diskquota has drifted out of synchronization, then the system-manager can force a quota rebuild---due to various factors, the quota file can potentially drift from the actual use over time, and a periodic rebuild can be performed at appropriate intervals.

Also be aware that the DIRECTORY/SIZE command can report larger values than might otherwise be expected when used to evaluate files and/or directories that are alias links---such as the system roots on OpenVMS system disks---as the command reports a total that is cumulative over all of the files and directories examined, without regard for which ones might be alias entries and which are not. (In other words, a DIRECTORY/SIZE of an entire OpenVMS system disk will report a disk useage value larger than the (usually more accurate) value reported by the SHOW DEVICE command. This as a result of the alias entries linking each SYS$SYSDEVICE:[SYSCOMMON]SYS*.DIR directory file and the SYS$SYSDEVICE:[000000]VMS$COMMON.DIR file together.)

9.3 How do I make sure that my data is safely written to disk?

If your application must absolutely guarantee that data is available, no matter what, there's really no substitute for RMS Journaling and host- or controller-based shadowing. However, you can achieve a good degree of data integrity by issuing a SYS$FLUSH RMS call at appropriate times (if you're using RMS, that is.) If you're using a high-level language's I/O system, check that language's documentation to see if you can access the RMS control blocks for the open file. In C you can use fflush followed by fsync.

For details on disk bad block handling on MSCP and on SCSI disk devices, please see Ask The Wizard (ATW) topic (6926).

For additional information on the OpenVMS Ask The Wizard (ATW) area and for a pointer to the available ATW Wizard.zip archive, please see Section 3.9.

9.4 What are the limits on file specifications and directories?

A file specification has an aggregate maximum size of 255 characters at present. The node and device specification may be up to 255 characters each - file name and file types may be up to 39 characters each. File versions are from 1 through 32767, though 0 (latest version), -0 (oldest version) and -n (n'th previous version) can be used in most contexts. A file specification may not have more than 8 directories and subdirectories - while it is possible to create subdirectories of greater depth, accessing them is problematic in most cases and this should be avoided.

Application developers should use OpenVMS-supplied routines for parsing file specifications - this ensures that changes in what is allowable will not tend to break your application. Consider that various parts of the file specification may contain quoted strings with embedded spaces and other punctuation! Some routines of interest are SYS$FILESCAN, SYS$PARSE and LIB$TRIM_FILESPEC. For further information, see the OpenVMS Guide to File Applications.

Performance of larger directory files improves (greatly) with OpenVMS V7.2 and later---operations on directory files of 128 blocks and larger were rather slower on earlier OpenVMS releases due to the smaller size of the directory cache and due to the directory I/O processing logic.

For fastest directory deletions, consider a reverse deletion---delete from the last file in the directory to the first. This reversal speeds the deletion operation by avoiding unnecessary directory I/O operations as the files are deleted. Tools such as the Freeware DFU can be used for this purpose, as can various available reverse-DELETE DCL command procedures.

9.5 What is the largest disk volume size OpenVMS can access?

One Terabyte (TB; 2**31 blocks of 2**9 bytes; 0x07FFFFFFF blocks). 255 volumes in a volume set. The largest contiguous allocation possible for any particular file is 0x03FFFFFFF blocks.

Prior to the release of V6.0, the OpenVMS file system was limited to disk volumes of 8.38 GB (2**24 blocks, 16777216 blocks) or less.

On some systems, there are restrictions in the console program that limit the size of the OpenVMS system disk. Note that data disks are not affected by console program limits. For example, all members of the VAXstation 3100 series are limited to a system disk to 1.073 GB or less due to the console, though larger data disks are possible. This limit due to the SCSI drivers used by and built into the console ROM to read the OpenVMS bootstrap files, and these same drivers are also used by OpenVMS to write the system crashump.

There are numerous discussions of this VAXstation 3100 in the comp.os.vms newsgroup archives. Please use Google newsgroup search to search the archives for further details, for discussions of the workarounds, and for details of the potential for a simple failed bootstrap and particularly for discussions of the potential for severe system disk corruptions on crashes.

Some SCSI disks with capacities larger than 8.58 gigabytes (GB) will require the use of an OpenVMS ECO kit (eg: ALPSCSI04_062 or later; see Section 14.26 for details) for new SCSI device drivers. Failure to use this ECO can cause "rounding errors" on the SCSI disk device capacity---OpenVMS will not use nor display the full capacity of the drive---and "%sysinit-e-error mounting system device status equals 000008C4" (8C4 -> "%SYSTEM-?-FILESTRUCT, unsupported file structure level") errors during bootstrap. (One workaround for the bootstrap when the bitmap is located far into the disk is the use of INIT/INDEX=BEGIN.) The problem here involves the particular extensions and fields used for larger capacity disks within the SCSI specifications and within the various intepretations of same.

For ATA (IDE) disk drives:

See Section 14.4.4.2 for additional ATA SYS$DQDRIVER information.

Be aware that a known restriction in certain older versions of the Alpha SRM Console prevents booting most ATA (IDE) drives larger than 8.455 GB, depending on exactly where the various files are located on the volume. Updated SRM consoles for systems with SRM and ATA (IDE) drive support are (will be) available. (OpenVMS Engineering has successfully bootstrapped 20GB ATA (IDE) disks using the appropriate SRM console version.)

NOTE: All ATA-related disk sizes listed in this section are stated in units of "disk (base ten) gigabytes" (1 GB = 10^9 bytes) and NOT in units of "software (base two) gigabytes" (1 GB = 2^30 (1073741824.) bytes. See Section 14.26.

Be aware that larger disks that are using an extension of SCSI-2--- disks that are using a mode page field that the SCSI-2 specifications normally reserved for tape devices---to permit a larger disk volume size will require a SCSI driver update for OpenVMS, and this change is part of V7.1-2 and later, and also part of ALPSCSI07_062 and later. (These larger disks disks will typically report a DRVERR, or will see the volume size "rounded down".) SCSI disks larger than 16777216 blocks cira 8.455 GB (base ten); 8GB (base two) require this ECO, or require the use of OpenVMS Alpha V7.1-2 or later.

Applications written in C can be limited to file sizes of two gigabytes and less, as a result of the use of longword values within C file operations, and specifically off_t. This restriction is lifted in OpenVMS V7.3-1 and later, and with the application of the C ECO kits available for specific earlier releases. The use of a longword for off_t restricts applications using native C I/O to file sizes of two gigabytes or less, or these applications must use native RMS or XQP calls for specific operations.

Also see Section 14.14, Section 14.26.


Previous Next Contents Index