man > perlvms(1)

PERLVMS(1)                        Perl Programmers Reference Guide                        PERLVMS(1)

NAME
       perlvms - VMS-specific documentation for Perl

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
       [.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 AT perl.org.

Installation
       Directions for building and installing Perl 5 can be found in the file README.vms in the main
       source directory of the Perl distribution.

Organization of Perl Images
   Core Images
       During the build process, three Perl images are produced.  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 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 PERLSHR.  While it's possible to put the image in 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, 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.

   Perl Extensions
       Perl extensions are packages which provide both XS and Perl code to add new functionality to
       perl.  (XS is a meta-language which simplifies writing C code which interacts with Perl, see
       perlxs for more details.)  The Perl code for an extension is treated like any other library
       module - it's made available in your script through the appropriate "use" or "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 static configuration, the object code for the extension is linked
       directly into PerlShr.Exe, and is initialized whenever Perl is invoked.  In the 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 "use"d or "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: Extshortname.xs (where Extshortname is the portion of the extension's
       name following the last "::"), containing the XS code, Extshortname.pm, the Perl library
       module for the extension, and Makefile.PL, a Perl script which uses the "MakeMaker" library
       modules supplied with Perl to generate a Descrip.MMS file for the extension.

   Installing static extensions
       Since static extensions are incorporated directly into PerlShr.Exe, you'll have to rebuild
       Perl to incorporate a new extension.  You should edit the main Descrip.MMS or Makefile you
       use to build Perl, adding the extension's name to the "ext" macro, and the extension's object
       file to the "extobj" macro.  You'll also need to build the extension's object file, either by
       adding dependencies to the main Descrip.MMS, or using a separate Descrip.MMS for the
       extension.  Then, rebuild PerlShr.Exe to incorporate the new code.

       Finally, you'll need to copy the extension's Perl library module to the [.Extname]
       subdirectory under one of the directories in @INC, where Extname is the name of the
       extension, with all "::" replaced by "." (e.g.  the library module for extension Foo::Bar
       would be copied to a [.Foo.Bar] subdirectory).

   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 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 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.)

       •   the  [.Lib.Auto.Arch$PVersExtname]  subdirectory of one of the directories in @INC (where
           PVers is the version of Perl you're using, as supplied in $], with '.' converted to '_'),
           or

       •   one of the directories in @INC, or

       •   a directory which the extensions Perl library module passes to the DynaLoader when asking
           it to map the shareable image, or

       •   Sys$Share or Sys$Library.

       If the shareable image isn't in any of these places, you'll need to  define  a  logical  name
       Extshortname,  where Extshortname is the portion of the extension's name after the last "::",
       which translates to the full file specification of the shareable image.

File specifications
   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 (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 "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, 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 "./.../" in a  Unix  path  is  now  translated  to  "[.^.^.^.]"  instead  of  the
       traditional  VMS "[...]".  To be compatible with what MakeMaker expects, if a VMS path cannot
       be translated to a Unix path, it is passed through unchanged, so unixify("[...]") will return
       "[...]".

       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.

   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.

       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 "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
       "File::Spec->case_tolerant" method to determine the state, and not the $^O variable.

   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 "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.

   Wildcard expansion
       File specifications containing wildcards are allowed both on the command line and within Perl
       globs (e.g. "<*.c>").  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 """ around a  perl  program  command  line
       argument.  However, owing to the stripping of """ 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 PERL.C, PERL.EXE, PERL.H, and 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  glob()  VMS  wildcard
       expansion   is   performed.   (csh-style   wildcard   expansion   is  available  if  you  use
       "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    "[.t]*.*"   will   yield   filespecs    like
       "perl_root:[t]base.dir",  while  the  expansion  of  "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.

   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  "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  "$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.

PERL5LIB and PERLLIB
       The PERL5LIB and PERLLIB environment elements work as documented in  perl,  except  that  the
       element  separator  is,  by  default, '|' instead of ':'.  However, when running under a Unix
       shell as determined by the logical name "GNV$UNIX_SHELL", the separator will  be  ':'  as  on
       Unix systems. The directory specifications may use either VMS or Unix syntax.

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  "TERM"  to  be  "xterm",  and  the
       environment variable "DISPLAY" to exist.  "xterm" must be in lower case.

         $define TERM "xterm"

         $define DISPLAY "hostname:0.0"

       Currently  the  value  of  "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

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 "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.

Command line
   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:

       •   "<file" reads stdin from "file",

       •   ">file" writes stdout to "file",

       •   ">>file" appends stdout to "file",

       •   "2>file" writes stderr to "file",

       •   "2>>file" appends stderr to "file", and

       •   "2>&1" redirects stderr to stdout.

       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.

   Command line switches
       The following command line switches behave differently under VMS than described  in  perlrun.
       Note  also  that  in  order  to  pass uppercase switches to Perl, you need to enclose them in
       double-quotes on the command line, since the CRTL downcases all unquoted strings.

       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.

       -i  If  the  "-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.)

       -S  If the "-S" or "-"S"" switch is present 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 .pl, and a type of .com, in that order.

       -u  The "-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.

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

       File tests
           The tests "-b", "-B", "-c", "-C", "-d", "-e", "-f", "-o", "-M", "-s", "-S",  "-t",  "-T",
           and "-z" work as advertised.  The return values for "-r", "-w", and "-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,  "-O",  "-R",  "-W",  and  "-X"  are
           equivalent  to  "-o",  "-r",  "-w",  and "-x".  Similarly, several other tests, including
           "-A", "-g", "-k", "-l", "-p", and "-u", aren't particularly meaningful under VMS, and the
           values returned by these tests reflect whatever your CRTL  stat()  routine  does  to  the
           equivalent  bits  in  the  st_mode  field.  Finally, "-d" returns true if passed a device
           specification without an explicit directory (e.g.  "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 ("-r", "-w", and
           "-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 $! indicating  that  the
           file  does  not  exist.   You  can use "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  stat.h,  in  the  mode  value it returns, if you need an approximation of the
           file's protections.

       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 "lib$spawn()", any valid DCL
           command string may be specified.

       binmode FILEHANDLE
           The "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 "binmode" was called.

           Note that "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 "vmsfopen" function  in  the  VMS::Stdio  extension  to  gain  finer
           control of I/O to files and devices with different record structures.

       crypt PLAINTEXT, USER
           The  "crypt"  operator uses the "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 "crypt" may be compared against the encrypted password from the UAF
           returned by the "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 "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;
               }

       die "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  "PERL_VMS_POSIX_EXIT"  is active (see "$?" below), the native VMS exit status value
           will have either one of the $! or $? or $^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  "die"  if
           either  $!  or  $?  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 $^E value is set  one  of
           ERROR  or  SEVERE_ERROR severity, then the $^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   "die"   in  the
           "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 "die" in "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 "$?" for a description of the encoding of the Unix value  to  produce  a  native  VMS
           status containing it.

       dump
           Rather  than  causing  Perl  to  abort and dump core, the "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 "dump", or, if no label was
           specified, back to the beginning of the program.  All other state of  the  program  (e.g.
           values of variables, open file handles) are not affected by calling "dump".

       exec LIST
           A  call to "exec" will cause Perl to exit, and to invoke the command given as an argument
           to "exec" via "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 .Exe and the process defaults to expand the filespec) and pass the rest
           of "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 "MCR" or  a  text  file  which  should  be
           passed to DCL as a command procedure.

       fork
           While in principle the "fork" operator could be implemented via (and with the same rather
           severe  limitations  as)  the CRTL vfork() routine, and while some internal support to do
           just that is in place,  the  implementation  has  never  been  completed,  making  "fork"
           currently  unavailable.  A true kernel 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 perlfork).  In the meantime, use "system", backticks, or piped filehandles to
           create subprocesses.

       getpwent
       getpwnam
       getpwuid
           These operators obtain the information described in perlfunc, if you have the  privileges
           necessary  to  retrieve  the named user's UAF information via "sys$getuai".  If not, then
           only the $name, $uid, and $gid items are returned.  The  $dir  item  contains  the  login
           directory  in  VMS  syntax,  while the $comment item contains the login directory in Unix
           syntax. The $gcos item contains the owner field from the UAF record.  The $quota item  is
           not used.

       gmtime
           The "gmtime" operator will function properly if you have a working CRTL 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 "undef" is returned.

       kill
           In  most  cases, "kill" is implemented via the undocumented system service $SIGPRC, which
           has the same calling sequence as $FORCEX, but throws an exception in the  target  process
           rather than forcing it to call $EXIT.  Generally speaking, "kill" follows the behavior of
           the  CRTL's  kill() function, but unlike that function can be called from within a signal
           handler.  Also, unlike the "kill" in some versions of the CRTL, Perl's "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.

       qx//
           See the entry on "backticks" above.

       select (system call)
           If  Perl  was  not  built with socket support, the system call version of "select" is not
           available at all.  If socket support is present, then the system call version of "select"
           functions only for file descriptors attached to sockets.  It will not provide information
           about regular files or pipes, since the CRTL  select()  routine  does  not  provide  this
           functionality.

       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 "st_dev" and "st_ino" fields of a "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.

       system LIST
           The "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
           "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.  ":"  or  "]"),  an
           attempt  is made to expand it using  a default type of .Exe and the process defaults, and
           if successful, the resulting file is invoked via "MCR". This  allows  you  to  invoke  an
           image  directly  simply  by  passing the file specification to "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 "MCR" or a text file which should be passed to DCL as a command procedure.

           If  LIST  consists of the empty string, "system" spawns an interactive DCL subprocess, in
           the same fashion as typing SPAWN at the DCL prompt.

           Perl waits for the subprocess to complete before  continuing  execution  in  the  current
           process.  As described in perlfunc, the return value of "system" is a fake "status" which
           follows  POSIX  semantics  unless  the pragma "use vmsish 'status'" is in effect; see the
           description of $? in this document for more detail.

       time
           The value returned by "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.

       times
           The array returned by the "times" operator is divided up according to the same rules  the
           CRTL  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 times() keeps track of  subprocesses  separately.   Note  especially
           that  the  VAXCRTL  (at  least) keeps track only of subprocesses spawned using fork() and
           exec(); it will not accumulate the times of subprocesses spawned via pipes, system(),  or
           backticks.

       unlink LIST
           "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 "unlink", no files with the names passed to "unlink" will exist.   (Note:
           This    can    be    changed    at    compile    time;    if   you   "use   Config"   and
           $Config{'d_unlink_all_versions'} is "define", then "unlink" will delete all versions of a
           file on the first call.)

           "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
           "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 "VMS::Stdio::remove", if you've installed the VMS::Stdio extension
           distributed with Perl). If "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 "unlink" is to be compatible with POSIX behavior and not traditional VMS
           behavior.

       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.

       waitpid PID,FLAGS
           If PID is a subprocess started by a piped open() (see open), "waitpid" will wait for that
           subprocess, and return its final status value in $?.  If PID is a subprocess  created  in
           some  other way (e.g.  SPAWNed before Perl was invoked), "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
           "-w" switch, a warning will be issued.)

           Returns PID on success, -1 on error.  The FLAGS argument is ignored in all cases.

