perlvms - VMS-specific documentation for Perl


DESCRIPTION

       Gathered below are notes describing details of Perl 5's
       behavior on VMS.  They are a supplement to the regular
       Perl 5 documentation, so we have focussed on the ways in
       which Perl 5 functions differently under VMS than it does
       under Unix, and on the interactions between Perl and the
       rest of the operating system.  We haven't tried to dupli­
       cate complete descriptions of Perl features from the main
       Perl documentation, which can be found in the [.pod] sub­
       directory of the Perl distribution.

       We hope these notes will save you from confusion and lost
       sleep when writing Perl scripts on VMS.  If you find we've
       missed something you think should appear here, please
       don't hesitate to drop a line to vmsperl@newman.upenn.edu.


Installation

       Directions for building and installing Perl 5 can be found
       in the file README.vms in the main source directory of the
       Perl distribution..


Organization of Perl Images

       Core Images

       During the installation process, three Perl images are
       produced.  Miniperl.Exe is an executable image which con­
       tains all of the basic functionality of Perl, but cannot
       take advantage of Perl extensions.  It is used to generate
       several files needed to build the complete Perl and vari­
       ous extensions.  Once you've finished installing Perl, you
       can delete this image.

       Most of the complete Perl resides in the shareable image
       PerlShr.Exe, which provides a core to which the Perl exe­
       cutable image and all Perl extensions are linked.  You
       should place this image in Sys$Share, or define the logi­
       cal name PerlShr to translate to the full file specifica­
       tion of this image.  It should be world readable.  (Remem­
       ber that if a user has execute only access to PerlShr, VMS
       will treat it as if it were a privileged shareable image,
       and will therefore require all downstream shareable images
       to be INSTALLed, etc.)

       Finally, Perl.Exe is an executable image containing the
       main entry point for Perl, as well as some initialization
       code.  It should be placed in a public directory, and made
       world executable.  In order to run Perl with command line
       arguments, you should define a foreign command to invoke
       this image.


       Perl extensions are packages which provide both XS and
       Perl code to add new functionality to perl.  (XS is a
       meta-language which simplifies writing C code which inter­
       acts with Perl, see the perlxs manpage for more details.)
       The Perl code for an extension is treated like any other
       library module - it's made available in your script
       through the appropriate `use' or `require' statement, and
       usually defines a Perl package containing the extension.

       The portion of the extension provided by the XS code may
       be connected to the rest of Perl in either of two ways.
       In the static configuration, the object code for the
       extension is linked directly into PerlShr.Exe, and is ini­
       tialized whenever Perl is invoked.  In the dynamic config­
       uration, the extension's machine code is placed into a
       separate shareable image, which is mapped by Perl's
       DynaLoader when the extension is `use'd or `require'd in
       your script.  This allows you to maintain the extension as
       a separate entity, at the cost of keeping track of the
       additional shareable image.  Most extensions can be set up
       as either static or dynamic.

       The source code for an extension usually resides in its
       own directory.  At least three files are generally pro­
       vided: Extshortname.xs (where Extshortname is the portion
       of the extension's name following the last `::'), contain­
       ing the XS code, Extshortname.pm, the Perl library module
       for the extension, and Makefile.PL, a Perl script which
       uses the `MakeMaker' library modules supplied with Perl to
       generate a Descrip.MMS file for the extension.

       Installing static extensions

       Since static extensions are incorporated directly into
       PerlShr.Exe, you'll have to rebuild Perl to incorporate a
       new extension.  You should edit the main Descrip.MMS or
       Makefile you use to build Perl, adding the extension's
       name to the `ext' macro, and the extension's object file
       to the `extobj' macro.  You'll also need to build the
       extension's object file, either by adding dependencies to
       the main Descrip.MMS, or using a separate Descrip.MMS for
       the extension.  Then, rebuild PerlShr.Exe to incorporate
       the new code.

       Finally, you'll need to copy the extension's Perl library
       module to the [.Extname] subdirectory under one of the
       directories in `@INC', where Extname is the name of the
       extension, with all `::' replaced by `.' (e.g.  the
       library module for extension Foo::Bar would be copied to a
       [.Foo.Bar] subdirectory).


       In general, the distributed kit for a Perl extension
       includes a file named Makefile.PL, which is a Perl program
       which is used to create a Descrip.MMS file which can be
       used to build and install the files required by the exten­
       sion.  The kit should be unpacked into a directory tree
       not under the main Perl source directory, and the proce­
       dure for building the extension is simply

           $ perl Makefile.PL  ! Create Descrip.MMS
           $ mmk               ! Build necessary files
           $ mmk test          ! Run test code, if supplied
           $ mmk install       ! Install into public Perl tree

       N.B. The procedure by which extensions are built and
       tested creates several levels (at least 4) under the
       directory in which the extension's source files live.  For
       this reason, you shouldn't nest the source directory too
       deeply in your directory structure, lest you eccedd RMS'
       maximum of 8 levels of subdirectory in a filespec.  (You
       can use rooted logical names to get another 8 levels of
       nesting, if you can't place the files near the top of the
       physical directory structure.)

       VMS support for this process in the current release of
       Perl is sufficient to handle most extensions.  However, it
       does not yet recognize extra libraries required to build
       shareable images which are part of an extension, so these
       must be added to the linker options file for the extension
       by hand.  For instance, if the PGPLOT extension to Perl
       requires the PGPLOTSHR.EXE shareable image in order to
       properly link the Perl extension, then the line `PGPLOT­
       SHR/Share' must be added to the linker options file
       PGPLOT.Opt produced during the build process for the Perl
       extension.

       By default, the shareable image for an extension is placed
       [.lib.site_perl.autoArch.Extname] directory of the
       installed Perl directory tree (where Arch is VMS_VAX or
       VMS_AXP, and Extname is the name of the extension, with
       each `::' translated to `.').  (See the MakeMaker documen­
       tation for more details on installation options for exten­
       sions.)  However, it can be manually placed in any of sev­
       eral locations:
          - the [.Lib.Auto.Arch$PVersExtname] subdirectory
            of one of the directories in `@INC' (where PVers
            is the version of Perl you're using, as supplied in
       `$]',
            with '.' converted to '_'), or
          - one of the directories in `@INC', or
          - a directory which the extensions Perl library module
            passes to the DynaLoader when asking it to map
            the shareable image, or

       isn't in any of these places, you'll need to define a log­
       ical name Extshortname, where Extshortname is the portion
       of the extension's name after the last `::', which trans­
       lates to the full file specification of the shareable
       image.


