home *** CD-ROM | disk | FTP | other *** search
- =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@newman.upenn.edu.
-
- =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 installation 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 extensions. It is used to generate several files needed
- to build the complete Perl and various extensions. Once you've
- finished installing Perl, you can delete this image.
-
- 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. You should place this
- image in F<Sys$Share>, or define the logical name F<PerlShr> to
- translate to the full file specification of this image. It should
- be world readable. (Remember that if a user has execute only access
- to F<PerlShr>, VMS will treat it as if it were a privileged shareable
- image, and will therefore require all downstream shareable images to be
- INSTALLed, etc.)
-
-
- Finally, 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
-
- 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'
- maximum of 8 levels of subdirectory in a filespec. (You
- can use rooted logical names to get another 8 levels of
- nesting, if you can't place the files near the top of
- the physical directory structure.)
-
- VMS support for this process in the current release of Perl
- is sufficient to handle most extensions. However, it does
- not yet recognize extra libraries required to build shareable
- images which are part of an extension, so these must be added
- to the linker options file for the extension by hand. For
- instance, if the F<PGPLOT> extension to Perl requires the
- F<PGPLOTSHR.EXE> shareable image in order to properly link
- the Perl extension, then the line C<PGPLOTSHR/Share> must
- 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
- 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>.
- 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 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.
-
- =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 wildcard filespec uses VMS syntax, the resultant
- filespecs will follow VMS syntax; if a Unix-style filespec is
- passed in, Unix-style filespecs will be returned.
-
- In both cases, VMS wildcard expansion is performed. (csh-style
- wildcard expansion is available if you use 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.
-
- =head1 PERL5LIB and PERLLIB
-
- The PERL5LIB and PERLLIB logical names work as documented L<perl>,
- except that the element separator is '|' instead of ':'. The
- directory specifications may use either VMS or Unix syntax.
-
- =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>.
-
- 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.
-
- =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> 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, endpwent, eof, eval, exec*,
- exists, exit, exp, fileno, fork*, getc, getlogin,
- getpwent*, getpwnam*, getpwuid*, glob, gmtime*, goto,
- grep, hex, import, index, int, join, keys, kill*,
- last, lc, lcfirst, length, local, localtime, log, m//,
- map, mkdir, my, next, no, oct, open, opendir, ord, pack,
- pipe, pop, pos, print, printf, push, q//, qq//, qw//,
- qx//*, quotemeta, rand, read, readdir, redo, ref, rename,
- require, reset, return, reverse, rewinddir, rindex,
- rmdir, s///, scalar, seek, seekdir, select(internal),
- select (system call)*, setpwent, shift, sin, sleep,
- sort, splice, split, sprintf, sqrt, srand, stat,
- study, substr, sysread, system*, syswrite, tell,
- telldir, tie, time, times*, tr///, uc, ucfirst, umask,
- undef, unlink*, unpack, untie, unshift, use, utime*,
- values, vec, wait, waitpid*, wantarray, warn, write, y///
-
- The following functions were not implemented in the VMS port,
- and calling them produces a fatal error (usually) or
- undefined behavior (rarely, we hope):
-
- chroot, dbmclose, dbmopen, fcntl, flock,
- getpgrp, getppid, getpriority, getgrent, getgrgid,
- getgrnam, setgrent, endgrent, ioctl, link, lstat,
- msgctl, msgget, msgsend, msgrcv, readlink, semctl,
- semget, semop, setpgrp, setpriority, shmctl, shmget,
- shmread, shmwrite, socketpair, symlink, syscall
-
- The following functions are available on Perls compiled with Dec C 5.2 or
- greater and running VMS 7.0 or greater
-
- truncate
-
- The following functions may or may not be implemented,
- depending on what type of socket support you've built into
- your copy of Perl:
-
- accept, bind, connect, getpeername,
- gethostbyname, getnetbyname, getprotobyname,
- getservbyname, gethostbyaddr, getnetbyaddr,
- getprotobynumber, getservbyport, gethostent,
- getnetent, getprotoent, getservent, sethostent,
- setnetent, setprotoent, setservent, endhostent,
- endnetent, endprotoent, endservent, getsockname,
- getsockopt, listen, recv, select(system call)*,
- send, setsockopt, shutdown, socket
-
- =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.
-
- 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 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
-
- 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 '@' 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.
-
- 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>.
-
- =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.
-
- =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> 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.)
-
- 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 typiing
- 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).
-
- =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 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>,
- 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.
-
- =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).
-
- =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,
- and you invoked Perl with the C<-w> switch, a warning will be issued.)
-
- 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 infrmation
- 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 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>, 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.)
-
- 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 logicals representing process-permanent
- files, such as C<SYS$INPUT> and C<SYS$OUTPUT>. The translations for these
- logicals are prepended with a two-byte binary value (0x1B 0x00) that needs to be
- stripped off if you want to use it. (In previous versions of perl it wasn't
- possible to get the values of these logicals, as the null byte acted as an
- end-of-string marker)
-
- =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.
-
- =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 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.).
-
- =item $^S
-
- 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.
-
- =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
-
- This document was last updated on 26-Feb-2000, for Perl 5,
- patchlevel 6.
-
- =head1 AUTHOR
-
- Charles Bailey <bailey@cor.newman.upenn.edu>
- Dan Sugalski <dan@sidhe.org>
-