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@genetics.upenn.edu.
+hesitate to drop a line to vmsperl@perl.org.
=head1 Installation
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
-L<perlapi> for more details.) The Perl code for an
+L<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
C<use> or C<require> statement, and usually defines a Perl
I<N.B.> The procedure by which extensions are built and
tested creates several levels (at least 4) under the
directory in which the extension's source files live.
-For this reason, you shouldn't nest the source directory
-too deeply in your directory structure, lest you eccedd RMS'
+For this reason if you are running a version of VMS prior
+to V7.1 you shouldn't nest the source directory
+too deeply in your directory structure lest you exceed RMS'
maximum of 8 levels of subdirectory in a filespec. (You
can use rooted logical names to get another 8 levels of
nesting, if you can't place the files near the top of
be added to the linker options file F<PGPLOT.Opt> produced
during the build process for the Perl extension.
-By default, the shareable image for an extension is placed
-F<[.lib.site_perl.auto>I<Arch>.I<Extname>F<]> directory of the
+By default, the shareable image for an extension is placed in
+the F<[.lib.site_perl.auto>I<Arch>.I<Extname>F<]> directory of the
installed Perl directory tree (where I<Arch> is F<VMS_VAX> or
F<VMS_AXP>, and I<Extname> is the name of the extension, with
each C<::> translated to C<.>). (See the MakeMaker documentation
for more details on installation options for extensions.)
However, it can be manually placed in any of several locations:
- - the F<[.Lib.Auto.>I<Arch>I<$PVers>I<Extname>F<]> subdirectory
- of one of the directories in C<@INC> (where I<PVers>
- is the version of Perl you're using, as supplied in C<$]>,
- with '.' converted to '_'), or
- - one of the directories in C<@INC>, or
- - a directory which the extensions Perl library module
- passes to the DynaLoader when asking it to map
- the shareable image, or
- - F<Sys$Share> or F<Sys$Library>.
+
+=over 4
+
+=item *
+
+the F<[.Lib.Auto.>I<Arch>I<$PVers>I<Extname>F<]> subdirectory
+of one of the directories in C<@INC> (where I<PVers>
+is the version of Perl you're using, as supplied in C<$]>,
+with '.' converted to '_'), or
+
+=item *
+
+one of the directories in C<@INC>, or
+
+=item *
+
+a directory which the extensions Perl library module
+passes to the DynaLoader when asking it to map
+the shareable image, or
+
+=item *
+
+F<Sys$Share> or F<Sys$Library>.
+
+=back
+
If the shareable image isn't in any of these places, you'll need
to define a logical name I<Extshortname>, where I<Extshortname>
is the portion of the extension's name after the last C<::>, which
=head2 Syntax
-We have tried to make Perl aware of both VMS-style and Unix-
-style file specifications wherever possible. You may use
-either style, or both, on the command line and in scripts,
-but you may not combine the two styles within a single fle
-specification. VMS Perl interprets Unix pathnames in much
-the same way as the CRTL (I<e.g.> the first component of
-an absolute path is read as the device name for the
-VMS file specification). There are a set of functions
-provided in the C<VMS::Filespec> package for explicit
-interconversion between VMS and Unix syntax; its
-documentation provides more details.
-
-Filenames are, of course, still case-insensitive. For
-consistency, most Perl routines return filespecs using
-lower case letters only, regardless of the case used in
-the arguments passed to them. (This is true only when
-running under VMS; Perl respects the case-sensitivity
-of OSs like Unix.)
-
-We've tried to minimize the dependence of Perl library
-modules on Unix syntax, but you may find that some of these,
-as well as some scripts written for Unix systems, will
-require that you use Unix syntax, since they will assume that
-'/' is the directory separator, I<etc.> If you find instances
-of this in the Perl distribution itself, please let us know,
-so we can try to work around them.
+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 (I<e.g.> the first component
+of an absolute path is read as the device name for the VMS file
+specification). There are a set of functions provided in the
+C<VMS::Filespec> package for explicit interconversion between VMS and
+Unix syntax; its documentation provides more details.
+
+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, I<etc.> If you find instances
+of this in the Perl distribution itself, please let us know,
+so we can try to work around them.
+
+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.
+
+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
+C<./.../> in a UNIX path is now translated to C<[.^.^.^.]> instead of
+the traditional VMS C<[...]>. To be compatible with what MakeMaker
+expects, if a VMS path cannot be translated to a UNIX path, it is
+passed through unchanged, so C<unixify("[...]")> will return C<[...]>.
+
+The handling of extended characters is largely complete in the
+VMS-specific C infrastructure of Perl, but more work is still needed to
+fully support extended syntax filenames in several core modules. In
+particular, at this writing PathTools has only partial support for
+directories containing some extended characters.
+
+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.
+
+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 unixify() or
+vmsify().
+
+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.
+
+=head2 Filename Case
+
+Perl follows VMS defaults and override settings in preserving (or not
+preserving) filename case. Case is not preserved on ODS-2 formatted
+volumes on any architecture. On ODS-5 volumes, filenames may be case
+preserved depending on process and feature settings. Perl now honors
+DECC$EFS_CASE_PRESERVE and DECC$ARGV_PARSE_STYLE on those systems where
+the CRTL supports these features. When these features are not enabled
+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.
+
+I<N. B.> 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 expections 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.
+
+OpenVMS Alpha v7.3-1 and later and all version of OpenVMS I64 support
+case sensitivity as a process setting (see C<SET PROCESS
+/CASE_LOOKUP=SENSITIVE>). Perl does not currently suppport case
+sensitivity on VMS, but it may in the future, so Perl programs should
+use the C<File::Spec->case_tolerant> method to determine the state, and
+not the C<$^O> variable.
+
+=head2 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 C<SHOW ROOT> 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.
=head2 Wildcard expansion
File specifications containing wildcards are allowed both on
-the command line and within Perl globs (e.g. <CE<lt>*.cE<gt>>). If
+the command line and within Perl globs (e.g. C<E<lt>*.cE<gt>>). 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 C<"> around a perl program command line argument. However,
+owing to the stripping of C<"> 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 F<PERL.C>, F<PERL.EXE>,
+F<PERL.H>, and F<PERL.OBJ>):
+
+ $ perl -e "print join(' ',@ARGV)" perl.*
+ perl.c perl.exe perl.h perl.obj
+
+in the following triple quoted manner:
+ $ perl -e "print join(' ',@ARGV)" """perl.*"""
+ perl.*
+
+In both the case of unquoted command line arguments or in calls
+to C<glob()> VMS wildcard expansion is performed. (csh-style
+wildcard expansion is available if you use C<File::Glob::glob>.)
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
Similarly, the resultant filespec will contain the file version
only if one was present in the input filespec.
+
=head2 Pipes
Input and output pipes to Perl filehandles are supported; the
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 passed directly to lib$spawn
-as the command to execute. In this case, Perl will wait for
-the subprocess to complete before continuing.
+string between the backticks is handled as if it were the
+argument to the C<system> operator (see below). In this case,
+Perl will wait for the subprocess to complete before continuing.
+
+The mailbox (MBX) that perl can create to communicate with a pipe
+defaults to a buffer size of 512. 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 double the MBX size from the default within
+a Perl program, use C<$ENV{'PERL_MBX_SIZE'} = 1024;> and then
+open and use pipe constructs. An alternative would be to issue
+the command:
+
+ $ Define PERL_MBX_SIZE 1024
+
+before running your wide record pipe program. A larger value may
+improve performance at the expense of the BYTLM UAF quota.
=head1 PERL5LIB and PERLLIB
-The PERL5LIB and PERLLIB logical names work as documented L<perl>,
+The PERL5LIB and PERLLIB logical names work as documented in L<perl>,
except that the element separator is '|' instead of ':'. The
directory specifications may use either VMS or Unix syntax.
+=head1 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.
+
+Perl on VMS supports an emulation of the forked debugger when Perl is
+run on a VMS system that has X11 support installed.
+
+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.
+
+The forked debugger requires the environment variable C<TERM> to be C<xterm>,
+and the environment variable C<DISPLAY> to exist. C<xterm> must be in
+lower case.
+
+ $define TERM "xterm"
+
+ $define DISPLAY "hostname:0.0"
+
+Currently the value of C<DISPLAY> 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.
+
+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.
+
+ $define PERLDB_PIDS XXXX
+
+
+=head1 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.
+
+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 usally not practical.
+
+Starting Perl in the VMS debugger may change the program execution
+profile in a way that such problems are not reproduced.
+
+The C<kill> function can be used to test this functionality from within
+a program.
+
+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".
+
+This logical name must be defined before Perl is started.
+
=head1 Command line
=head2 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:
- <F<file> reads stdin from F<file>,
- >F<file> writes stdout to F<file>,
- >>F<file> appends stdout to F<file>,
- 2>F<file> writes stderr to F<file>, and
- 2>>F<file> appends stderr to F<file>.
+=over 4
+
+=item *
+
+C<E<lt>file> reads stdin from C<file>,
+
+=item *
+
+C<E<gt>file> writes stdout to C<file>,
+
+=item *
+
+C<E<gt>E<gt>file> appends stdout to C<file>,
+
+=item *
+
+C<2E<gt>file> writes stderr to C<file>,
+
+=item *
+
+C<2E<gt>E<gt>file> appends stderr to C<file>, and
+
+=item *
+
+C<< 2>&1 >> redirects stderr to stdout.
+
+=back
In addition, output may be piped to a subprocess, using the
character '|'. Anything after this character on the command
them in double-quotes on the command line, since the CRTL
downcases all unquoted strings.
+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.
+
=over 4
=item -i
=item -S
-If the C<-S> switch is present I<and> 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 the C<"-S"> or C<-"S"> switch is present I<and> 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 F<.pl>, and a type of F<.com>, in that order.
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, endpwent, eof, eval, exec*,
- exists, exit, exp, fileno, fork*, getc, getlogin,
+ 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, import, index, int, join, keys, kill*,
- last, lc, lcfirst, length, local, localtime, log, m//,
+ 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, redo, ref, rename,
+ 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)*, setpwent, shift, sin, sleep,
- sort, splice, split, sprintf, sqrt, srand, stat,
- study, substr, sysread, system*, syswrite, tell,
+ 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///
and calling them produces a fatal error (usually) or
undefined behavior (rarely, we hope):
- chroot, dbmclose, dbmopen, fcntl, flock,
- getpgrp, getppid, getpriority, getgrent, getgrgid,
- getgrnam, setgrent, endgrent, ioctl, link, lstat,
- msgctl, msgget, msgsend, msgrcv, readlink, semctl,
+ chroot, dbmclose, dbmopen, fork*, getpgrp, getpriority,
+ msgctl, msgget, msgsend, msgrcv, semctl,
semget, semop, setpgrp, setpriority, shmctl, shmget,
- shmread, shmwrite, socketpair, symlink, syscall, truncate
+ shmread, shmwrite, syscall
+
+The following functions are available on Perls compiled with Dec C
+5.2 or greater and running VMS 7.0 or greater:
+
+ truncate
+
+The following functions are available on Perls built on VMS 7.2 or
+greater:
+
+ fcntl (without locking)
The following functions may or may not be implemented,
depending on what type of socket support you've built into
getsockopt, listen, recv, select(system call)*,
send, setsockopt, shutdown, socket
+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.
+
+ link
+
+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.
+
+ getgrgid, getgrnam, getpwnam, getpwuid,
+ setgrent, ttyname
+
+The following functions are available on Perls built on 64 bit OpenVMS v8.2
+and later.
+
+ statvfs, socketpair
+
=over 4
=item File tests
specification without an explicit directory (e.g. C<DUA1:>), as
well as if passed a directory.
+There are DECC feature logical names AND ODS-5 volume attributes that
+also control what values are returned for the date fields.
+
Note: Some sites have reported problems when using the file-access
tests (C<-r>, C<-w>, and C<-x>) on files accessed via DEC's DFS.
Specifically, since DFS does not currently provide access to the
password strings; you'll have to upcase the arguments to
C<crypt> to insure that you'll get the proper value:
- sub validate_passwd {
- my($user,$passwd) = @_;
- my($pwdhash);
- if ( !($pwdhash = (getpwnam($user))[1]) ||
- $pwdhash ne crypt("\U$passwd","\U$name") ) {
- intruder_alert($name);
+ sub validate_passwd {
+ my($user,$passwd) = @_;
+ my($pwdhash);
+ if ( !($pwdhash = (getpwnam($user))[1]) ||
+ $pwdhash ne crypt("\U$passwd","\U$name") ) {
+ intruder_alert($name);
+ }
+ return 1;
}
- return 1;
- }
+
+
+=item die
+
+C<die> 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.
+
+When the future POSIX_EXIT mode is active, C<die>, the native VMS exit
+status value will have either one of the C<$!> or C<$?> or C<$^E> 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 C<die> if
+either C<$!> or C<$?> 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 C<$^E> value is set one of ERROR or SEVERE_ERROR
+severity, then the C<$^E> 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.
+
+Please note a significant difference in the behavior of C<die> in
+the future POSIX_EXIT 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.
+
+The minimum severity level set by C<die> in a future POSIX_EXIT mode
+may be changed to be ERROR or higher before that mode becomes fully active
+depending on the results of testing and further review. If this is
+done, the behavior of c<DIE> in the future POSIX_EXIT will close enough
+to the default mode that most DCL shell scripts will probably not notice
+a difference.
+
+See C<$?> for a description of the encoding of the UNIX value to
+produce a native VMS status containing it.
+
=item dump
=item exec LIST
-The C<exec> operator behaves in one of two different ways.
-If called after a call to C<fork>, it will invoke the CRTL
-C<execv()> routine, passing its arguments to the subprocess
-created by C<fork> for execution. In this case, it is
-subject to all limitations that affect C<execv()>. (In
-particular, this usually means that the command executed in
-the subprocess must be an image compiled from C source code,
-and that your options for passing file descriptors and signal
-handlers to the subprocess are limited.)
-
-If the call to C<exec> does not follow a call to C<fork>, it
-will cause Perl to exit, and to invoke the command given as
-an argument to C<exec> via C<lib$do_command>. If the argument
-begins with a '$' (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 F<.Exe> and
-the process defaults to expand the filespec) and pass the
-rest of C<exec>'s argument to it as parameters.
-
-You can use C<exec> in both ways within the same script, as
-long as you call C<fork> and C<exec> in pairs. Perl
-keeps track of how many times C<fork> and C<exec> have been
-called, and will call the CRTL C<execv()> routine if there have
-previously been more calls to C<fork> than to C<exec>.
+A call to C<exec> will cause Perl to exit, and to invoke the command
+given as an argument to C<exec> via C<lib$do_command>. 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 F<.Exe> and the process
+defaults to expand the filespec) and pass the rest of C<exec>'s
+argument to it as parameters. If the token has no file type, and
+matches a file with null type, then an attempt is made to determine
+whether the file is an executable image which should be invoked
+using C<MCR> or a text file which should be passed to DCL as a
+command procedure.
=item fork
-The C<fork> operator works in the same way as the CRTL
-C<vfork()> routine, which is quite different under VMS than
-under Unix. Specifically, while C<fork> returns 0 after it
-is called and the subprocess PID after C<exec> is called, in
-both cases the thread of execution is within the parent
-process, so there is no opportunity to perform operations in
-the subprocess before calling C<exec>.
-
-In general, the use of C<fork> and C<exec> to create
-subprocess is not recommended under VMS; wherever possible,
-use the C<system> operator or piped filehandles instead.
+While in principle the C<fork> operator could be implemented via
+(and with the same rather severe limitations as) the CRTL C<vfork()>
+routine, and while some internal support to do just that is in
+place, the implementation has never been completed, making C<fork>
+currently unavailable. A true kernel C<fork()> 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
+L<perlfork>). In the meantime, use C<system>, backticks, or piped
+filehandles to create subprocesses.
=item getpwent
=item kill
-In most cases, C<kill> kill is implemented via the CRTL's C<kill()>
-function, so it will behave according to that function's
-documentation. If you send a SIGKILL, however, the $DELPRC system
-service is called directly. This insures that the target
-process is actually deleted, if at all possible. (The CRTL's C<kill()>
-function is presently implemented via $FORCEX, which is ignored by
-supervisor-mode images like DCL.)
+In most cases, C<kill> is implemented via the undocumented system
+service <$SIGPRC>, which has the same calling sequence as <$FORCEX>, but
+throws an exception in the target process rather than forcing it to call
+C<$EXIT>. Generally speaking, C<kill> follows the behavior of the
+CRTL's C<kill()> function, but unlike that function can be called from
+within a signal handler. Also, unlike the C<kill> in some versions of
+the CRTL, Perl's C<kill> checks the validity of the signal passed in and
+returns an error rather than attempting to send an unrecognized signal.
Also, negative signal values don't do anything special under
VMS; they're just converted to the corresponding positive value.
The C<system> operator creates a subprocess, and passes its
arguments to the subprocess for execution as a DCL command.
Since the subprocess is created directly via C<lib$spawn()>, any
-valid DCL command string may be specified. If LIST consists
-of the empty string, C<system> spawns an interactive DCL subprocess,
-in the same fashion as typiing B<SPAWN> at the DCL prompt.
+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. C<:> or C<]>), an attempt is made to expand it
+using a default type of F<.Exe> and the process defaults, and if
+successful, the resulting file is invoked via C<MCR>. This allows you
+to invoke an image directly simply by passing the file specification
+to C<system>, a common Unixish idiom. If the token has no file type,
+and matches a file with null type, then an attempt is made to
+determine whether the file is an executable image which should be
+invoked using C<MCR> or a text file which should be passed to DCL
+as a command procedure.
+
+If LIST consists of the empty string, C<system> spawns an
+interactive DCL subprocess, in the same fashion as typing
+B<SPAWN> at the DCL prompt.
+
Perl waits for the subprocess to complete before continuing
execution in the current process. As described in L<perlfunc>,
the return value of C<system> is a fake "status" which follows
-POSIX semantics; see the description of C<$?> in this document
-for more detail. The actual VMS exit status of the subprocess
-is available in C<$^S> (as long as you haven't used another Perl
-function that resets C<$?> and C<$^S> in the meantime).
+POSIX semantics unless the pragma C<use vmsish 'status'> is in
+effect; see the description of C<$?> in this document for more
+detail.
=item time
according to the same rules the CRTL C<times()> 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 subprocess may or may
+under VMS, and the time accumulated by a subprocess may or may
not appear separately in the "child time" field, depending on
whether L<times> keeps track of subprocesses separately. Note
especially that the VAXCRTL (at least) keeps track only of
subprocesses spawned using L<fork> and L<exec>; it will not
-accumulate the times of suprocesses spawned via pipes, L<system>,
+accumulate the times of subprocesses spawned via pipes, L<system>,
or backticks.
=item unlink LIST
C<unlink> will delete the highest version of a file only; in
order to delete all versions, you need to say
- 1 while (unlink LIST);
+
+ 1 while unlink LIST;
+
You may need to make this change to scripts written for a
Unix system which expect that after a call to C<unlink>,
no files with the names passed to C<unlink> will exist.
in midstream, the file may be left intact, but with a changed ACL
allowing you delete access.
+This behavior of C<unlink> is to be compatible with POSIX behavior
+and not traditional VMS behavior.
+
=item utime LIST
-Since ODS-2, the VMS file structure for disk files, does not keep
-track of access times, this operator changes only the modification
-time of the file (VMS revision date).
+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.
=item waitpid PID,FLAGS
-If PID is a subprocess started by a piped L<open>, C<waitpid>
-will wait for that subprocess, and return its final
-status value. If PID is a subprocess created in some other way
-(e.g. SPAWNed before Perl was invoked), or is not a subprocess of
-the current process, C<waitpid> will check once per second whether
-the process has completed, and when it has, will return 0. (If PID
-specifies a process that isn't a subprocess of the current process,
+If PID is a subprocess started by a piped C<open()> (see L<open>),
+C<waitpid> will wait for that subprocess, and return its final status
+value in C<$?>. If PID is a subprocess created in some other way (e.g.
+SPAWNed before Perl was invoked), C<waitpid> 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 C<-w> switch, a warning will be issued.)
-The FLAGS argument is ignored in all cases.
+Returns PID on success, -1 on error. The FLAGS argument is ignored
+in all cases.
=back
The following VMS-specific information applies to the indicated
"special" Perl variables, in addition to the general information
-in L<perlvar>. Where there is a conflict, this infrmation
+in L<perlvar>. Where there is a conflict, this information
takes precedence.
=over 4
=item %ENV
-Reading the elements of the %ENV array returns the
-translation of the logical name specified by the key,
-according to the normal search order of access modes and
-logical name tables. If you append a semicolon to the
-logical name, followed by an integer, that integer is
-used as the translation index for the logical name,
-so that you can look up successive values for search
-list logical names. For instance, if you say
+The operation of the C<%ENV> array depends on the translation
+of the logical name F<PERL_ENV_TABLES>. If defined, it should
+be a search list, each element of which specifies a location
+for C<%ENV> elements. If you tell Perl to read or set the
+element C<$ENV{>I<name>C<}>, then Perl uses the translations of
+F<PERL_ENV_TABLES> as follows:
+
+=over 4
+
+=item CRTL_ENV
+
+This string tells Perl to consult the CRTL's internal C<environ>
+array of key-value pairs, using I<name> as the key. In most cases,
+this contains only a few keys, but if Perl was invoked via the C
+C<exec[lv]e()> function, as is the case for CGI processing by some
+HTTP servers, then the C<environ> array may have been populated by
+the calling program.
+
+=item CLISYM_[LOCAL]
+
+A string beginning with C<CLISYM_>tells Perl to consult the CLI's
+symbol tables, using I<name> as the name of the symbol. When reading
+an element of C<%ENV>, the local symbol table is scanned first, followed
+by the global symbol table.. The characters following C<CLISYM_> are
+significant when an element of C<%ENV> is set or deleted: if the
+complete string is C<CLISYM_LOCAL>, the change is made in the local
+symbol table; otherwise the global symbol table is changed.
+
+=item Any other string
+
+If an element of F<PERL_ENV_TABLES> translates to any other string,
+that string is used as the name of a logical name table, which is
+consulted using I<name> as the logical name. The normal search
+order of access modes is used.
+
+=back
+
+F<PERL_ENV_TABLES> is translated once when Perl starts up; any changes
+you make while Perl is running do not affect the behavior of C<%ENV>.
+If F<PERL_ENV_TABLES> is not defined, then Perl defaults to consulting
+first the logical name tables specified by F<LNM$FILE_DEV>, and then
+the CRTL C<environ> array.
+
+In all operations on %ENV, the key string is treated as if it
+were entirely uppercase, regardless of the case actually
+specified in the Perl expression.
+
+When an element of C<%ENV> is read, the locations to which
+F<PERL_ENV_TABLES> points are checked in order, and the value
+obtained from the first successful lookup is returned. If the
+name of the C<%ENV> element contains a semi-colon, it and
+any characters after it are removed. These are ignored when
+the CRTL C<environ> 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
$ Define STORY once,upon,a,time,there,was
$ perl -e "for ($i = 0; $i <= 6; $i++) " -
_$ -e "{ print $ENV{'story;'.$i},' '}"
-Perl will print C<ONCE UPON A TIME THERE WAS>.
-
-The %ENV keys C<home>, C<path>,C<term>, and C<user>
-return the CRTL "environment variables" of the same
-names, if these logical names are not defined. The
-key C<default> returns the current default device
-and directory specification, regardless of whether
-there is a logical name DEFAULT defined..
-
-Setting an element of %ENV defines a supervisor-mode logical
-name in the process logical name table. C<Undef>ing or
-C<delete>ing an element of %ENV deletes the equivalent user-
-mode or supervisor-mode logical name from the process logical
-name table. If you use C<undef>, the %ENV element remains
-empty. If you use C<delete>, another attempt is made at
-logical name translation after the deletion, so an inner-mode
-logical name or a name in another logical name table will
-replace the logical name just deleted. It is not possible
-at present to define a search list logical name via %ENV.
+Perl will print C<ONCE UPON A TIME THERE WAS>, assuming, of course,
+that F<PERL_ENV_TABLES> is set up so that the logical name C<story>
+is found, rather than a CLI symbol or CRTL C<environ> element with
+the same name.
+
+When an element of C<%ENV> is set to a defined string, the
+corresponding definition is made in the location to which the
+first translation of F<PERL_ENV_TABLES> points. If this causes a
+logical name to be created, it is defined in supervisor mode.
+(The same is done if an existing logical name was defined in
+executive or kernel mode; an existing user or supervisor mode
+logical name is reset to the new value.) If the value is an empty
+string, the logical name's translation is defined as a single NUL
+(ASCII 00) character, since a logical name cannot translate to a
+zero-length string. (This restriction does not apply to CLI symbols
+or CRTL C<environ> values; they are set to the empty string.)
+An element of the CRTL C<environ> array can be set only if your
+copy of Perl knows about the CRTL's C<setenv()> function. (This is
+present only in some versions of the DECCRTL; check C<$Config{d_setenv}>
+to see whether your copy of Perl was built with a CRTL that has this
+function.)
+
+When an element of C<%ENV> is set to C<undef>,
+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 C<environ>
+array is set to the empty string; this can only be done if your
+copy of Perl knows about the CRTL C<setenv()> function.) Using
+C<delete> to remove an element from C<%ENV> has a similar effect,
+but after the element is deleted, another attempt is made to
+look up the element, so an inner-mode logical name or a name in
+another location will replace the logical name just deleted.
+In either case, only the first value found searching PERL_ENV_TABLES
+is altered. It is not possible at present to define a search list
+logical name via %ENV.
+
+The element C<$ENV{DEFAULT}> is special: when read, it returns
+Perl's current default device and directory, and when set, it
+resets them, regardless of the definition of F<PERL_ENV_TABLES>.
+It cannot be cleared or deleted; attempts to do so are silently
+ignored.
+
+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
+
+ foreach my $key (qw[C-local keys you want promoted]) {
+ my $temp = $ENV{$key}; # read from C-local array
+ $ENV{$key} = $temp; # and define as logical name
+ }
+
+(You can't just say C<$ENV{$key} = $ENV{$key}>, since the
+Perl optimizer is smart enough to elide the expression.)
+
+Don't try to clear C<%ENV> by saying C<%ENV = ();>, it will throw
+a fatal error. This is equivalent to doing the following from DCL:
+
+ DELETE/LOGICAL *
+
+You can imagine how bad things would be if, for example, the SYS$MANAGER
+or SYS$SYSTEM logical names were deleted.
At present, the first time you iterate over %ENV using
C<keys>, or C<values>, you will incur a time penalty as all
logical names are read, in order to fully populate %ENV.
Subsequent iterations will not reread logical names, so they
won't be as slow, but they also won't reflect any changes
-to logical name tables caused by other programs. The C<each>
-operator is special: it returns each element I<already> in
-%ENV, but doesn't go out and look for more. Therefore, if
-you've previously used C<keys> or C<values>, you'll see all
-the logical names visible to your process, and if not, you'll
-see only the names you've looked up so far. (This is a
-consequence of the way C<each> is implemented now, and it
-may change in the future, so it wouldn't be a good idea
-to rely on it too much.)
+to logical name tables caused by other programs.
-In all operations on %ENV, the key string is treated as if it
-were entirely uppercase, regardless of the case actually
-specified in the Perl expression.
+You do need to be careful with the logical names representing
+process-permanent files, such as C<SYS$INPUT> and C<SYS$OUTPUT>.
+The translations for these logical names are prepended with a
+two-byte binary value (0x1B 0x00) that needs to be stripped off
+if you wantto 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)
=item $!
corresponding VMS message string, as retrieved by sys$getmsg().
Setting C<$^E> sets vaxc$errno to the value specified.
+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.
+
=item $?
The "status value" returned in C<$?> is synthesized from the
portably test for successful completion of subprocesses. The
low order 8 bits of C<$?> are always 0 under VMS, since the
termination status of a process may or may not have been
-generated by an exception. The next 8 bits are derived from
-severity portion of the subprocess' exit status: if the
-severity was success or informational, these bits are all 0;
-otherwise, they contain the severity value shifted left one bit.
-As a result, C<$?> will always be zero if the subprocess' exit
-status indicated successful completion, and non-zero if a
-warning or error occurred. The actual VMS exit status may
-be found in C<$^S> (q.v.).
+generated by an exception.
+
+The next 8 bits contain the termination status of the program.
+
+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.
+
+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:
+
+ VMS_status = 0x35a000 + (unix_value * 8) + 1.
+
+And in the special case of unix value 1 the encoding is:
-=item $^S
+ VMS_status = 0x35a000 + 8 + 2 + 0x10000000.
-Under VMS, this is the 32-bit VMS status value returned by the
-last subprocess to complete. Unlink C<$?>, no manipulation
-is done to make this look like a POSIX wait(5) value, so it
-may be treated as a normal VMS status value.
+For other termination statuses, the severity portion of the
+subprocess' 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.
+
+As a result, C<$?> will always be zero if the subprocess' 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.
+
+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 C<$?> is between 2 and 255 or 0, then
+C<$?> accurately reflects a value passed back from a UNIX application.
+If C<$?> is 1, and the severity bits indicate a VMS error (2), then
+C<$?> is from a UNIX application exit value.
+
+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.
+
+And success is always the value 0 in all behaviors.
+
+When the actual VMS termination status of the child is an error,
+internally the C<$!> 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.
+
+Conversely, when setting C<$?> 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 C<$?> to zero results in the generic success value
+SS$_NORMAL, and setting C<$?> to a non-zero value results in the
+generic failure status SS$_ABORT. See also L<perlport/exit>.
+
+With the future POSIX_EXIT mode set, setting C<$?> will cause the
+new value to also be encoded into C<$^E> so that the either the
+original parent or child exit status values of 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 consequence of it known to not be a valid native VMS status value.
+It is recommend that only values in range of normal UNIX parent or
+child status numbers, 0 to 255 are used.
+
+The pragma C<use vmsish 'status'> makes C<$?> 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 C<$?> in an END
+block (but zero will still be converted to SS$_NORMAL).
+
+Do not use the pragma C<use vmsish 'status'> with the future
+POSIX_EXIT mode, 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.
=item $|
=back
+=head1 Standard modules with VMS-specific differences
+
+=head2 SDBM_File
+
+SDBM_File works properly on VMS. It has, however, one minor
+difference. The database directory file created has a F<.sdbm_dir>
+extension rather than a F<.dir> extension. F<.dir> files are VMS filesystem
+directory files, and using them for other purposes could cause unacceptable
+problems.
+
=head1 Revision date
-This document was last updated on 28-Feb-1996, for Perl 5,
-patchlevel 2.
+This document was last updated on 3-Dec-2007, for Perl 5,
+patchlevel 10.
=head1 AUTHOR
-Charles Bailey bailey@genetics.upenn.edu
-
+Charles Bailey bailey@cor.newman.upenn.edu
+Craig Berry craigberry@mac.com
+Dan Sugalski dan@sidhe.org
+John Malmberg wb8tyw@qsl.net