File specifications

       Syntax

       We have tried to make Perl aware of both VMS-style and
       Unix- style file specifications wherever possible.  You
       may use either style, or both, on the command line and in
       scripts, but you may not combine the two styles within a
       single fle specification.  VMS Perl interprets Unix path­
       names in much the same way as the CRTL (e.g. the first
       component of an absolute path is read as the device name
       for the VMS file specification).  There are a set of func­
       tions provided in the `VMS::Filespec' package for explicit
       interconversion between VMS and Unix syntax; its documen­
       tation provides more details.

       Filenames are, of course, still case-insensitive.  For
       consistency, most Perl routines return  filespecs using
       lower case letters only, regardless of the case used in
       the arguments passed to them.  (This is true  only when
       running under VMS; Perl respects the case-sensitivity of
       OSs like Unix.)

       We've tried to minimize the dependence of Perl library
       modules on Unix syntax, but you may find that some of
       these, as well as some scripts written for Unix systems,
       will require that you use Unix syntax, since they will
       assume that '/' is the directory separator, etc.  If you
       find instances of this in the Perl distribution itself,
       please let us know, so we can try to work around them.

       Wildcard expansion

       File specifications containing wildcards are allowed both
       on the command line and within Perl globs (e.g. <C<*.c>>).
       If the wildcard filespec uses VMS syntax, the resultant
       filespecs will follow VMS syntax; if a Unix-style filespec
       is passed in, Unix-style filespecs will be returned.

       In both cases, VMS wildcard expansion is performed. (csh-
       style wildcard expansion is available if you use
       `File::Glob::glob'.)  If the wildcard filespec contains a
       device or directory specification, then the resultant
       filespecs will also contain a device and directory; other­
       wise, device and directory information are removed.  VMS-
       style resultant filespecs will contain a full device and
       directory, while Unix-style resultant filespecs will con­
       tain only as much of a directory path as was present in

       tory is Perl_Root:[000000], the expansion of `[.t]*.*'
       will yield filespecs  like "perl_root:[t]base.dir", while
       the expansion of `t/*/*' will yield filespecs like
       "t/base.dir".  (This is done to match the behavior of glob
       expansion performed by Unix shells.)

       Similarly, the resultant filespec will contain the file
       version only if one was present in the input filespec.

       Pipes

       Input and output pipes to Perl filehandles are supported;
       the "file name" is passed to lib$spawn() for asynchronous
       execution.  You should be careful to close any pipes you
       have opened in a Perl script, lest you leave any
       "orphaned" subprocesses around when Perl exits.

       You may also use backticks to invoke a DCL subprocess,
       whose output is used as the return value of the expres­
       sion.  The string between the backticks is handled as if
       it were the argument to the `system' operator (see below).
       In this case, Perl will wait for the subprocess to com­
       plete before continuing.


PERL5LIB and PERLLIB

       The PERL5LIB and PERLLIB logical names work as documented
       the perl manpage, except that the element separator is '|'
       instead of ':'.  The directory specifications may use
       either VMS or Unix syntax.


Command line

       I/O redirection and backgrounding

       Perl for VMS supports redirection of input and output on
       the command line, using a subset of Bourne shell syntax:

           <Fand the script name does
           not contain a directory, then Perl translates the log­
           ical name DCL$PATH as a searchlist, using each trans­
           lation as a directory in which to look for the script.
           In addition, if no file type is specified, Perl looks
           in each directory for a file matching the name speci­
           fied, with a blank type, a type of .pl, and a type of
           .com, in that order.

       -u  The `-u' switch causes the VMS debugger to be invoked
           after the Perl program is compiled, but before it has
           run.  It does not create a core dump file.


Perl functions

       As of the time this document was last revised, the follow­
       ing Perl functions were implemented in the VMS port of
       Perl (functions marked with * are discussed in more detail
       below):

           caller, chdir, chmod, chown, chomp, chop, chr,
           close, closedir, cos, crypt*, defined, delete,
           die, do, dump*, each, endpwent, eof, eval, exec*,
           exists, exit, exp, fileno, fork*, getc, getlogin,
           getpwent*, getpwnam*, getpwuid*, glob, gmtime*, goto,
           grep, hex, import, index, int, join, keys, kill*,
           last, lc, lcfirst, length, local, localtime, log, m//,
           map, mkdir, my, next, no, oct, open, opendir, ord, pack,
           pipe, pop, pos, print, printf, push, q//, qq//, qw//,
           qx//*, quotemeta, rand, read, readdir, redo, ref, rename,
           require, reset, return, reverse, rewinddir, rindex,
           rmdir, s///, scalar, seek, seekdir, select(internal),
           select (system call)*, setpwent, shift, sin, sleep,
           sort, splice, split, sprintf, sqrt, srand, stat,
           study, substr, sysread, system*, syswrite, tell,
           telldir, tie, time, times*, tr///, uc, ucfirst, umask,
           undef, unlink*, unpack, untie, unshift, use, utime*,
           values, vec, wait, waitpid*, wantarray, warn, write, y///

       The following functions were not implemented in the VMS
       port, and calling them produces a fatal error (usually) or
       undefined behavior (rarely, we hope):

           chroot, dbmclose, dbmopen, fcntl, flock,
           getpgrp, getppid, getpriority, getgrent, getgrgid,
           getgrnam, setgrent, endgrent, ioctl, link, lstat,
           msgctl, msgget, msgsend, msgrcv, readlink, semctl,
           semget, semop, setpgrp, setpriority, shmctl, shmget,
           shmread, shmwrite, socketpair, symlink, syscall

       The following functions are available on Perls compiled
       with Dec C 5.2 or greater and running VMS 7.0 or greater

           truncate

       The following functions may or may not be implemented,
       depending on what type of socket support you've built into
       your copy of Perl:

           accept, bind, connect, getpeername,
           gethostbyname, getnetbyname, getprotobyname,
           getservbyname, gethostbyaddr, getnetbyaddr,
           getprotobynumber, getservbyport, gethostent,
           getnetent, getprotoent, getservent, sethostent,
           setnetent, setprotoent, setservent, endhostent,
           endnetent, endprotoent, endservent, getsockname,
           getsockopt, listen, recv, select(system call)*,
           send, setsockopt, shutdown, socket

       File tests
           The tests `-b', `-B', `-c', `-C', `-d', `-e', `-f',
           `-o', `-M', `-s', `-S', `-t', `-T', and `-z' work as

           `-x' tell you whether you can actually access the
           file; this may not reflect the UIC-based file protec­
           tions.  Since real and effective UIC don't differ
           under VMS, `-O', `-R', `-W', and `-X' are equivalent
           to `-o', `-r', `-w', and `-x'.  Similarly, several
           other tests, including `-A', `-g', `-k', `-l', `-p',
           and `-u', aren't particularly meaningful under VMS,
           and the values returned by these tests reflect what­
           ever your CRTL `stat()' routine does to the equivalent
           bits in the st_mode field.  Finally, `-d' returns true
           if passed a device specification without an explicit
           directory (e.g. `DUA1:'), as well as if passed a
           directory.

           Note: Some sites have reported problems when using the
           file-access tests (`-r', `-w', and `-x') on files
           accessed via DEC's DFS.  Specifically, since DFS does
           not currently provide access to the extended file
           header of files on remote volumes, attempts to examine
           the ACL fail, and the file tests will return false,
           with `$!' indicating that the file does not exist.
           You can use `stat' on these files, since that checks
           UIC-based protection only, and then manually check the
           appropriate bits, as defined by your C compiler's
           stat.h, in the mode value it returns, if you need an
           approximation of the file's protections.

       backticks
           Backticks create a subprocess, and pass the enclosed
           string to it for execution as a DCL command.  Since
           the subprocess is created directly via `lib$spawn()',
           any valid DCL command string may be specified.

       binmode FILEHANDLE
           The `binmode' operator will attempt to insure that no
           translation of carriage control occurs on input from
           or output to this filehandle.  Since this involves
           reopening the file and then restoring its file posi­
           tion indicator, if this function returns FALSE, the
           underlying filehandle may no longer point to an open
           file, or may point to a different position in the file
           than before `binmode' was called.

           Note that `binmode' is generally not necessary when
           using normal filehandles; it is provided so that you
           can control I/O to existing record-structured files
           when necessary.  You can also use the `vmsfopen' func­
           tion in the VMS::Stdio extension to gain finer control
           of I/O to files and devices with different record
           structures.

       crypt PLAINTEXT, USER
           The `crypt' operator uses the `sys$hash_password'

           of PLAINTEXT.  If USER is a valid username, the algo­
           rithm and salt values are taken from that user's UAF
           record.  If it is not, then the preferred algorithm
           and a salt of 0 are used.  The quadword encrypted
           value is returned as an 8-character string.

           The value returned by `crypt' may be compared against
           the encrypted password from the UAF returned by the
           `getpw*' functions, in order to authenticate users.
           If you're going to do this, remember that the
           encrypted password in the UAF was generated using
           uppercase username and password strings; you'll have
           to upcase the arguments to `crypt' to insure that
           you'll get the proper value:

             sub validate_passwd {
               my($user,$passwd) = @_;
               my($pwdhash);
               if ( !($pwdhash = (getpwnam($user))[1]) ||
                    $pwdhash ne crypt("\U$passwd","\U$name") ) {
                 intruder_alert($name);
               }
               return 1;
             }

       dump
           Rather than causing Perl to abort and dump core, the
           `dump' operator invokes the VMS debugger.  If you con­
           tinue to execute the Perl program under the debugger,
           control will be transferred to the label specified as
           the argument to `dump', or, if no label was specified,
           back to the beginning of the program.  All other state
           of the program (e.g. values of variables, open file
           handles) are not affected by calling `dump'.

       exec LIST
           The `exec' operator behaves in one of two different
           ways.  If called after a call to `fork', it will
           invoke the CRTL `execv()' routine, passing its argu­
           ments to the subprocess created by `fork' for execu­
           tion.  In this case, it is subject to all limitations
           that affect `execv()'.  (In particular, this usually
           means that the command executed in the subprocess must
           be an image compiled from C source code, and that your
           options for passing file descriptors and signal han­
           dlers to the subprocess are limited.)

           If the call to `exec' does not follow a call to
           `fork', it will cause Perl to exit, and to invoke the
           command given as an argument to `exec' via
           `lib$do_command'.  If the argument begins with '@' or
           '$' (other than as part of a filespec), then it is

           on the command line is treated as the filespec of an
           image to run, and an attempt is made to invoke it
           (using .Exe and the process defaults to expand the
           filespec) and pass the rest of `exec''s argument to it
           as parameters.  If the token has no file type, and
           matches a file with null type, then an attempt is made
           to determine whether the file is an executable image
           which should be invoked using `MCR' or a text file
           which should be passed to DCL as a command procedure.

           You can use `exec' in both ways within the same
           script, as long as you call `fork' and `exec' in
           pairs.  Perl keeps track of how many times `fork' and
           `exec' have been called, and will call the CRTL
           `execv()' routine if there have previously been more
           calls to `fork' than to `exec'.

       fork
           The `fork' operator works in the same way as the CRTL
           `vfork()' routine, which is quite different under VMS
           than under Unix.  Specifically, while `fork' returns 0
           after it is called and the subprocess PID after `exec'
           is called, in both cases the thread of execution is
           within the parent process, so there is no opportunity
           to perform operations in the subprocess before calling
           `exec'.

           In general, the use of `fork' and `exec' to create
           subprocess is not recommended under VMS; wherever pos­
           sible, use the `system' operator or piped filehandles
           instead.

       getpwent

       getpwnam

       getpwuid
           These operators obtain the information described in
           the perlfunc manpage, if you have the privileges nec­
           essary to retrieve the named user's UAF information
           via `sys$getuai'.  If not, then only the `$name',
           `$uid', and `$gid' items are returned.  The `$dir'
           item contains the login directory in VMS syntax, while
           the `$comment' item contains the login directory in
           Unix syntax. The `$gcos' item contains the owner field
           from the UAF record.  The `$quota' item is not used.

       gmtime
           The `gmtime' operator will function properly if you
           have a working CRTL `gmtime()' routine, or if the log­
           ical name SYS$TIMEZONE_DIFFERENTIAL is defined as the
           number of seconds which must be added to UTC to yield
           local time.  (This logical name is defined

           built-in UTC support.)  If neither of these cases is
           true, a warning message is printed, and `undef' is
           returned.

       kill
           In most cases, `kill' kill is implemented via the
           CRTL's `kill()' function, so it will behave according
           to that function's documentation.  If you send a
           SIGKILL, however, the $DELPRC system service is called
           directly.  This insures that the target process is
           actually deleted, if at all possible.  (The CRTL's
           `kill()' function is presently implemented via
           $FORCEX, which is ignored by supervisor-mode images
           like DCL.)

           Also, negative signal values don't do anything special
           under VMS; they're just converted to the corresponding
           positive value.

       qx//
           See the entry on `backticks' above.

       select (system call)
           If Perl was not built with socket support, the system
           call version of `select' is not available at all.  If
           socket support is present, then the system call ver­
           sion of `select' functions only for file descriptors
           attached to sockets.  It will not provide information
           about regular files or pipes, since the CRTL
           `select()' routine does not provide this functional­
           ity.

       stat EXPR
           Since VMS keeps track of files according to a differ­
           ent scheme than Unix, it's not really possible to rep­
           resent the file's ID in the `st_dev' and `st_ino'
           fields of a `struct stat'.  Perl tries its best,
           though, and the values it uses are pretty unlikely to
           be the same for two different files.  We can't guaran­
           tee this, though, so caveat scriptor.

       system LIST
           The `system' operator creates a subprocess, and passes
           its arguments to the subprocess for execution as a DCL
           command.  Since the subprocess is created directly via
           `lib$spawn()', any valid DCL command string may be
           specified.  If the string begins with '@', it is
           treated as a DCL command unconditionally.  Otherwise,
           if the first token contains a character used as a
           delimiter in file specification (e.g. `:' or `]'), an
           attempt is made to expand it using  a default type of
           .Exe and the process defaults, and if successful, the
           resulting file is invoked via `MCR'. This allows you

           specification to `system', a common Unixish idiom.  If
           the token has no file type, and matches a file with
           null type, then an attempt is made to determine
           whether the file is an executable image which should
           be invoked using `MCR' or a text file which should be
           passed to DCL as a command procedure.

           If LIST consists of the empty string, `system' spawns
           an interactive DCL subprocess, in the same fashion as
           typiing SPAWN at the DCL prompt.

           Perl waits for the subprocess to complete before con­
           tinuing execution in the current process.  As
           described in the perlfunc manpage, the return value of
           `system' is a fake "status" which follows POSIX seman­
           tics; see the description of `$?' in this document for
           more detail.  The actual VMS exit status of the sub­
           process is available in `$^S' (as long as you haven't
           used another Perl function that resets `$?' and `$^S'
           in the meantime).

       time
           The value returned by `time' is the offset in seconds
           from 01-JAN-1970 00:00:00 (just like the CRTL's
           times() routine), in order to make life easier for
           code coming in from the POSIX/Unix world.

       times
           The array returned by the `times' operator is divided
           up according to the same rules the CRTL `times()' rou­
           tine.  Therefore, the "system time" elements will
           always be 0, since there is no difference between
           "user time" and "system" time under VMS, and the time
           accumulated by subprocess may or may not appear sepa­
           rately in the "child time" field, depending on whether
           the times manpage keeps track of subprocesses sepa­
           rately.  Note especially that the VAXCRTL (at least)
           keeps track only of subprocesses spawned using the
           fork manpage and the exec manpage; it will not accumu­
           late the times of suprocesses spawned via pipes, the
           system manpage, or backticks.

       unlink LIST
           `unlink' will delete the highest version of a file
           only; in order to delete all versions, you need to say
               1 while (unlink LIST); You may need to make this
           change to scripts written for a Unix system which
           expect that after a call to `unlink', no files with
           the names passed to `unlink' will exist.  (Note: This
           can be changed at compile time; if you `use Config'
           and `$Config{'d_unlink_all_versions'}' is `define',
           then `unlink' will delete all versions of a file on
           the first call.)

           if it requires changing file protection (though it
           won't try to change the protection of the parent
           directory).  You can tell whether you've got explicit
           delete access to a file by using the `VMS::File­
           spec::candelete' operator.  For instance, in order to
           delete only files to which you have delete access, you
           could say something like

               sub safe_unlink {
                   my($file,$num);
                   foreach $file (@_) {
                       next unless VMS::Filespec::candelete($file);
                       $num += unlink $file;
                   }
                   $num;
               }

           (or you could just use `VMS::Stdio::remove', if you've
           installed the VMS::Stdio extension distributed with
           Perl). If `unlink' has to change the file protection
           to delete the file, and you interrupt it in midstream,
           the file may be left intact, but with a changed ACL
           allowing you delete access.

       utime LIST
           Since ODS-2, the VMS file structure for disk files,
           does not keep track of access times, this operator
           changes only the modification time of the file (VMS
           revision date).

       waitpid PID,FLAGS
           If PID is a subprocess started by a piped the open
           manpage, `waitpid' will wait for that subprocess, and
           return its final status value.  If PID is a subprocess
           created in some other way (e.g. SPAWNed before Perl
           was invoked), or is not a subprocess of the current
           process, `waitpid' will check once per second whether
           the process has completed, and when it has, will
           return 0.  (If PID specifies a process that isn't a
           subprocess of the current process, and you invoked
           Perl with the `-w' switch, a warning will be issued.)

           The FLAGS argument is ignored in all cases.


Perl variables

       The following VMS-specific information applies to the
       indicated "special" Perl variables, in addition to the
       general information in the perlvar manpage.  Where there
       is a conflict, this infrmation takes precedence.

       %ENV
           The operation of the `%ENV' array depends on the
           translation of the logical name PERL_ENV_TABLES.  If

           which specifies a location for `%ENV' elements.  If
           you tell Perl to read or set the element
           `$ENV{'name`}', then Perl uses the translations of
           PERL_ENV_TABLES as follows:

           CRTL_ENV
               This string tells Perl to consult the CRTL's
               internal `environ' array of key-value pairs, using
               name as the key.  In most cases, this contains
               only a few keys, but if Perl was invoked via the C
               `exec[lv]e()' function, as is the case for CGI
               processing by some HTTP servers, then the `envi­
               ron' array may have been populated by the calling
               program.

           CLISYM_[LOCAL]
               A string beginning with `CLISYM_'tells Perl to
               consult the CLI's symbol tables, using name as the
               name of the symbol.  When reading an element of
               `%ENV', the local symbol table is scanned first,
               followed by the global symbol table..  The charac­
               ters following `CLISYM_' are significant when an
               element of `%ENV' is set or deleted: if the com­
               plete string is `CLISYM_LOCAL', the change is made
               in the local symbol table, otherwise the global
               symbol table is changed.

           Any other string
               If an element of PERL_ENV_TABLES translates to any
               other string, that string is used as the name of a
               logical name table, which is consulted using name
               as the logical name.  The normal search order of
               access modes is used.

           PERL_ENV_TABLES is translated once when Perl starts
           up; any changes you make while Perl is running do not
           affect the behavior of `%ENV'.  If PERL_ENV_TABLES is
           not defined, then Perl defaults to consulting first
           the logical name tables specified by LNM$FILE_DEV, and
           then the CRTL `environ' array.

           In all operations on %ENV, the key string is treated
           as if it were entirely uppercase, regardless of the
           case actually specified in the Perl expression.

           When an element of `%ENV' is read, the locations to
           which PERL_ENV_TABLES points are checked in order, and
           the value obtained from the first successful lookup is
           returned.  If the name of the `%ENV' element contains
           a semi-colon, it and any characters after it are
           removed.  These are ignored when the CRTL `environ'
           array or a CLI symbol table is consulted.  However,
           the name is looked up in a logical name table, the

           tion index to be used for the lookup.   This lets you
           look up successive values for search list logical
           names.  For instance, if you say

              $  Define STORY  once,upon,a,time,there,was
              $  perl -e "for ($i = 0; $i <= 6; $i++) " -
              _$ -e "{ print $ENV{'story;'.$i},' '}"

           Perl will print `ONCE UPON A TIME THERE WAS', assum­
           ing, of course, that PERL_ENV_TABLES is set up so that
           the logical name `story' is found, rather than a CLI
           symbol or CRTL `environ' element with the same name.

           When an element of `%ENV' is set to a defined string,
           the corresponding definition is made in the location
           to which the first translation of PERL_ENV_TABLES
           points.  If this causes a logical name to be created,
           it is defined in supervisor mode.  (The same is done
           if an existing logical name was defined in executive
           or kernel mode; an existing user or supervisor mode
           logical name is reset to the new value.)  If the value
           is an empty string, the logical name's translation is
           defined as a single NUL (ASCII 00) character, since a
           logical name cannot translate to a zero-length string.
           (This restriction does not apply to CLI symbols or
           CRTL `environ' values; they are set to the empty
           string.)  An element of the CRTL `environ' array can
           be set only if your copy of Perl knows about the
           CRTL's `setenv()' function.  (This is present only in
           some versions of the DECCRTL; check `$Con­
           fig{d_setenv}' to see whether your copy of Perl was
           built with a CRTL that has this function.)

           When an element of `%ENV' is set to `undef', the ele­
           ment is looked up as if it were being read, and if it
           is found, it is deleted.  (An item "deleted" from the
           CRTL `environ' array is set to the empty string; this
           can only be done if your copy of Perl knows about the
           CRTL `setenv()' function.)  Using `delete' to remove
           an element from `%ENV' has a similar effect, but after
           the element is deleted, another attempt is made to
           look up the element, so an inner-mode logical name or
           a name in another location will replace the logical
           name just deleted.  In either case, only the first
           value found searching PERL_ENV_TABLES is altered.  It
           is not possible at present to define a search list
           logical name via %ENV.

           The element `$ENV{DEFAULT}' is special: when read, it
           returns Perl's current default device and directory,
           and when set, it resets them, regardless of the defi­
           nition of PERL_ENV_TABLES.  It cannot be cleared or
           deleted; attempts to do so are silently ignored.

           C-local environ array to a subprocess which isn't
           started by fork/exec, or isn't running a C program,
           you can "promote" them to logical names in the current
           process, which will then be inherited by all subpro­
           cesses, by saying

               foreach my $key (qw[C-local keys you want promoted]) {
                  my $temp = $ENV{$key}; # read from C-local array
                  $ENV{$key} = $temp;    # and define as logical name
               }

           (You can't just say `$ENV{$key} = $ENV{$key}', since
           the Perl optimizer is smart enough to elide the
           expression.)

           At present, the first time you iterate over %ENV using
           `keys', or `values',  you will incur a time penalty as
           all logical names are read, in order to fully populate
           %ENV.  Subsequent iterations will not reread logical
           names, so they won't be as slow, but they also won't
           reflect any changes to logical name tables caused by
           other programs.

           You do need to be careful with the logicals represent­
           ing process-permanent files, such as `SYS$INPUT' and
           `SYS$OUTPUT'.  The translations for these logicals are
           prepended with a two-byte binary value (0x1B 0x00)
           that needs to be stripped off if you want to use it.
           (In previous versions of perl it wasn't possible to
           get the values of these logicals, as the null byte
           acted as an end-of-string marker)

       $!  The string value of `$!' is that returned by the
           CRTL's strerror() function, so it will include the VMS
           message for VMS-specific errors.  The numeric value of
           `$!' is the value of `errno', except if errno is EVM­
           SERR, in which case `$!' contains the value of
           vaxc$errno.  Setting `$!'  always sets errno to the
           value specified.  If this value is EVMSERR, it also
           sets vaxc$errno to 4 (NONAME-F-NOMSG), so that the
           string value of `$!' won't reflect the VMS error mes­
           sage from before `$!' was set.

       $^E This variable provides direct access to VMS status
           values in vaxc$errno, which are often more specific
           than the generic Unix-style error messages in `$!'.
           Its numeric value is the value of vaxc$errno, and its
           string value is the corresponding VMS message string,
           as retrieved by sys$getmsg().  Setting `$^E' sets
           vaxc$errno to the value specified.

       $?  The "status value" returned in `$?' is synthesized
           from the actual exit status of the subprocess in a way

           allow Perl programs to portably test for successful
           completion of subprocesses.  The low order 8 bits of
           `$?' are always 0 under VMS, since the termination
           status of a process may or may not have been generated
           by an exception.  The next 8 bits are derived from
           severity portion of the subprocess' exit status: if
           the severity was success or informational, these bits
           are all 0; otherwise, they contain the severity value
           shifted left one bit.  As a result, `$?' will always
           be zero if the subprocess' exit status indicated suc­
           cessful completion, and non-zero if a warning or error
           occurred.  The actual VMS exit status may be found in
           `$^S' (q.v.).

       $^S Under VMS, this is the 32-bit VMS status value
           returned by the last subprocess to complete.  Unlink
           `$?', no manipulation is done to make this look like a
           POSIX wait(5) value, so it may be treated as a normal
           VMS status value.

       $|  Setting `$|' for an I/O stream causes data to be
           flushed all the way to disk on each write (i.e. not
           just to the underlying RMS buffers for a file).  In
           other words, it's equivalent to calling fflush() and
           fsync() from C.


Standard modules with VMS-specific differences

       SDBM_File

       SDBM_File works properly on VMS. It has, however, one
       minor difference. The database directory file created has
       a .sdbm_dir extension rather than a .dir extension. .dir
       files are VMS filesystem directory files, and using them
       for other purposes could cause unacceptable problems.


Revision date

       This document was last updated on 26-Feb-2000, for Perl 5,
       patchlevel 6.


AUTHOR

       Charles Bailey  <bailey@cor.newman.upenn.edu> Dan Sugalski
       <dan@sidhe.org>


Man(1) output converted with man2html