1189 lines
50 KiB
Plaintext
1189 lines
50 KiB
Plaintext
|
=head1 NAME
|
||
|
|
||
|
perlvms - VMS-specific documentation for Perl
|
||
|
|
||
|
=head1 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 F<[.pod]>
|
||
|
subdirectory of the Perl distribution.
|
||
|
|
||
|
We hope these notes will save you from confusion and lost
|
||
|
sleep when writing Perl scripts on VMS. If you find we've
|
||
|
missed something you think should appear here, please don't
|
||
|
hesitate to drop a line to vmsperl@perl.org.
|
||
|
|
||
|
=head1 Installation
|
||
|
|
||
|
Directions for building and installing Perl 5 can be found in
|
||
|
the file F<README.vms> in the main source directory of the
|
||
|
Perl distribution.
|
||
|
|
||
|
=head1 Organization of Perl Images
|
||
|
|
||
|
=head2 Core Images
|
||
|
|
||
|
During the build process, three Perl images are produced.
|
||
|
F<Miniperl.Exe> 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.
|
||
|
|
||
|
Most of the complete Perl resides in the shareable image F<PerlShr.Exe>,
|
||
|
which provides a core to which the Perl executable image and all Perl
|
||
|
extensions are linked. It is generally located via the logical name
|
||
|
F<PERLSHR>. While it's possible to put the image in F<SYS$SHARE> 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.
|
||
|
|
||
|
Finally, F<Perl.Exe> is an executable image containing the main
|
||
|
entry point for Perl, as well as some initialization code. It
|
||
|
should be placed in a public directory, and made world executable.
|
||
|
In order to run Perl with command line arguments, you should
|
||
|
define a foreign command to invoke this image.
|
||
|
|
||
|
=head2 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
|
||
|
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
|
||
|
package containing the extension.
|
||
|
|
||
|
The portion of the extension provided by the XS code may be
|
||
|
connected to the rest of Perl in either of two ways. In the
|
||
|
B<static> configuration, the object code for the extension is
|
||
|
linked directly into F<PerlShr.Exe>, and is initialized whenever
|
||
|
Perl is invoked. In the B<dynamic> configuration, the extension's
|
||
|
machine code is placed into a separate shareable image, which is
|
||
|
mapped by Perl's DynaLoader when the extension is C<use>d or
|
||
|
C<require>d in your script. This allows you to maintain the
|
||
|
extension as a separate entity, at the cost of keeping track of the
|
||
|
additional shareable image. Most extensions can be set up as either
|
||
|
static or dynamic.
|
||
|
|
||
|
The source code for an extension usually resides in its own
|
||
|
directory. At least three files are generally provided:
|
||
|
I<Extshortname>F<.xs> (where I<Extshortname> is the portion of
|
||
|
the extension's name following the last C<::>), containing
|
||
|
the XS code, I<Extshortname>F<.pm>, the Perl library module
|
||
|
for the extension, and F<Makefile.PL>, a Perl script which uses
|
||
|
the C<MakeMaker> library modules supplied with Perl to generate
|
||
|
a F<Descrip.MMS> file for the extension.
|
||
|
|
||
|
=head2 Installing static extensions
|
||
|
|
||
|
Since static extensions are incorporated directly into
|
||
|
F<PerlShr.Exe>, you'll have to rebuild Perl to incorporate a
|
||
|
new extension. You should edit the main F<Descrip.MMS> or F<Makefile>
|
||
|
you use to build Perl, adding the extension's name to the C<ext>
|
||
|
macro, and the extension's object file to the C<extobj> macro.
|
||
|
You'll also need to build the extension's object file, either
|
||
|
by adding dependencies to the main F<Descrip.MMS>, or using a
|
||
|
separate F<Descrip.MMS> for the extension. Then, rebuild
|
||
|
F<PerlShr.Exe> to incorporate the new code.
|
||
|
|
||
|
Finally, you'll need to copy the extension's Perl library
|
||
|
module to the F<[.>I<Extname>F<]> subdirectory under one
|
||
|
of the directories in C<@INC>, where I<Extname> is the name
|
||
|
of the extension, with all C<::> replaced by C<.> (e.g.
|
||
|
the library module for extension Foo::Bar would be copied
|
||
|
to a F<[.Foo.Bar]> subdirectory).
|
||
|
|
||
|
=head2 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 F<Descrip.MMS> file which can be used to build and
|
||
|
install the files required by the extension. The kit should be
|
||
|
unpacked into a directory tree B<not> under the main Perl source
|
||
|
directory, and the procedure for building the extension is simply
|
||
|
|
||
|
$ perl Makefile.PL ! Create Descrip.MMS
|
||
|
$ mmk ! Build necessary files
|
||
|
$ mmk test ! Run test code, if supplied
|
||
|
$ mmk install ! Install into public Perl tree
|
||
|
|
||
|
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.)
|
||
|
|
||
|
=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
|
||
|
translates to the full file specification of the shareable image.
|
||
|
|
||
|
=head1 File specifications
|
||
|
|
||
|
=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 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<[...]>.
|
||
|
|
||
|
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 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.
|
||
|
|
||
|
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 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.
|
||
|
|
||
|
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 support 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. 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
|
||
|
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 C<[.t]*.*> will yield filespecs like
|
||
|
"perl_root:[t]base.dir", while the expansion of C<t/*/*> will
|
||
|
yield filespecs like "t/base.dir". (This is done to match
|
||
|
the behavior of glob expansion performed by Unix shells.)
|
||
|
|
||
|
Similarly, the resultant filespec will contain the file version
|
||
|
only if one was present in the input filespec.
|
||
|
|
||
|
|
||
|
=head2 Pipes
|
||
|
|
||
|
Input and output pipes to Perl filehandles are supported; the
|
||
|
"file name" is passed to lib$spawn() for asynchronous
|
||
|
execution. You should be careful to close any pipes you have
|
||
|
opened in a Perl script, lest you leave any "orphaned"
|
||
|
subprocesses around when Perl exits.
|
||
|
|
||
|
You may also use backticks to invoke a DCL subprocess, whose
|
||
|
output is used as the return value of the expression. The
|
||
|
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 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
|
||
|
C<$ENV{'PERL_MBX_SIZE'} = 32767;> and then open and use pipe constructs.
|
||
|
An alternative would be to issue the command:
|
||
|
|
||
|
$ Define PERL_MBX_SIZE 32767
|
||
|
|
||
|
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 environment elements work as documented in L<perl>,
|
||
|
except that the element separator is, by default, '|' instead of ':'.
|
||
|
However, when running under a Unix shell as determined by the logical
|
||
|
name C<GNV$UNIX_SHELL>, the separator will be ':' as on Unix systems. 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 usually 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:
|
||
|
|
||
|
=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
|
||
|
line is passed to a subprocess for execution; the subprocess
|
||
|
takes the output of Perl as its input.
|
||
|
|
||
|
Finally, if the command line ends with '&', the entire
|
||
|
command is run in the background as an asynchronous
|
||
|
subprocess.
|
||
|
|
||
|
=head2 Command line switches
|
||
|
|
||
|
The following command line switches behave differently under
|
||
|
VMS than described in L<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.
|
||
|
|
||
|
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
|
||
|
|
||
|
If the C<-i> 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.)
|
||
|
|
||
|
=item -S
|
||
|
|
||
|
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.
|
||
|
|
||
|
=item -u
|
||
|
|
||
|
The C<-u> switch causes the VMS debugger to be invoked
|
||
|
after the Perl program is compiled, but before it has
|
||
|
run. It does not create a core dump file.
|
||
|
|
||
|
=back
|
||
|
|
||
|
=head1 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):
|
||
|
|
||
|
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///
|
||
|
|
||
|
The following functions were not implemented in the VMS port,
|
||
|
and calling them produces a fatal error (usually) or
|
||
|
undefined behavior (rarely, we hope):
|
||
|
|
||
|
chroot, dbmclose, dbmopen, fork*, getpgrp, getpriority,
|
||
|
msgctl, msgget, msgsend, msgrcv, semctl,
|
||
|
semget, semop, setpgrp, setpriority, shmctl, shmget,
|
||
|
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
|
||
|
your copy of Perl:
|
||
|
|
||
|
accept, bind, connect, getpeername,
|
||
|
gethostbyname, getnetbyname, getprotobyname,
|
||
|
getservbyname, gethostbyaddr, getnetbyaddr,
|
||
|
getprotobynumber, getservbyport, gethostent,
|
||
|
getnetent, getprotoent, getservent, sethostent,
|
||
|
setnetent, setprotoent, setservent, endhostent,
|
||
|
endnetent, endprotoent, endservent, getsockname,
|
||
|
getsockopt, listen, recv, select(system call)*,
|
||
|
send, setsockopt, shutdown, socket
|
||
|
|
||
|
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
|
||
|
|
||
|
The tests C<-b>, C<-B>, C<-c>, C<-C>, C<-d>, C<-e>, C<-f>,
|
||
|
C<-o>, C<-M>, C<-s>, C<-S>, C<-t>, C<-T>, and C<-z> work as
|
||
|
advertised. The return values for C<-r>, C<-w>, and C<-x>
|
||
|
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, C<-O>, C<-R>, C<-W>,
|
||
|
and C<-X> are equivalent to C<-o>, C<-r>, C<-w>, and C<-x>.
|
||
|
Similarly, several other tests, including C<-A>, C<-g>, C<-k>,
|
||
|
C<-l>, C<-p>, and C<-u>, aren't particularly meaningful under
|
||
|
VMS, and the values returned by these tests reflect whatever
|
||
|
your CRTL C<stat()> routine does to the equivalent bits in the
|
||
|
st_mode field. Finally, C<-d> returns true if passed a device
|
||
|
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
|
||
|
extended file header of files on remote volumes, attempts to
|
||
|
examine the ACL fail, and the file tests will return false,
|
||
|
with C<$!> indicating that the file does not exist. You can
|
||
|
use C<stat> on these files, since that checks UIC-based protection
|
||
|
only, and then manually check the appropriate bits, as defined by
|
||
|
your C compiler's F<stat.h>, in the mode value it returns, if you
|
||
|
need an approximation of the file's protections.
|
||
|
|
||
|
=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 C<lib$spawn()>, any valid DCL command string
|
||
|
may be specified.
|
||
|
|
||
|
=item binmode FILEHANDLE
|
||
|
|
||
|
The C<binmode> operator will attempt to insure that no translation
|
||
|
of carriage control occurs on input from or output to this filehandle.
|
||
|
Since this involves reopening the file and then restoring its
|
||
|
file 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 C<binmode>
|
||
|
was called.
|
||
|
|
||
|
Note that C<binmode> is generally not necessary when using normal
|
||
|
filehandles; it is provided so that you can control I/O to existing
|
||
|
record-structured files when necessary. You can also use the
|
||
|
C<vmsfopen> function in the VMS::Stdio extension to gain finer
|
||
|
control of I/O to files and devices with different record structures.
|
||
|
|
||
|
=item crypt PLAINTEXT, USER
|
||
|
|
||
|
The C<crypt> operator uses the C<sys$hash_password> 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.
|
||
|
|
||
|
The value returned by C<crypt> may be compared against
|
||
|
the encrypted password from the UAF returned by the C<getpw*>
|
||
|
functions, in order to authenticate users. If you're
|
||
|
going to do this, remember that the encrypted password in
|
||
|
the UAF was generated using uppercase username and
|
||
|
password strings; you'll have to upcase the arguments to
|
||
|
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);
|
||
|
}
|
||
|
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 C<PERL_VMS_POSIX_EXIT> is active (see L</"$?"> below), 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 C<PERL_VMS_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 C<PERL_VMS_POSIX_EXIT> mode
|
||
|
may be changed to be ERROR or higher in the future depending on the
|
||
|
results of testing and further review.
|
||
|
|
||
|
See L</"$?"> for a description of the encoding of the Unix value to
|
||
|
produce a native VMS status containing it.
|
||
|
|
||
|
=item dump
|
||
|
|
||
|
Rather than causing Perl to abort and dump core, the C<dump>
|
||
|
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
|
||
|
C<dump>, or, if no label was specified, back to the
|
||
|
beginning of the program. All other state of the program
|
||
|
(I<e.g.> values of variables, open file handles) are not
|
||
|
affected by calling C<dump>.
|
||
|
|
||
|
=item exec LIST
|
||
|
|
||
|
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
|
||
|
|
||
|
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 getpwnam
|
||
|
|
||
|
=item getpwuid
|
||
|
|
||
|
These operators obtain the information described in L<perlfunc>,
|
||
|
if you have the privileges necessary to retrieve the named user's
|
||
|
UAF information via C<sys$getuai>. If not, then only the C<$name>,
|
||
|
C<$uid>, and C<$gid> items are returned. The C<$dir> item contains
|
||
|
the login directory in VMS syntax, while the C<$comment> item
|
||
|
contains the login directory in Unix syntax. The C<$gcos> item
|
||
|
contains the owner field from the UAF record. The C<$quota>
|
||
|
item is not used.
|
||
|
|
||
|
=item gmtime
|
||
|
|
||
|
The C<gmtime> operator will function properly if you have a
|
||
|
working CRTL C<gmtime()> 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 C<undef> is returned.
|
||
|
|
||
|
=item kill
|
||
|
|
||
|
In most cases, C<kill> is implemented via the undocumented system
|
||
|
service C<$SIGPRC>, which has the same calling sequence as C<$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.
|
||
|
|
||
|
=item qx//
|
||
|
|
||
|
See the entry on C<backticks> above.
|
||
|
|
||
|
=item select (system call)
|
||
|
|
||
|
If Perl was not built with socket support, the system call
|
||
|
version of C<select> is not available at all. If socket
|
||
|
support is present, then the system call version of
|
||
|
C<select> functions only for file descriptors attached
|
||
|
to sockets. It will not provide information about regular
|
||
|
files or pipes, since the CRTL C<select()> routine does not
|
||
|
provide this functionality.
|
||
|
|
||
|
=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 C<st_dev> and C<st_ino> fields of a C<struct stat>. Perl
|
||
|
tries its best, though, and the values it uses are pretty unlikely
|
||
|
to be the same for two different files. We can't guarantee this,
|
||
|
though, so caveat scriptor.
|
||
|
|
||
|
=item system LIST
|
||
|
|
||
|
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 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 unless the pragma C<use vmsish 'status'> is in
|
||
|
effect; see the description of C<$?> in this document for more
|
||
|
detail.
|
||
|
|
||
|
=item time
|
||
|
|
||
|
The value returned by C<time> is the offset in seconds from
|
||
|
01-JAN-1970 00:00:00 (just like the CRTL's times() routine), in order
|
||
|
to make life easier for code coming in from the POSIX/Unix world.
|
||
|
|
||
|
=item times
|
||
|
|
||
|
The array returned by the C<times> operator is divided up
|
||
|
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 a subprocess may or may
|
||
|
not appear separately in the "child time" field, depending on
|
||
|
whether C<times()> keeps track of subprocesses separately. Note
|
||
|
especially that the VAXCRTL (at least) keeps track only of
|
||
|
subprocesses spawned using C<fork()> and C<exec()>; it will not
|
||
|
accumulate the times of subprocesses spawned via pipes, C<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;
|
||
|
|
||
|
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.
|
||
|
(Note: This can be changed at compile time; if you
|
||
|
C<use Config> and C<$Config{'d_unlink_all_versions'}> is
|
||
|
C<define>, then C<unlink> will delete all versions of a
|
||
|
file on the first call.)
|
||
|
|
||
|
C<unlink> 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
|
||
|
C<VMS::Filespec::candelete> operator. For instance, in order
|
||
|
to delete only files to which you have delete access, you could
|
||
|
say something like
|
||
|
|
||
|
sub safe_unlink {
|
||
|
my($file,$num);
|
||
|
foreach $file (@_) {
|
||
|
next unless VMS::Filespec::candelete($file);
|
||
|
$num += unlink $file;
|
||
|
}
|
||
|
$num;
|
||
|
}
|
||
|
|
||
|
(or you could just use C<VMS::Stdio::remove>, if you've installed
|
||
|
the VMS::Stdio extension distributed with Perl). If C<unlink> has to
|
||
|
change the file protection to delete the file, and you interrupt it
|
||
|
in midstream, the file may be left intact, but with a changed ACL
|
||
|
allowing you delete access.
|
||
|
|
||
|
This behavior of C<unlink> is to be compatible with POSIX behavior
|
||
|
and not traditional VMS behavior.
|
||
|
|
||
|
=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.
|
||
|
|
||
|
=item waitpid PID,FLAGS
|
||
|
|
||
|
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.)
|
||
|
|
||
|
Returns PID on success, -1 on error. The FLAGS argument is ignored
|
||
|
in all cases.
|
||
|
|
||
|
=back
|
||
|
|
||
|
=head1 Perl variables
|
||
|
|
||
|
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 information
|
||
|
takes precedence.
|
||
|
|
||
|
=over 4
|
||
|
|
||
|
=item %ENV
|
||
|
|
||
|
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 some embedded Perl
|
||
|
applications or when running under a shell such as GNV bash, 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. This default order is reversed when the
|
||
|
logical name F<GNV$UNIX_SHELL> is defined, such as when running under
|
||
|
GNV bash.
|
||
|
|
||
|
For operations on %ENV 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 %ENV based on the
|
||
|
CRTL's environ array preserve the case of the key string when stored, and
|
||
|
lookups are case sensitive.
|
||
|
|
||
|
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>, 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 C<NUL>
|
||
|
(ASCII C<\0>) 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.)
|
||
|
|
||
|
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.) 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.
|
||
|
|
||
|
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 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)
|
||
|
|
||
|
=item $!
|
||
|
|
||
|
The string value of C<$!> is that returned by the CRTL's
|
||
|
strerror() function, so it will include the VMS message for
|
||
|
VMS-specific errors. The numeric value of C<$!> is the
|
||
|
value of C<errno>, except if errno is EVMSERR, in which
|
||
|
case C<$!> contains the value of vaxc$errno. Setting C<$!>
|
||
|
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 C<$!> won't reflect the VMS error
|
||
|
message from before C<$!> was set.
|
||
|
|
||
|
=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 C<$!>. Its numeric value
|
||
|
is the value of vaxc$errno, and its string value is the
|
||
|
corresponding VMS message string, as retrieved by sys$getmsg().
|
||
|
Setting 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
|
||
|
actual exit status of the subprocess in a way that approximates
|
||
|
POSIX wait(5) semantics, in order to allow Perl programs to
|
||
|
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 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:
|
||
|
|
||
|
VMS_status = 0x35a000 + 8 + 2 + 0x10000000.
|
||
|
|
||
|
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.
|
||
|
|
||
|
As a result, C<$?> 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.
|
||
|
|
||
|
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 C<PERL_VMS_POSIX_EXIT> logical name defined as "ENABLE",
|
||
|
setting C<$?> will cause the new value to be encoded into C<$^E>
|
||
|
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.
|
||
|
|
||
|
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 C<PERL_VMS_POSIX_EXIT>
|
||
|
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.
|
||
|
|
||
|
In general, with C<PERL_VMS_POSIX_EXIT> 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.
|
||
|
|
||
|
N.B. Setting C<DECC$FILENAME_UNIX_REPORT> implicitly enables
|
||
|
C<PERL_VMS_POSIX_EXIT>.
|
||
|
|
||
|
=item $|
|
||
|
|
||
|
Setting C<$|> for an I/O stream causes data to be flushed
|
||
|
all the way to disk on each write (I<i.e.> not just to
|
||
|
the underlying RMS buffers for a file). In other words,
|
||
|
it's equivalent to calling fflush() and fsync() from C.
|
||
|
|
||
|
=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
|
||
|
|
||
|
Please see the git repository for revision history.
|
||
|
|
||
|
=head1 AUTHOR
|
||
|
|
||
|
Charles Bailey bailey@cor.newman.upenn.edu
|
||
|
Craig Berry craigberry@mac.com
|
||
|
Dan Sugalski dan@sidhe.org
|
||
|
John Malmberg wb8tyw@qsl.net
|