summaryrefslogtreecommitdiffstats
path: root/upstream/mageia-cauldron/man1/perlvms.1
diff options
context:
space:
mode:
Diffstat (limited to 'upstream/mageia-cauldron/man1/perlvms.1')
-rw-r--r--upstream/mageia-cauldron/man1/perlvms.11197
1 files changed, 1197 insertions, 0 deletions
diff --git a/upstream/mageia-cauldron/man1/perlvms.1 b/upstream/mageia-cauldron/man1/perlvms.1
new file mode 100644
index 00000000..dba02b0f
--- /dev/null
+++ b/upstream/mageia-cauldron/man1/perlvms.1
@@ -0,0 +1,1197 @@
+.\" -*- mode: troff; coding: utf-8 -*-
+.\" Automatically generated by Pod::Man 5.01 (Pod::Simple 3.43)
+.\"
+.\" Standard preamble:
+.\" ========================================================================
+.de Sp \" Vertical space (when we can't use .PP)
+.if t .sp .5v
+.if n .sp
+..
+.de Vb \" Begin verbatim text
+.ft CW
+.nf
+.ne \\$1
+..
+.de Ve \" End verbatim text
+.ft R
+.fi
+..
+.\" \*(C` and \*(C' are quotes in nroff, nothing in troff, for use with C<>.
+.ie n \{\
+. ds C` ""
+. ds C' ""
+'br\}
+.el\{\
+. ds C`
+. ds C'
+'br\}
+.\"
+.\" Escape single quotes in literal strings from groff's Unicode transform.
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\"
+.\" If the F register is >0, we'll generate index entries on stderr for
+.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
+.\" entries marked with X<> in POD. Of course, you'll have to process the
+.\" output yourself in some meaningful fashion.
+.\"
+.\" Avoid warning from groff about undefined register 'F'.
+.de IX
+..
+.nr rF 0
+.if \n(.g .if rF .nr rF 1
+.if (\n(rF:(\n(.g==0)) \{\
+. if \nF \{\
+. de IX
+. tm Index:\\$1\t\\n%\t"\\$2"
+..
+. if !\nF==2 \{\
+. nr % 0
+. nr F 2
+. \}
+. \}
+.\}
+.rr rF
+.\" ========================================================================
+.\"
+.IX Title "PERLVMS 1"
+.TH PERLVMS 1 2023-11-28 "perl v5.38.2" "Perl Programmers Reference Guide"
+.\" For nroff, turn off justification. Always turn off hyphenation; it makes
+.\" way too many mistakes in technical documents.
+.if n .ad l
+.nh
+.SH NAME
+perlvms \- VMS\-specific documentation for Perl
+.SH DESCRIPTION
+.IX Header "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 duplicate complete
+descriptions of Perl features from the main Perl
+documentation, which can be found in the \fI[.pod]\fR
+subdirectory of the Perl distribution.
+.PP
+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@perl.org.
+.SH Installation
+.IX Header "Installation"
+Directions for building and installing Perl 5 can be found in
+the file \fIREADME.vms\fR in the main source directory of the
+Perl distribution.
+.SH "Organization of Perl Images"
+.IX Header "Organization of Perl Images"
+.SS "Core Images"
+.IX Subsection "Core Images"
+During the build process, three Perl images are produced.
+\&\fIMiniperl.Exe\fR is an executable image which contains all of
+the basic functionality of Perl, but cannot take advantage of
+Perl XS extensions and has a hard-wired list of library locations
+for loading pure-Perl modules. It is used extensively to build and
+test Perl and various extensions, but is not installed.
+.PP
+Most of the complete Perl resides in the shareable image \fIPerlShr.Exe\fR,
+which provides a core to which the Perl executable image and all Perl
+extensions are linked. It is generally located via the logical name
+\&\fIPERLSHR\fR. While it's possible to put the image in \fISYS$SHARE\fR to
+make it loadable, that's not recommended. And while you may wish to
+INSTALL the image for performance reasons, you should not install it
+with privileges; if you do, the result will not be what you expect as
+image privileges are disabled during Perl start-up.
+.PP
+Finally, \fIPerl.Exe\fR 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.
+.SS "Perl Extensions"
+.IX Subsection "Perl Extensions"
+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 interacts with Perl, see
+perlxs 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
+\&\f(CW\*(C`use\*(C'\fR or \f(CW\*(C`require\*(C'\fR statement, and usually defines a Perl
+package containing the extension.
+.PP
+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
+\&\fBstatic\fR configuration, the object code for the extension is
+linked directly into \fIPerlShr.Exe\fR, and is initialized whenever
+Perl is invoked. In the \fBdynamic\fR configuration, the extension's
+machine code is placed into a separate shareable image, which is
+mapped by Perl's DynaLoader when the extension is \f(CW\*(C`use\*(C'\fRd or
+\&\f(CW\*(C`require\*(C'\fRd 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.
+.PP
+The source code for an extension usually resides in its own
+directory. At least three files are generally provided:
+\&\fIExtshortname\fR\fI.xs\fR (where \fIExtshortname\fR is the portion of
+the extension's name following the last \f(CW\*(C`::\*(C'\fR), containing
+the XS code, \fIExtshortname\fR\fI.pm\fR, the Perl library module
+for the extension, and \fIMakefile.PL\fR, a Perl script which uses
+the \f(CW\*(C`MakeMaker\*(C'\fR library modules supplied with Perl to generate
+a \fIDescrip.MMS\fR file for the extension.
+.SS "Installing static extensions"
+.IX Subsection "Installing static extensions"
+Since static extensions are incorporated directly into
+\&\fIPerlShr.Exe\fR, you'll have to rebuild Perl to incorporate a
+new extension. You should edit the main \fIDescrip.MMS\fR or \fIMakefile\fR
+you use to build Perl, adding the extension's name to the \f(CW\*(C`ext\*(C'\fR
+macro, and the extension's object file to the \f(CW\*(C`extobj\*(C'\fR macro.
+You'll also need to build the extension's object file, either
+by adding dependencies to the main \fIDescrip.MMS\fR, or using a
+separate \fIDescrip.MMS\fR for the extension. Then, rebuild
+\&\fIPerlShr.Exe\fR to incorporate the new code.
+.PP
+Finally, you'll need to copy the extension's Perl library
+module to the \fI[.\fR\fIExtname\fR\fI]\fR subdirectory under one
+of the directories in \f(CW@INC\fR, where \fIExtname\fR is the name
+of the extension, with all \f(CW\*(C`::\*(C'\fR replaced by \f(CW\*(C`.\*(C'\fR (e.g.
+the library module for extension Foo::Bar would be copied
+to a \fI[.Foo.Bar]\fR subdirectory).
+.SS "Installing dynamic extensions"
+.IX Subsection "Installing dynamic extensions"
+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 \fIDescrip.MMS\fR file which can be used to build and
+install the files required by the extension. The kit should be
+unpacked into a directory tree \fBnot\fR under the main Perl source
+directory, and the procedure for building the extension is simply
+.PP
+.Vb 4
+\& $ perl Makefile.PL ! Create Descrip.MMS
+\& $ mmk ! Build necessary files
+\& $ mmk test ! Run test code, if supplied
+\& $ mmk install ! Install into public Perl tree
+.Ve
+.PP
+VMS support for this process in the current release of Perl
+is sufficient to handle most extensions. (See the MakeMaker
+documentation for more details on installation options for
+extensions.)
+.IP \(bu 4
+the \fI[.Lib.Auto.\fR\fIArch\fR\f(CI$PVers\fR\fI\fR\fIExtname\fR\fI]\fR subdirectory
+of one of the directories in \f(CW@INC\fR (where \fIPVers\fR
+is the version of Perl you're using, as supplied in \f(CW$]\fR,
+with '.' converted to '_'), or
+.IP \(bu 4
+one of the directories in \f(CW@INC\fR, or
+.IP \(bu 4
+a directory which the extensions Perl library module
+passes to the DynaLoader when asking it to map
+the shareable image, or
+.IP \(bu 4
+\&\fISys$Share\fR or \fISys$Library\fR.
+.PP
+If the shareable image isn't in any of these places, you'll need
+to define a logical name \fIExtshortname\fR, where \fIExtshortname\fR
+is the portion of the extension's name after the last \f(CW\*(C`::\*(C'\fR, which
+translates to the full file specification of the shareable image.
+.SH "File specifications"
+.IX Header "File specifications"
+.SS Syntax
+.IX Subsection "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 file specification. VMS Perl interprets Unix
+pathnames in much the same way as the CRTL (\fIe.g.\fR the first component
+of an absolute path is read as the device name for the VMS file
+specification). There are a set of functions provided in the
+\&\f(CW\*(C`VMS::Filespec\*(C'\fR package for explicit interconversion between VMS and
+Unix syntax; its documentation provides more details.
+.PP
+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, \fIetc.\fR If you find instances
+of this in the Perl distribution itself, please let us know,
+so we can try to work around them.
+.PP
+Also when working on Perl programs on VMS, if you need a syntax
+in a specific operating system format, then you need either to
+check the appropriate DECC$ feature logical, or call a conversion
+routine to force it to that format.
+.PP
+The feature logical name DECC$FILENAME_UNIX_REPORT modifies traditional
+Perl behavior in the conversion of file specifications from Unix to VMS
+format in order to follow the extended character handling rules now
+expected by the CRTL. Specifically, when this feature is in effect, the
+\&\f(CW\*(C`./.../\*(C'\fR in a Unix path is now translated to \f(CW\*(C`[.^.^.^.]\*(C'\fR instead of
+the traditional VMS \f(CW\*(C`[...]\*(C'\fR. To be compatible with what MakeMaker
+expects, if a VMS path cannot be translated to a Unix path, it is
+passed through unchanged, so \f(CWunixify("[...]")\fR will return \f(CW\*(C`[...]\*(C'\fR.
+.PP
+There are several ambiguous cases where a conversion routine cannot
+determine whether an input filename is in Unix format or in VMS format,
+since now both VMS and Unix file specifications may have characters in
+them that could be mistaken for syntax delimiters of the other type. So
+some pathnames simply cannot be used in a mode that allows either type
+of pathname to be present. Perl will tend to assume that an ambiguous
+filename is in Unix format.
+.PP
+Allowing "." as a version delimiter is simply incompatible with
+determining whether a pathname is in VMS format or in Unix format with
+extended file syntax. There is no way to know whether "perl\-5.8.6" is a
+Unix "perl\-5.8.6" or a VMS "perl\-5.8;6" when passing it to \fBunixify()\fR or
+\&\fBvmsify()\fR.
+.PP
+The DECC$FILENAME_UNIX_REPORT logical name controls how Perl interprets
+filenames to the extent that Perl uses the CRTL internally for many
+purposes, and attempts to follow CRTL conventions for reporting
+filenames. The DECC$FILENAME_UNIX_ONLY feature differs in that it
+expects all filenames passed to the C run-time to be already in Unix
+format. This feature is not yet supported in Perl since Perl uses
+traditional OpenVMS file specifications internally and in the test
+harness, and it is not yet clear whether this mode will be useful or
+useable. The feature logical name DECC$POSIX_COMPLIANT_PATHNAMES is new
+with the RMS Symbolic Link SDK and included with OpenVMS v8.3, but is
+not yet supported in Perl.
+.SS "Filename Case"
+.IX Subsection "Filename Case"
+Perl enables DECC$EFS_CASE_PRESERVE and DECC$ARGV_PARSE_STYLE by
+default. Note that the latter only takes effect when extended parse
+is set in the process in which Perl is running. When these features
+are explicitly disabled in the environment or the CRTL does not support
+them, Perl follows the traditional CRTL behavior of downcasing command-line
+arguments and returning file specifications in lower case only.
+.PP
+\&\fIN. B.\fR It is very easy to get tripped up using a mixture of other
+programs, external utilities, and Perl scripts that are in varying
+states of being able to handle case preservation. For example, a file
+created by an older version of an archive utility or a build utility
+such as MMK or MMS may generate a filename in all upper case even on an
+ODS\-5 volume. If this filename is later retrieved by a Perl script or
+module in a case preserving environment, that upper case name may not
+match the mixed-case or lower-case expectations of the Perl code. Your
+best bet is to follow an all-or-nothing approach to case preservation:
+either don't use it at all, or make sure your entire toolchain and
+application environment support and use it.
+.PP
+OpenVMS Alpha v7.3\-1 and later and all version of OpenVMS I64 support
+case sensitivity as a process setting (see \f(CW\*(C`SET\ PROCESS\ /CASE_LOOKUP=SENSITIVE\*(C'\fR). Perl does not currently support case
+sensitivity on VMS, but it may in the future, so Perl programs should
+use the \f(CW\*(C`File::Spec\->case_tolerant\*(C'\fR method to determine the state, and
+not the \f(CW$^O\fR variable.
+.SS "Symbolic Links"
+.IX Subsection "Symbolic Links"
+When built on an ODS\-5 volume with symbolic links enabled, Perl by
+default supports symbolic links when the requisite support is available
+in the filesystem and CRTL (generally 64\-bit OpenVMS v8.3 and later).
+There are a number of limitations and caveats to be aware of when
+working with symbolic links on VMS. Most notably, the target of a valid
+symbolic link must be expressed as a Unix-style path and it must exist
+on a volume visible from your POSIX root (see the \f(CW\*(C`SHOW\ ROOT\*(C'\fR command
+in DCL help). For further details on symbolic link capabilities and
+requirements, see chapter 12 of the CRTL manual that ships with OpenVMS
+v8.3 or later.
+.SS "Wildcard expansion"
+.IX Subsection "Wildcard expansion"
+File specifications containing wildcards are allowed both on
+the command line and within Perl globs (e.g. \f(CW\*(C`<*.c>\*(C'\fR). 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.
+Similar to the behavior of wildcard globbing for a Unix shell,
+one can escape command line wildcards with double quotation
+marks \f(CW\*(C`"\*(C'\fR around a perl program command line argument. However,
+owing to the stripping of \f(CW\*(C`"\*(C'\fR characters carried out by the C
+handling of argv you will need to escape a construct such as
+this one (in a directory containing the files \fIPERL.C\fR, \fIPERL.EXE\fR,
+\&\fIPERL.H\fR, and \fIPERL.OBJ\fR):
+.PP
+.Vb 2
+\& $ perl \-e "print join(\*(Aq \*(Aq,@ARGV)" perl.*
+\& perl.c perl.exe perl.h perl.obj
+.Ve
+.PP
+in the following triple quoted manner:
+.PP
+.Vb 2
+\& $ perl \-e "print join(\*(Aq \*(Aq,@ARGV)" """perl.*"""
+\& perl.*
+.Ve
+.PP
+In both the case of unquoted command line arguments or in calls
+to \f(CWglob()\fR VMS wildcard expansion is performed. (csh-style
+wildcard expansion is available if you use \f(CW\*(C`File::Glob::glob\*(C'\fR.)
+If the wildcard filespec contains a device or directory
+specification, then the resultant filespecs will also contain
+a device and directory; otherwise, device and directory
+information are removed. VMS-style resultant filespecs will
+contain a full device and directory, while Unix-style
+resultant filespecs will contain only as much of a directory
+path as was present in the input filespec. For example, if
+your default directory is Perl_Root:[000000], the expansion
+of \f(CW\*(C`[.t]*.*\*(C'\fR will yield filespecs like
+"perl_root:[t]base.dir", while the expansion of \f(CW\*(C`t/*/*\*(C'\fR will
+yield filespecs like "t/base.dir". (This is done to match
+the behavior of glob expansion performed by Unix shells.)
+.PP
+Similarly, the resultant filespec will contain the file version
+only if one was present in the input filespec.
+.SS Pipes
+.IX Subsection "Pipes"
+Input and output pipes to Perl filehandles are supported; the
+"file name" is passed to lib$\fBspawn()\fR 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.
+.PP
+You may also use backticks to invoke a DCL subprocess, whose
+output is used as the return value of the expression. The
+string between the backticks is handled as if it were the
+argument to the \f(CW\*(C`system\*(C'\fR operator (see below). In this case,
+Perl will wait for the subprocess to complete before continuing.
+.PP
+The mailbox (MBX) that perl can create to communicate with a pipe
+defaults to a buffer size of 8192 on 64\-bit systems, 512 on VAX. The
+default buffer size is adjustable via the logical name PERL_MBX_SIZE
+provided that the value falls between 128 and the SYSGEN parameter
+MAXBUF inclusive. For example, to set the mailbox size to 32767 use
+\&\f(CW\*(C`$ENV{\*(AqPERL_MBX_SIZE\*(Aq} = 32767;\*(C'\fR and then open and use pipe constructs.
+An alternative would be to issue the command:
+.PP
+.Vb 1
+\& $ Define PERL_MBX_SIZE 32767
+.Ve
+.PP
+before running your wide record pipe program. A larger value may
+improve performance at the expense of the BYTLM UAF quota.
+.SH "PERL5LIB and PERLLIB"
+.IX Header "PERL5LIB and PERLLIB"
+The PERL5LIB and PERLLIB environment elements work as documented in perl,
+except that the element separator is, by default, '|' instead of ':'.
+However, when running under a Unix shell as determined by the logical
+name \f(CW\*(C`GNV$UNIX_SHELL\*(C'\fR, the separator will be ':' as on Unix systems. The
+directory specifications may use either VMS or Unix syntax.
+.SH "The Perl Forked Debugger"
+.IX Header "The Perl Forked Debugger"
+The Perl forked debugger places the debugger commands and output in a
+separate X\-11 terminal window so that commands and output from multiple
+processes are not mixed together.
+.PP
+Perl on VMS supports an emulation of the forked debugger when Perl is
+run on a VMS system that has X11 support installed.
+.PP
+To use the forked debugger, you need to have the default display set to an
+X\-11 Server and some environment variables set that Unix expects.
+.PP
+The forked debugger requires the environment variable \f(CW\*(C`TERM\*(C'\fR to be \f(CW\*(C`xterm\*(C'\fR,
+and the environment variable \f(CW\*(C`DISPLAY\*(C'\fR to exist. \f(CW\*(C`xterm\*(C'\fR must be in
+lower case.
+.PP
+.Vb 1
+\& $define TERM "xterm"
+\&
+\& $define DISPLAY "hostname:0.0"
+.Ve
+.PP
+Currently the value of \f(CW\*(C`DISPLAY\*(C'\fR is ignored. It is recommended that it be set
+to be the hostname of the display, the server and screen in Unix notation. In
+the future the value of DISPLAY may be honored by Perl instead of using the
+default display.
+.PP
+It may be helpful to always use the forked debugger so that script I/O is
+separated from debugger I/O. You can force the debugger to be forked by
+assigning a value to the logical name <PERLDB_PIDS> that is not a process
+identification number.
+.PP
+.Vb 1
+\& $define PERLDB_PIDS XXXX
+.Ve
+.SH PERL_VMS_EXCEPTION_DEBUG
+.IX Header "PERL_VMS_EXCEPTION_DEBUG"
+The PERL_VMS_EXCEPTION_DEBUG being defined as "ENABLE" will cause the VMS
+debugger to be invoked if a fatal exception that is not otherwise
+handled is raised. The purpose of this is to allow debugging of
+internal Perl problems that would cause such a condition.
+.PP
+This allows the programmer to look at the execution stack and variables to
+find out the cause of the exception. As the debugger is being invoked as
+the Perl interpreter is about to do a fatal exit, continuing the execution
+in debug mode is usually not practical.
+.PP
+Starting Perl in the VMS debugger may change the program execution
+profile in a way that such problems are not reproduced.
+.PP
+The \f(CW\*(C`kill\*(C'\fR function can be used to test this functionality from within
+a program.
+.PP
+In typical VMS style, only the first letter of the value of this logical
+name is actually checked in a case insensitive mode, and it is considered
+enabled if it is the value "T","1" or "E".
+.PP
+This logical name must be defined before Perl is started.
+.SH "Command line"
+.IX Header "Command line"
+.SS "I/O redirection and backgrounding"
+.IX Subsection "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:
+.IP \(bu 4
+\&\f(CW\*(C`<file\*(C'\fR reads stdin from \f(CW\*(C`file\*(C'\fR,
+.IP \(bu 4
+\&\f(CW\*(C`>file\*(C'\fR writes stdout to \f(CW\*(C`file\*(C'\fR,
+.IP \(bu 4
+\&\f(CW\*(C`>>file\*(C'\fR appends stdout to \f(CW\*(C`file\*(C'\fR,
+.IP \(bu 4
+\&\f(CW\*(C`2>file\*(C'\fR writes stderr to \f(CW\*(C`file\*(C'\fR,
+.IP \(bu 4
+\&\f(CW\*(C`2>>file\*(C'\fR appends stderr to \f(CW\*(C`file\*(C'\fR, and
+.IP \(bu 4
+\&\f(CW\*(C`2>&1\*(C'\fR redirects stderr to stdout.
+.PP
+In addition, output may be piped to a subprocess, using the
+character '|'. Anything after this character on the command
+line is passed to a subprocess for execution; the subprocess
+takes the output of Perl as its input.
+.PP
+Finally, if the command line ends with '&', the entire
+command is run in the background as an asynchronous
+subprocess.
+.SS "Command line switches"
+.IX Subsection "Command line switches"
+The following command line switches behave differently under
+VMS than described in perlrun. Note also that in order
+to pass uppercase switches to Perl, you need to enclose
+them in double-quotes on the command line, since the CRTL
+downcases all unquoted strings.
+.PP
+On newer 64 bit versions of OpenVMS, a process setting now
+controls if the quoting is needed to preserve the case of
+command line arguments.
+.IP \-i 4
+.IX Item "-i"
+If the \f(CW\*(C`\-i\*(C'\fR switch is present but no extension for a backup
+copy is given, then inplace editing creates a new version of
+a file; the existing copy is not deleted. (Note that if
+an extension is given, an existing file is renamed to the backup
+file, as is the case under other operating systems, so it does
+not remain as a previous version under the original filename.)
+.IP \-S 4
+.IX Item "-S"
+If the \f(CW"\-S"\fR or \f(CW\*(C`\-"S"\*(C'\fR switch is present \fIand\fR the script
+name does not contain a directory, then Perl translates the
+logical name DCL$PATH as a searchlist, using each translation
+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 specified, with a blank type,
+a type of \fI.pl\fR, and a type of \fI.com\fR, in that order.
+.IP \-u 4
+.IX Item "-u"
+The \f(CW\*(C`\-u\*(C'\fR 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.
+.SH "Perl functions"
+.IX Header "Perl functions"
+As of the time this document was last revised, the following
+Perl functions were implemented in the VMS port of Perl
+(functions marked with * are discussed in more detail below):
+.PP
+.Vb 10
+\& file tests*, abs, alarm, atan, backticks*, binmode*, bless,
+\& caller, chdir, chmod, chown, chomp, chop, chr,
+\& close, closedir, cos, crypt*, defined, delete, die, do, dump*,
+\& each, endgrent, endpwent, eof, eval, exec*, exists, exit, exp,
+\& fileno, flock getc, getgrent*, getgrgid*, getgrnam, getlogin,
+\& getppid, getpwent*, getpwnam*, getpwuid*, glob, gmtime*, goto,
+\& grep, hex, ioctl, import, index, int, join, keys, kill*,
+\& last, lc, lcfirst, lchown*, length, link*, local, localtime, log,
+\& lstat, 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, readlink*, redo, ref,
+\& rename, require, reset, return, reverse, rewinddir, rindex,
+\& rmdir, s///, scalar, seek, seekdir, select(internal),
+\& select (system call)*, setgrent, setpwent, shift, sin, sleep,
+\& socketpair, sort, splice, split, sprintf, sqrt, srand, stat,
+\& study, substr, symlink*, 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///
+.Ve
+.PP
+The following functions were not implemented in the VMS port,
+and calling them produces a fatal error (usually) or
+undefined behavior (rarely, we hope):
+.PP
+.Vb 4
+\& chroot, dbmclose, dbmopen, fork*, getpgrp, getpriority,
+\& msgctl, msgget, msgsend, msgrcv, semctl,
+\& semget, semop, setpgrp, setpriority, shmctl, shmget,
+\& shmread, shmwrite, syscall
+.Ve
+.PP
+The following functions are available on Perls compiled with Dec C
+5.2 or greater and running VMS 7.0 or greater:
+.PP
+.Vb 1
+\& truncate
+.Ve
+.PP
+The following functions are available on Perls built on VMS 7.2 or
+greater:
+.PP
+.Vb 1
+\& fcntl (without locking)
+.Ve
+.PP
+The following functions may or may not be implemented,
+depending on what type of socket support you've built into
+your copy of Perl:
+.PP
+.Vb 9
+\& 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
+.Ve
+.PP
+The following function is available on Perls built on 64 bit OpenVMS v8.2
+with hard links enabled on an ODS\-5 formatted build disk. CRTL support
+is in principle available as of OpenVMS v7.3\-1, and better configuration
+support could detect this.
+.PP
+.Vb 1
+\& link
+.Ve
+.PP
+The following functions are available on Perls built on 64 bit OpenVMS
+v8.2 and later. CRTL support is in principle available as of OpenVMS
+v7.3\-2, and better configuration support could detect this.
+.PP
+.Vb 2
+\& getgrgid, getgrnam, getpwnam, getpwuid,
+\& setgrent, ttyname
+.Ve
+.PP
+The following functions are available on Perls built on 64 bit OpenVMS v8.2
+and later.
+.PP
+.Vb 1
+\& statvfs, socketpair
+.Ve
+.IP "File tests" 4
+.IX Item "File tests"
+The tests \f(CW\*(C`\-b\*(C'\fR, \f(CW\*(C`\-B\*(C'\fR, \f(CW\*(C`\-c\*(C'\fR, \f(CW\*(C`\-C\*(C'\fR, \f(CW\*(C`\-d\*(C'\fR, \f(CW\*(C`\-e\*(C'\fR, \f(CW\*(C`\-f\*(C'\fR,
+\&\f(CW\*(C`\-o\*(C'\fR, \f(CW\*(C`\-M\*(C'\fR, \f(CW\*(C`\-s\*(C'\fR, \f(CW\*(C`\-S\*(C'\fR, \f(CW\*(C`\-t\*(C'\fR, \f(CW\*(C`\-T\*(C'\fR, and \f(CW\*(C`\-z\*(C'\fR work as
+advertised. The return values for \f(CW\*(C`\-r\*(C'\fR, \f(CW\*(C`\-w\*(C'\fR, and \f(CW\*(C`\-x\*(C'\fR
+tell you whether you can actually access the file; this may
+not reflect the UIC-based file protections. Since real and
+effective UIC don't differ under VMS, \f(CW\*(C`\-O\*(C'\fR, \f(CW\*(C`\-R\*(C'\fR, \f(CW\*(C`\-W\*(C'\fR,
+and \f(CW\*(C`\-X\*(C'\fR are equivalent to \f(CW\*(C`\-o\*(C'\fR, \f(CW\*(C`\-r\*(C'\fR, \f(CW\*(C`\-w\*(C'\fR, and \f(CW\*(C`\-x\*(C'\fR.
+Similarly, several other tests, including \f(CW\*(C`\-A\*(C'\fR, \f(CW\*(C`\-g\*(C'\fR, \f(CW\*(C`\-k\*(C'\fR,
+\&\f(CW\*(C`\-l\*(C'\fR, \f(CW\*(C`\-p\*(C'\fR, and \f(CW\*(C`\-u\*(C'\fR, aren't particularly meaningful under
+VMS, and the values returned by these tests reflect whatever
+your CRTL \f(CWstat()\fR routine does to the equivalent bits in the
+st_mode field. Finally, \f(CW\*(C`\-d\*(C'\fR returns true if passed a device
+specification without an explicit directory (e.g. \f(CW\*(C`DUA1:\*(C'\fR), as
+well as if passed a directory.
+.Sp
+There are DECC feature logical names AND ODS\-5 volume attributes that
+also control what values are returned for the date fields.
+.Sp
+Note: Some sites have reported problems when using the file-access
+tests (\f(CW\*(C`\-r\*(C'\fR, \f(CW\*(C`\-w\*(C'\fR, and \f(CW\*(C`\-x\*(C'\fR) 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 \f(CW$!\fR indicating that the file does not exist. You can
+use \f(CW\*(C`stat\*(C'\fR on these files, since that checks UIC-based protection
+only, and then manually check the appropriate bits, as defined by
+your C compiler's \fIstat.h\fR, in the mode value it returns, if you
+need an approximation of the file's protections.
+.IP backticks 4
+.IX Item "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 \f(CW\*(C`lib$spawn()\*(C'\fR, any valid DCL command string
+may be specified.
+.IP "binmode FILEHANDLE" 4
+.IX Item "binmode FILEHANDLE"
+The \f(CW\*(C`binmode\*(C'\fR 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 position 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 \f(CW\*(C`binmode\*(C'\fR
+was called.
+.Sp
+Note that \f(CW\*(C`binmode\*(C'\fR 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
+\&\f(CW\*(C`vmsfopen\*(C'\fR function in the VMS::Stdio extension to gain finer
+control of I/O to files and devices with different record structures.
+.IP "crypt PLAINTEXT, USER" 4
+.IX Item "crypt PLAINTEXT, USER"
+The \f(CW\*(C`crypt\*(C'\fR operator uses the \f(CW\*(C`sys$hash_password\*(C'\fR system
+service to generate the hashed representation of PLAINTEXT.
+If USER is a valid username, the algorithm 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.
+.Sp
+The value returned by \f(CW\*(C`crypt\*(C'\fR may be compared against
+the encrypted password from the UAF returned by the \f(CW\*(C`getpw*\*(C'\fR
+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
+\&\f(CW\*(C`crypt\*(C'\fR to insure that you'll get the proper value:
+.Sp
+.Vb 9
+\& sub validate_passwd {
+\& my($user,$passwd) = @_;
+\& my($pwdhash);
+\& if ( !($pwdhash = (getpwnam($user))[1]) ||
+\& $pwdhash ne crypt("\eU$passwd","\eU$name") ) {
+\& intruder_alert($name);
+\& }
+\& return 1;
+\& }
+.Ve
+.IP die 4
+.IX Item "die"
+\&\f(CW\*(C`die\*(C'\fR will force the native VMS exit status to be an SS$_ABORT code
+if neither of the $! or $? status values are ones that would cause
+the native status to be interpreted as being what VMS classifies as
+SEVERE_ERROR severity for DCL error handling.
+.Sp
+When \f(CW\*(C`PERL_VMS_POSIX_EXIT\*(C'\fR is active (see "$?" below), the native VMS exit
+status value will have either one of the \f(CW$!\fR or \f(CW$?\fR or \f(CW$^E\fR or
+the Unix value 255 encoded into it in a way that the effective original
+value can be decoded by other programs written in C, including Perl
+and the GNV package. As per the normal non-VMS behavior of \f(CW\*(C`die\*(C'\fR if
+either \f(CW$!\fR or \f(CW$?\fR are non-zero, one of those values will be
+encoded into a native VMS status value. If both of the Unix status
+values are 0, and the \f(CW$^E\fR value is set one of ERROR or SEVERE_ERROR
+severity, then the \f(CW$^E\fR value will be used as the exit code as is.
+If none of the above apply, the Unix value of 255 will be encoded into
+a native VMS exit status value.
+.Sp
+Please note a significant difference in the behavior of \f(CW\*(C`die\*(C'\fR in
+the \f(CW\*(C`PERL_VMS_POSIX_EXIT\*(C'\fR mode is that it does not force a VMS
+SEVERE_ERROR status on exit. The Unix exit values of 2 through
+255 will be encoded in VMS status values with severity levels of
+SUCCESS. The Unix exit value of 1 will be encoded in a VMS status
+value with a severity level of ERROR. This is to be compatible with
+how the VMS C library encodes these values.
+.Sp
+The minimum severity level set by \f(CW\*(C`die\*(C'\fR in \f(CW\*(C`PERL_VMS_POSIX_EXIT\*(C'\fR mode
+may be changed to be ERROR or higher in the future depending on the
+results of testing and further review.
+.Sp
+See "$?" for a description of the encoding of the Unix value to
+produce a native VMS status containing it.
+.IP dump 4
+.IX Item "dump"
+Rather than causing Perl to abort and dump core, the \f(CW\*(C`dump\*(C'\fR
+operator invokes the VMS debugger. If you continue to
+execute the Perl program under the debugger, control will
+be transferred to the label specified as the argument to
+\&\f(CW\*(C`dump\*(C'\fR, or, if no label was specified, back to the
+beginning of the program. All other state of the program
+(\fIe.g.\fR values of variables, open file handles) are not
+affected by calling \f(CW\*(C`dump\*(C'\fR.
+.IP "exec LIST" 4
+.IX Item "exec LIST"
+A call to \f(CW\*(C`exec\*(C'\fR will cause Perl to exit, and to invoke the command
+given as an argument to \f(CW\*(C`exec\*(C'\fR via \f(CW\*(C`lib$do_command\*(C'\fR. If the
+argument begins with '@' or '$' (other than as part of a filespec),
+then it is executed as a DCL command. Otherwise, the first token on
+the command line is treated as the filespec of an image to run, and
+an attempt is made to invoke it (using \fI.Exe\fR and the process
+defaults to expand the filespec) and pass the rest of \f(CW\*(C`exec\*(C'\fR'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 \f(CW\*(C`MCR\*(C'\fR or a text file which should be passed to DCL as a
+command procedure.
+.IP fork 4
+.IX Item "fork"
+While in principle the \f(CW\*(C`fork\*(C'\fR operator could be implemented via
+(and with the same rather severe limitations as) the CRTL \f(CWvfork()\fR
+routine, and while some internal support to do just that is in
+place, the implementation has never been completed, making \f(CW\*(C`fork\*(C'\fR
+currently unavailable. A true kernel \f(CWfork()\fR is expected in a
+future version of VMS, and the pseudo-fork based on interpreter
+threads may be available in a future version of Perl on VMS (see
+perlfork). In the meantime, use \f(CW\*(C`system\*(C'\fR, backticks, or piped
+filehandles to create subprocesses.
+.IP getpwent 4
+.IX Item "getpwent"
+.PD 0
+.IP getpwnam 4
+.IX Item "getpwnam"
+.IP getpwuid 4
+.IX Item "getpwuid"
+.PD
+These operators obtain the information described in perlfunc,
+if you have the privileges necessary to retrieve the named user's
+UAF information via \f(CW\*(C`sys$getuai\*(C'\fR. If not, then only the \f(CW$name\fR,
+\&\f(CW$uid\fR, and \f(CW$gid\fR items are returned. The \f(CW$dir\fR item contains
+the login directory in VMS syntax, while the \f(CW$comment\fR item
+contains the login directory in Unix syntax. The \f(CW$gcos\fR item
+contains the owner field from the UAF record. The \f(CW$quota\fR
+item is not used.
+.IP gmtime 4
+.IX Item "gmtime"
+The \f(CW\*(C`gmtime\*(C'\fR operator will function properly if you have a
+working CRTL \f(CWgmtime()\fR routine, or if the logical 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 automatically if you are running a version of
+VMS with built-in UTC support.) If neither of these cases is
+true, a warning message is printed, and \f(CW\*(C`undef\*(C'\fR is returned.
+.IP kill 4
+.IX Item "kill"
+In most cases, \f(CW\*(C`kill\*(C'\fR is implemented via the undocumented system
+service \f(CW$SIGPRC\fR, which has the same calling sequence as \f(CW$FORCEX\fR, but
+throws an exception in the target process rather than forcing it to call
+\&\f(CW$EXIT\fR. Generally speaking, \f(CW\*(C`kill\*(C'\fR follows the behavior of the
+CRTL's \f(CWkill()\fR function, but unlike that function can be called from
+within a signal handler. Also, unlike the \f(CW\*(C`kill\*(C'\fR in some versions of
+the CRTL, Perl's \f(CW\*(C`kill\*(C'\fR checks the validity of the signal passed in and
+returns an error rather than attempting to send an unrecognized signal.
+.Sp
+Also, negative signal values don't do anything special under
+VMS; they're just converted to the corresponding positive value.
+.IP qx// 4
+.IX Item "qx//"
+See the entry on \f(CW\*(C`backticks\*(C'\fR above.
+.IP "select (system call)" 4
+.IX Item "select (system call)"
+If Perl was not built with socket support, the system call
+version of \f(CW\*(C`select\*(C'\fR is not available at all. If socket
+support is present, then the system call version of
+\&\f(CW\*(C`select\*(C'\fR functions only for file descriptors attached
+to sockets. It will not provide information about regular
+files or pipes, since the CRTL \f(CWselect()\fR routine does not
+provide this functionality.
+.IP "stat EXPR" 4
+.IX Item "stat EXPR"
+Since VMS keeps track of files according to a different scheme
+than Unix, it's not really possible to represent the file's ID
+in the \f(CW\*(C`st_dev\*(C'\fR and \f(CW\*(C`st_ino\*(C'\fR fields of a \f(CW\*(C`struct stat\*(C'\fR. Perl
+tries its best, though, and the values it uses are pretty unlikely
+to be the same for two different files. We can't guarantee this,
+though, so caveat scriptor.
+.IP "system LIST" 4
+.IX Item "system LIST"
+The \f(CW\*(C`system\*(C'\fR operator creates a subprocess, and passes its
+arguments to the subprocess for execution as a DCL command.
+Since the subprocess is created directly via \f(CW\*(C`lib$spawn()\*(C'\fR, 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. \f(CW\*(C`:\*(C'\fR or \f(CW\*(C`]\*(C'\fR), an attempt is made to expand it
+using a default type of \fI.Exe\fR and the process defaults, and if
+successful, the resulting file is invoked via \f(CW\*(C`MCR\*(C'\fR. This allows you
+to invoke an image directly simply by passing the file specification
+to \f(CW\*(C`system\*(C'\fR, 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 \f(CW\*(C`MCR\*(C'\fR or a text file which should be passed to DCL
+as a command procedure.
+.Sp
+If LIST consists of the empty string, \f(CW\*(C`system\*(C'\fR spawns an
+interactive DCL subprocess, in the same fashion as typing
+\&\fBSPAWN\fR at the DCL prompt.
+.Sp
+Perl waits for the subprocess to complete before continuing
+execution in the current process. As described in perlfunc,
+the return value of \f(CW\*(C`system\*(C'\fR is a fake "status" which follows
+POSIX semantics unless the pragma \f(CW\*(C`use vmsish \*(Aqstatus\*(Aq\*(C'\fR is in
+effect; see the description of \f(CW$?\fR in this document for more
+detail.
+.IP time 4
+.IX Item "time"
+The value returned by \f(CW\*(C`time\*(C'\fR is the offset in seconds from
+01\-JAN\-1970 00:00:00 (just like the CRTL's \fBtimes()\fR routine), in order
+to make life easier for code coming in from the POSIX/Unix world.
+.IP times 4
+.IX Item "times"
+The array returned by the \f(CW\*(C`times\*(C'\fR operator is divided up
+according to the same rules the CRTL \f(CWtimes()\fR routine.
+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 a subprocess may or may
+not appear separately in the "child time" field, depending on
+whether \f(CWtimes()\fR keeps track of subprocesses separately. Note
+especially that the VAXCRTL (at least) keeps track only of
+subprocesses spawned using \f(CWfork()\fR and \f(CWexec()\fR; it will not
+accumulate the times of subprocesses spawned via pipes, \f(CWsystem()\fR,
+or backticks.
+.IP "unlink LIST" 4
+.IX Item "unlink LIST"
+\&\f(CW\*(C`unlink\*(C'\fR will delete the highest version of a file only; in
+order to delete all versions, you need to say
+.Sp
+.Vb 1
+\& 1 while unlink LIST;
+.Ve
+.Sp
+You may need to make this change to scripts written for a
+Unix system which expect that after a call to \f(CW\*(C`unlink\*(C'\fR,
+no files with the names passed to \f(CW\*(C`unlink\*(C'\fR will exist.
+(Note: This can be changed at compile time; if you
+\&\f(CW\*(C`use Config\*(C'\fR and \f(CW$Config{\*(Aqd_unlink_all_versions\*(Aq}\fR is
+\&\f(CW\*(C`define\*(C'\fR, then \f(CW\*(C`unlink\*(C'\fR will delete all versions of a
+file on the first call.)
+.Sp
+\&\f(CW\*(C`unlink\*(C'\fR will delete a file if at all possible, even 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
+\&\f(CW\*(C`VMS::Filespec::candelete\*(C'\fR operator. For instance, in order
+to delete only files to which you have delete access, you could
+say something like
+.Sp
+.Vb 8
+\& sub safe_unlink {
+\& my($file,$num);
+\& foreach $file (@_) {
+\& next unless VMS::Filespec::candelete($file);
+\& $num += unlink $file;
+\& }
+\& $num;
+\& }
+.Ve
+.Sp
+(or you could just use \f(CW\*(C`VMS::Stdio::remove\*(C'\fR, if you've installed
+the VMS::Stdio extension distributed with Perl). If \f(CW\*(C`unlink\*(C'\fR 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.
+.Sp
+This behavior of \f(CW\*(C`unlink\*(C'\fR is to be compatible with POSIX behavior
+and not traditional VMS behavior.
+.IP "utime LIST" 4
+.IX Item "utime LIST"
+This operator changes only the modification time of the file (VMS
+revision date) on ODS\-2 volumes and ODS\-5 volumes without access
+dates enabled. On ODS\-5 volumes with access dates enabled, the
+true access time is modified.
+.IP "waitpid PID,FLAGS" 4
+.IX Item "waitpid PID,FLAGS"
+If PID is a subprocess started by a piped \f(CWopen()\fR (see open),
+\&\f(CW\*(C`waitpid\*(C'\fR will wait for that subprocess, and return its final status
+value in \f(CW$?\fR. If PID is a subprocess created in some other way (e.g.
+SPAWNed before Perl was invoked), \f(CW\*(C`waitpid\*(C'\fR will simply check once per
+second whether the process has completed, and return when it has. (If
+PID specifies a process that isn't a subprocess of the current process,
+and you invoked Perl with the \f(CW\*(C`\-w\*(C'\fR switch, a warning will be issued.)
+.Sp
+Returns PID on success, \-1 on error. The FLAGS argument is ignored
+in all cases.
+.SH "Perl variables"
+.IX Header "Perl variables"
+The following VMS-specific information applies to the indicated
+"special" Perl variables, in addition to the general information
+in perlvar. Where there is a conflict, this information
+takes precedence.
+.ie n .IP %ENV 4
+.el .IP \f(CW%ENV\fR 4
+.IX Item "%ENV"
+The operation of the \f(CW%ENV\fR array depends on the translation
+of the logical name \fIPERL_ENV_TABLES\fR. If defined, it should
+be a search list, each element of which specifies a location
+for \f(CW%ENV\fR elements. If you tell Perl to read or set the
+element \f(CW\*(C`$ENV{\*(C'\fR\fIname\fR\f(CW\*(C`}\*(C'\fR, then Perl uses the translations of
+\&\fIPERL_ENV_TABLES\fR as follows:
+.RS 4
+.IP CRTL_ENV 4
+.IX Item "CRTL_ENV"
+This string tells Perl to consult the CRTL's internal \f(CW\*(C`environ\*(C'\fR array
+of key-value pairs, using \fIname\fR as the key. In most cases, this
+contains only a few keys, but if Perl was invoked via the C
+\&\f(CW\*(C`exec[lv]e()\*(C'\fR function, as is the case for some embedded Perl
+applications or when running under a shell such as GNV bash, the
+\&\f(CW\*(C`environ\*(C'\fR array may have been populated by the calling program.
+.IP CLISYM_[LOCAL] 4
+.IX Item "CLISYM_[LOCAL]"
+A string beginning with \f(CW\*(C`CLISYM_\*(C'\fRtells Perl to consult the CLI's
+symbol tables, using \fIname\fR as the name of the symbol. When reading
+an element of \f(CW%ENV\fR, the local symbol table is scanned first, followed
+by the global symbol table.. The characters following \f(CW\*(C`CLISYM_\*(C'\fR are
+significant when an element of \f(CW%ENV\fR is set or deleted: if the
+complete string is \f(CW\*(C`CLISYM_LOCAL\*(C'\fR, the change is made in the local
+symbol table; otherwise the global symbol table is changed.
+.IP "Any other string" 4
+.IX Item "Any other string"
+If an element of \fIPERL_ENV_TABLES\fR translates to any other string,
+that string is used as the name of a logical name table, which is
+consulted using \fIname\fR as the logical name. The normal search
+order of access modes is used.
+.RE
+.RS 4
+.Sp
+\&\fIPERL_ENV_TABLES\fR is translated once when Perl starts up; any changes
+you make while Perl is running do not affect the behavior of \f(CW%ENV\fR.
+If \fIPERL_ENV_TABLES\fR is not defined, then Perl defaults to consulting
+first the logical name tables specified by \fILNM$FILE_DEV\fR, and then
+the CRTL \f(CW\*(C`environ\*(C'\fR array. This default order is reversed when the
+logical name \fIGNV$UNIX_SHELL\fR is defined, such as when running under
+GNV bash.
+.Sp
+For operations on \f(CW%ENV\fR entries based on logical names or DCL symbols, the
+key string is treated as if it were entirely uppercase, regardless of the
+case actually specified in the Perl expression. Entries in \f(CW%ENV\fR based on the
+CRTL's environ array preserve the case of the key string when stored, and
+lookups are case sensitive.
+.Sp
+When an element of \f(CW%ENV\fR is read, the locations to which
+\&\fIPERL_ENV_TABLES\fR points are checked in order, and the value
+obtained from the first successful lookup is returned. If the
+name of the \f(CW%ENV\fR element contains a semi-colon, it and
+any characters after it are removed. These are ignored when
+the CRTL \f(CW\*(C`environ\*(C'\fR array or a CLI symbol table is consulted.
+However, the name is looked up in a logical name table, the
+suffix after the semi-colon is treated as the translation index
+to be used for the lookup. This lets you look up successive values
+for search list logical names. For instance, if you say
+.Sp
+.Vb 3
+\& $ Define STORY once,upon,a,time,there,was
+\& $ perl \-e "for ($i = 0; $i <= 6; $i++) " \-
+\& _$ \-e "{ print $ENV{\*(Aqstory;\*(Aq.$i},\*(Aq \*(Aq}"
+.Ve
+.Sp
+Perl will print \f(CW\*(C`ONCE UPON A TIME THERE WAS\*(C'\fR, assuming, of course,
+that \fIPERL_ENV_TABLES\fR is set up so that the logical name \f(CW\*(C`story\*(C'\fR
+is found, rather than a CLI symbol or CRTL \f(CW\*(C`environ\*(C'\fR element with
+the same name.
+.Sp
+When an element of \f(CW%ENV\fR is set to a defined string, the
+corresponding definition is made in the location to which the
+first translation of \fIPERL_ENV_TABLES\fR 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 \f(CW\*(C`NUL\*(C'\fR
+(ASCII \f(CW\*(C`\e0\*(C'\fR) character, since a logical name cannot translate to a
+zero-length string. (This restriction does not apply to CLI symbols
+or CRTL \f(CW\*(C`environ\*(C'\fR values; they are set to the empty string.)
+.Sp
+When an element of \f(CW%ENV\fR is set to \f(CW\*(C`undef\*(C'\fR, the element is looked
+up as if it were being read, and if it is found, it is deleted. (An
+item "deleted" from the CRTL \f(CW\*(C`environ\*(C'\fR array is set to the empty
+string.) Using \f(CW\*(C`delete\*(C'\fR to remove an element from \f(CW%ENV\fR 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 \f(CW%ENV\fR.
+.Sp
+The element \f(CW$ENV{DEFAULT}\fR is special: when read, it returns
+Perl's current default device and directory, and when set, it
+resets them, regardless of the definition of \fIPERL_ENV_TABLES\fR.
+It cannot be cleared or deleted; attempts to do so are silently
+ignored.
+.Sp
+Note that if you want to pass on any elements of the
+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 subprocesses,
+by saying
+.Sp
+.Vb 4
+\& 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
+\& }
+.Ve
+.Sp
+(You can't just say \f(CW\*(C`$ENV{$key} = $ENV{$key}\*(C'\fR, since the
+Perl optimizer is smart enough to elide the expression.)
+.Sp
+Don't try to clear \f(CW%ENV\fR by saying \f(CW\*(C`%ENV = ();\*(C'\fR, it will throw
+a fatal error. This is equivalent to doing the following from DCL:
+.Sp
+.Vb 1
+\& DELETE/LOGICAL *
+.Ve
+.Sp
+You can imagine how bad things would be if, for example, the SYS$MANAGER
+or SYS$SYSTEM logical names were deleted.
+.Sp
+At present, the first time you iterate over \f(CW%ENV\fR using
+\&\f(CW\*(C`keys\*(C'\fR, or \f(CW\*(C`values\*(C'\fR, you will incur a time penalty as all
+logical names are read, in order to fully populate \f(CW%ENV\fR.
+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.
+.Sp
+You do need to be careful with the logical names representing
+process-permanent files, such as \f(CW\*(C`SYS$INPUT\*(C'\fR and \f(CW\*(C`SYS$OUTPUT\*(C'\fR.
+The translations for these logical names 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 logical names, as the null
+byte acted as an end-of-string marker)
+.RE
+.IP $! 4
+The string value of \f(CW$!\fR is that returned by the CRTL's
+\&\fBstrerror()\fR function, so it will include the VMS message for
+VMS-specific errors. The numeric value of \f(CW$!\fR is the
+value of \f(CW\*(C`errno\*(C'\fR, except if errno is EVMSERR, in which
+case \f(CW$!\fR contains the value of vaxc$errno. Setting \f(CW$!\fR
+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 \f(CW$!\fR won't reflect the VMS error
+message from before \f(CW$!\fR was set.
+.IP $^E 4
+.IX Item "$^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 \f(CW$!\fR. Its numeric value
+is the value of vaxc$errno, and its string value is the
+corresponding VMS message string, as retrieved by sys$\fBgetmsg()\fR.
+Setting \f(CW$^E\fR sets vaxc$errno to the value specified.
+.Sp
+While Perl attempts to keep the vaxc$errno value to be current, if
+errno is not EVMSERR, it may not be from the current operation.
+.IP $? 4
+The "status value" returned in \f(CW$?\fR is synthesized from the
+actual exit status of the subprocess in a way that approximates
+POSIX \fBwait\fR\|(5) semantics, in order to allow Perl programs to
+portably test for successful completion of subprocesses. The
+low order 8 bits of \f(CW$?\fR are always 0 under VMS, since the
+termination status of a process may or may not have been
+generated by an exception.
+.Sp
+The next 8 bits contain the termination status of the program.
+.Sp
+If the child process follows the convention of C programs
+compiled with the _POSIX_EXIT macro set, the status value will
+contain the actual value of 0 to 255 returned by that program
+on a normal exit.
+.Sp
+With the _POSIX_EXIT macro set, the Unix exit value of zero is
+represented as a VMS native status of 1, and the Unix values
+from 2 to 255 are encoded by the equation:
+.Sp
+.Vb 1
+\& VMS_status = 0x35a000 + (unix_value * 8) + 1.
+.Ve
+.Sp
+And in the special case of Unix value 1 the encoding is:
+.Sp
+.Vb 1
+\& VMS_status = 0x35a000 + 8 + 2 + 0x10000000.
+.Ve
+.Sp
+For other termination statuses, the severity portion of the
+subprocess's exit status is used: if the severity was success or
+informational, these bits are all 0; if the severity was
+warning, they contain a value of 1; if the severity was
+error or fatal error, they contain the actual severity bits,
+which turns out to be a value of 2 for error and 4 for severe_error.
+Fatal is another term for the severe_error status.
+.Sp
+As a result, \f(CW$?\fR will always be zero if the subprocess's exit
+status indicated successful completion, and non-zero if a
+warning or error occurred or a program compliant with encoding
+_POSIX_EXIT values was run and set a status.
+.Sp
+How can you tell the difference between a non-zero status that is
+the result of a VMS native error status or an encoded Unix status?
+You can not unless you look at the ${^CHILD_ERROR_NATIVE} value.
+The ${^CHILD_ERROR_NATIVE} value returns the actual VMS status value
+and check the severity bits. If the severity bits are equal to 1,
+then if the numeric value for \f(CW$?\fR is between 2 and 255 or 0, then
+\&\f(CW$?\fR accurately reflects a value passed back from a Unix application.
+If \f(CW$?\fR is 1, and the severity bits indicate a VMS error (2), then
+\&\f(CW$?\fR is from a Unix application exit value.
+.Sp
+In practice, Perl scripts that call programs that return _POSIX_EXIT
+type status values will be expecting those values, and programs that
+call traditional VMS programs will either be expecting the previous
+behavior or just checking for a non-zero status.
+.Sp
+And success is always the value 0 in all behaviors.
+.Sp
+When the actual VMS termination status of the child is an error,
+internally the \f(CW$!\fR value will be set to the closest Unix errno
+value to that error so that Perl scripts that test for error
+messages will see the expected Unix style error message instead
+of a VMS message.
+.Sp
+Conversely, when setting \f(CW$?\fR in an END block, an attempt is made
+to convert the POSIX value into a native status intelligible to
+the operating system upon exiting Perl. What this boils down to
+is that setting \f(CW$?\fR to zero results in the generic success value
+SS$_NORMAL, and setting \f(CW$?\fR to a non-zero value results in the
+generic failure status SS$_ABORT. See also "exit" in perlport.
+.Sp
+With the \f(CW\*(C`PERL_VMS_POSIX_EXIT\*(C'\fR logical name defined as "ENABLE",
+setting \f(CW$?\fR will cause the new value to be encoded into \f(CW$^E\fR
+so that either the original parent or child exit status values
+ 0 to 255 can be automatically recovered by C programs expecting
+_POSIX_EXIT behavior. If both a parent and a child exit value are
+non-zero, then it will be assumed that this is actually a VMS native
+status value to be passed through. The special value of 0xFFFF is
+almost a NOOP as it will cause the current native VMS status in the
+C library to become the current native Perl VMS status, and is handled
+this way as it is known to not be a valid native VMS status value.
+It is recommend that only values in the range of normal Unix parent or
+child status numbers, 0 to 255 are used.
+.Sp
+The pragma \f(CW\*(C`use vmsish \*(Aqstatus\*(Aq\*(C'\fR makes \f(CW$?\fR reflect the actual
+VMS exit status instead of the default emulation of POSIX status
+described above. This pragma also disables the conversion of
+non-zero values to SS$_ABORT when setting \f(CW$?\fR in an END
+block (but zero will still be converted to SS$_NORMAL).
+.Sp
+Do not use the pragma \f(CW\*(C`use vmsish \*(Aqstatus\*(Aq\*(C'\fR with \f(CW\*(C`PERL_VMS_POSIX_EXIT\*(C'\fR
+enabled, as they are at times requesting conflicting actions and the
+consequence of ignoring this advice will be undefined to allow future
+improvements in the POSIX exit handling.
+.Sp
+In general, with \f(CW\*(C`PERL_VMS_POSIX_EXIT\*(C'\fR enabled, more detailed information
+will be available in the exit status for DCL scripts or other native VMS tools,
+and will give the expected information for Posix programs. It has not been
+made the default in order to preserve backward compatibility.
+.Sp
+N.B. Setting \f(CW\*(C`DECC$FILENAME_UNIX_REPORT\*(C'\fR implicitly enables
+\&\f(CW\*(C`PERL_VMS_POSIX_EXIT\*(C'\fR.
+.IP $| 4
+Setting \f(CW$|\fR for an I/O stream causes data to be flushed
+all the way to disk on each write (\fIi.e.\fR not just to
+the underlying RMS buffers for a file). In other words,
+it's equivalent to calling \fBfflush()\fR and \fBfsync()\fR from C.
+.SH "Standard modules with VMS-specific differences"
+.IX Header "Standard modules with VMS-specific differences"
+.SS SDBM_File
+.IX Subsection "SDBM_File"
+SDBM_File works properly on VMS. It has, however, one minor
+difference. The database directory file created has a \fI.sdbm_dir\fR
+extension rather than a \fI.dir\fR extension. \fI.dir\fR files are VMS filesystem
+directory files, and using them for other purposes could cause unacceptable
+problems.
+.SH "Revision date"
+.IX Header "Revision date"
+Please see the git repository for revision history.
+.SH AUTHOR
+.IX Header "AUTHOR"
+Charles Bailey bailey@cor.newman.upenn.edu
+Craig Berry craigberry@mac.com
+Dan Sugalski dan@sidhe.org
+John Malmberg wb8tyw@qsl.net