diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 19:43:11 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 19:43:11 +0000 |
commit | fc22b3d6507c6745911b9dfcc68f1e665ae13dbc (patch) | |
tree | ce1e3bce06471410239a6f41282e328770aa404a /upstream/fedora-40/man1/perlvms.1 | |
parent | Initial commit. (diff) | |
download | manpages-l10n-fc22b3d6507c6745911b9dfcc68f1e665ae13dbc.tar.xz manpages-l10n-fc22b3d6507c6745911b9dfcc68f1e665ae13dbc.zip |
Adding upstream version 4.22.0.upstream/4.22.0
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'upstream/fedora-40/man1/perlvms.1')
-rw-r--r-- | upstream/fedora-40/man1/perlvms.1 | 1197 |
1 files changed, 1197 insertions, 0 deletions
diff --git a/upstream/fedora-40/man1/perlvms.1 b/upstream/fedora-40/man1/perlvms.1 new file mode 100644 index 00000000..d13f7c6c --- /dev/null +++ b/upstream/fedora-40/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 2024-01-25 "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 |