Perl variables
       The following VMS-specific information applies to the indicated "special" Perl variables,  in
       addition  to the general information in perlvar.  Where there is a conflict, this information
       takes precedence.

       %ENV
           The operation of  the  %ENV  array  depends  on  the  translation  of  the  logical  name
           PERL_ENV_TABLES.  If defined, it should be a search list, each element of which specifies
           a   location  for  %ENV  elements.   If  you  tell  Perl  to  read  or  set  the  element
           "$ENV{"name"}", then Perl uses the translations of PERL_ENV_TABLES as follows:

           CRTL_ENV
               This string tells Perl to consult the CRTL's internal "environ"  array  of  key-value
               pairs,  using  name as the key.  In most cases, this contains only a few keys, but if
               Perl was invoked via the 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 "environ" array
               may have been populated by the calling program.

           CLISYM_[LOCAL]
               A string beginning with "CLISYM_"tells Perl to consult the CLI's symbol tables, using
               name  as  the  name of the symbol.  When reading an element of %ENV, the local symbol
               table is scanned first,  followed  by  the  global  symbol  table..   The  characters
               following "CLISYM_" are significant when an element of %ENV is set or deleted: if the
               complete  string  is  "CLISYM_LOCAL",  the  change is made in the local symbol table;
               otherwise the global symbol table is changed.

           Any other string
               If an element of PERL_ENV_TABLES translates to any other string, that string is  used
               as  the  name  of  a logical name table, which is consulted using name as the logical
               name.  The normal search order of access modes is used.

           PERL_ENV_TABLES is translated once when Perl starts up; any changes you make  while  Perl
           is  running  do not affect the behavior of %ENV.  If PERL_ENV_TABLES is not defined, then
           Perl defaults to consulting first the logical name tables specified by LNM$FILE_DEV,  and
           then  the  CRTL  "environ"  array.   This default order is reversed when the logical name
           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  %ENV  is  read,  the locations to which PERL_ENV_TABLES points are
           checked in order, and the value obtained from the first successful  lookup  is  returned.
           If the name of the %ENV element contains a semi-colon, it and any characters after it are
           removed.   These  are  ignored  when  the  CRTL  "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 "ONCE UPON A TIME THERE WAS", assuming, of course, that PERL_ENV_TABLES
           is set up so that the logical name "story" is found, rather than a  CLI  symbol  or  CRTL
           "environ" element with the same name.

           When  an element of %ENV is set to a defined string, the corresponding definition is made
           in the location to which the first translation of 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 "\0")
           character, since a  logical  name  cannot  translate  to  a  zero-length  string.   (This
           restriction  does  not apply to CLI symbols or CRTL "environ" values; they are set to the
           empty string.)

           When an element of %ENV is set to "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 "environ"
           array is set to the empty string.)  Using "delete" to remove an element from %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 $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
           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 "$ENV{$key} = $ENV{$key}", since the Perl optimizer is  smart  enough
           to elide the expression.)

           Don't  try  to  clear  %ENV by saying "%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 "keys", or "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  "SYS$INPUT"  and  "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)

       $!  The string value of $! is that returned by the CRTL's strerror()  function,  so  it  will
           include the VMS message for VMS-specific errors.  The numeric value of $! is the value of
           "errno",  except  if errno is EVMSERR, in which case $! contains the value of vaxc$errno.
           Setting $!  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 $! won't reflect the
           VMS error message from before $! was set.

       $^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 $!.  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 $^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.

       $?  The  "status  value"  returned  in  $?  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 $? 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, $? 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 $? is between 2 and 255 or 0, then $? accurately reflects a value
           passed back from a Unix application.  If $? is 1, and the severity bits  indicate  a  VMS
           error (2), then $? 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 $! 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 $? 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 $? to  zero  results  in  the  generic  success  value
           SS$_NORMAL,  and  setting  $?  to  a non-zero value results in the generic failure status
           SS$_ABORT.  See also "exit" in perlport.

           With the "PERL_VMS_POSIX_EXIT" logical name defined as "ENABLE", setting  $?  will  cause
           the  new  value  to  be encoded into $^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 "use vmsish 'status'" makes $? 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 $? in an END block (but zero will
           still be converted to SS$_NORMAL).

           Do not use the pragma "use vmsish 'status'" with "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  "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 "DECC$FILENAME_UNIX_REPORT" implicitly enables "PERL_VMS_POSIX_EXIT".

       $|  Setting $| for an I/O stream causes data to be flushed all the way to disk on each  write
           (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.

Standard modules with VMS-specific differences
   SDBM_File
       SDBM_File works properly on  VMS.  It  has,  however,  one  minor  difference.  The  database
       directory file created has a .sdbm_dir extension rather than a .dir extension. .dir files are
       VMS  filesystem  directory  files, and using them for other purposes could cause unacceptable
       problems.

Revision date
       Please see the git repository for revision history.

AUTHOR
       Charles Bailey  bailey AT cor.edu  Craig  Berry   craigberry AT mac.com  Dan  Sugalski
       dan AT sidhe.org John Malmberg wb8tyw AT qsl.net

perl v5.38.2                                 2026-08-18                                   PERLVMS(1)
perlvms(1) □✕
NAME DESCRIPTION Installation Organization of Perl Images
Core Images Perl Extensions Installing static extensions Installing dynamic extensions
File specifications
Syntax Filename Case Symbolic Links Wildcard expansion Pipes
The Perl Forked Debugger PERL_VMS_EXCEPTION_DEBUG Command line
I/O redirection and backgrounding Command line switches
Perl functions Perl variables Standard modules with VMS-specific differences
SDBM_File
Revision date AUTHOR

Generated by phpman v9.9.10-37-gcf157e7 · Markdown · JSON · MCP Author: Che Dong Under GNU General Public License
2026-10-08 13:40 @216.73.217.162
CrawledBy Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; ClaudeBot/1.0; +claudebot@anthropic.com)
Valid XHTML 1.0 Transitional!Valid CSS!

^_top_^