| =head1 NAME |
| |
| perlvms - VMS-specific documentation for Perl |
| |
| =head1 DESCRIPTION |
| |
| Gathered below are notes describing details of Perl 5's |
| behavior on VMS. They are a supplement to the regular Perl 5 |
| documentation, so we have focussed on the ways in which Perl |
| 5 functions differently under VMS than it does under Unix, |
| and on the interactions between Perl and the rest of the |
| operating system. We haven't tried to duplicate complete |
| descriptions of Perl features from the main Perl |
| documentation, which can be found in the F<[.pod]> |
| subdirectory of the Perl distribution. |
| |
| We hope these notes will save you from confusion and lost |
| sleep when writing Perl scripts on VMS. If you find we've |
| missed something you think should appear here, please don't |
| hesitate to drop a line to vmsperl@perl.org. |
| |
| =head1 Installation |
| |
| Directions for building and installing Perl 5 can be found in |
| the file F<README.vms> in the main source directory of the |
| Perl distribution.. |
| |
| =head1 Organization of Perl Images |
| |
| =head2 Core Images |
| |
| During the 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 if you are running a version of VMS prior |
| to V7.1 you shouldn't nest the source directory |
| too deeply in your directory structure lest you exceed RMS' |
| maximum of 8 levels of subdirectory in a filespec. (You |
| can use rooted logical names to get another 8 levels of |
| nesting, if you can't place the files near the top of |
| 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 in |
| the F<[.lib.site_perl.auto>I<Arch>.I<Extname>F<]> directory of the |
| installed Perl directory tree (where I<Arch> is F<VMS_VAX> or |
| F<VMS_AXP>, and I<Extname> is the name of the extension, with |
| each C<::> translated to C<.>). (See the MakeMaker documentation |
| for more details on installation options for extensions.) |
| However, it can be manually placed in any of several locations: |
| |
| =over 4 |
| |
| =item * |
| |
| the F<[.Lib.Auto.>I<Arch>I<$PVers>I<Extname>F<]> subdirectory |
| of one of the directories in C<@INC> (where I<PVers> |
| is the version of Perl you're using, as supplied in C<$]>, |
| with '.' converted to '_'), or |
| |
| =item * |
| |
| one of the directories in C<@INC>, or |
| |
| =item * |
| |
| a directory which the extensions Perl library module |
| passes to the DynaLoader when asking it to map |
| the shareable image, or |
| |
| =item * |
| |
| F<Sys$Share> or F<Sys$Library>. |
| |
| =back |
| |
| If the shareable image isn't in any of these places, you'll need |
| to define a logical name I<Extshortname>, where I<Extshortname> |
| is the portion of the extension's name after the last C<::>, which |
| translates to the full file specification of the shareable image. |
| |
| =head1 File specifications |
| |
| =head2 Syntax |
| |
| We have tried to make Perl aware of both VMS-style and Unix-style file |
| specifications wherever possible. You may use either style, or both, |
| on the command line and in scripts, but you may not combine the two |
| styles within a single file specification. VMS Perl interprets Unix |
| pathnames in much the same way as the CRTL (I<e.g.> the first component |
| of an absolute path is read as the device name for the VMS file |
| specification). There are a set of functions provided in the |
| C<VMS::Filespec> package for explicit interconversion between VMS and |
| Unix syntax; its documentation provides more details. |
| |
| We've tried to minimize the dependence of Perl library |
| modules on Unix syntax, but you may find that some of these, |
| as well as some scripts written for Unix systems, will |
| require that you use Unix syntax, since they will assume that |
| '/' is the directory separator, I<etc.> If you find instances |
| of this in the Perl distribution itself, please let us know, |
| so we can try to work around them. |
| |
| Also when working on Perl programs on VMS, if you need a syntax |
| in a specific operating system format, then you need either to |
| check the appropriate DECC$ feature logical, or call a conversion |
| routine to force it to that format. |
| |
| The feature logical name DECC$FILENAME_UNIX_REPORT modifies traditional |
| Perl behavior in the conversion of file specifications from Unix to VMS |
| format in order to follow the extended character handling rules now |
| expected by the CRTL. Specifically, when this feature is in effect, the |
| C<./.../> in a Unix path is now translated to C<[.^.^.^.]> instead of |
| the traditional VMS C<[...]>. To be compatible with what MakeMaker |
| expects, if a VMS path cannot be translated to a Unix path, it is |
| passed through unchanged, so C<unixify("[...]")> will return C<[...]>. |
| |
| The handling of extended characters is largely complete in the |
| VMS-specific C infrastructure of Perl, but more work is still needed to |
| fully support extended syntax filenames in several core modules. In |
| particular, at this writing PathTools has only partial support for |
| directories containing some extended characters. |
| |
| There are several ambiguous cases where a conversion routine cannot |
| determine whether an input filename is in Unix format or in VMS format, |
| since now both VMS and Unix file specifications may have characters in |
| them that could be mistaken for syntax delimiters of the other type. So |
| some pathnames simply cannot be used in a mode that allows either type |
| of pathname to be present. Perl will tend to assume that an ambiguous |
| filename is in Unix format. |
| |
| Allowing "." as a version delimiter is simply incompatible with |
| determining whether a pathname is in VMS format or in Unix format with |
| extended file syntax. There is no way to know whether "perl-5.8.6" is a |
| Unix "perl-5.8.6" or a VMS "perl-5.8;6" when passing it to unixify() or |
| vmsify(). |
| |
| The DECC$FILENAME_UNIX_REPORT logical name controls how Perl interprets |
| filenames to the extent that Perl uses the CRTL internally for many |
| purposes, and attempts to follow CRTL conventions for reporting |
| filenames. The DECC$FILENAME_UNIX_ONLY feature differs in that it |
| expects all filenames passed to the C run-time to be already in Unix |
| format. This feature is not yet supported in Perl since Perl uses |
| traditional OpenVMS file specifications internally and in the test |
| harness, and it is not yet clear whether this mode will be useful or |
| useable. The feature logical name DECC$POSIX_COMPLIANT_PATHNAMES is new |
| with the RMS Symbolic Link SDK and included with OpenVMS v8.3, but is |
| not yet supported in Perl. |
| |
| =head2 Filename Case |
| |
| Perl follows VMS defaults and override settings in preserving (or not |
| preserving) filename case. Case is not preserved on ODS-2 formatted |
| volumes on any architecture. On ODS-5 volumes, filenames may be case |
| preserved depending on process and feature settings. Perl now honors |
| DECC$EFS_CASE_PRESERVE and DECC$ARGV_PARSE_STYLE on those systems where |
| the CRTL supports these features. When these features are not enabled |
| or the CRTL does not support them, Perl follows the traditional CRTL |
| behavior of downcasing command-line arguments and returning file |
| specifications in lower case only. |
| |
| I<N. B.> It is very easy to get tripped up using a mixture of other |
| programs, external utilities, and Perl scripts that are in varying |
| states of being able to handle case preservation. For example, a file |
| created by an older version of an archive utility or a build utility |
| such as MMK or MMS may generate a filename in all upper case even on an |
| ODS-5 volume. If this filename is later retrieved by a Perl script or |
| module in a case preserving environment, that upper case name may not |
| match the mixed-case or lower-case exceptions of the Perl code. Your |
| best bet is to follow an all-or-nothing approach to case preservation: |
| either don't use it at all, or make sure your entire toolchain and |
| application environment support and use it. |
| |
| OpenVMS Alpha v7.3-1 and later and all version of OpenVMS I64 support |
| case sensitivity as a process setting (see C<SET PROCESS |
| /CASE_LOOKUP=SENSITIVE>). Perl does not currently support case |
| sensitivity on VMS, but it may in the future, so Perl programs should |
| use the C<< File::Spec->case_tolerant >> method to determine the state, and |
| not the C<$^O> variable. |
| |
| =head2 Symbolic Links |
| |
| When built on an ODS-5 volume with symbolic links enabled, Perl by |
| default supports symbolic links when the requisite support is available |
| in the filesystem and CRTL (generally 64-bit OpenVMS v8.3 and later). |
| There are a number of limitations and caveats to be aware of when |
| working with symbolic links on VMS. Most notably, the target of a valid |
| symbolic link must be expressed as a Unix-style path and it must exist |
| on a volume visible from your POSIX root (see the C<SHOW ROOT> command |
| in DCL help). For further details on symbolic link capabilities and |
| requirements, see chapter 12 of the CRTL manual that ships with OpenVMS |
| v8.3 or later. |
| |
| =head2 Wildcard expansion |
| |
| File specifications containing wildcards are allowed both on |
| the command line and within Perl globs (e.g. C<E<lt>*.cE<gt>>). If |
| the wildcard filespec uses VMS syntax, the resultant |
| filespecs will follow VMS syntax; if a Unix-style filespec is |
| passed in, Unix-style filespecs will be returned. |
| Similar to the behavior of wildcard globbing for a Unix shell, |
| one can escape command line wildcards with double quotation |
| marks C<"> around a perl program command line argument. However, |
| owing to the stripping of C<"> characters carried out by the C |
| handling of argv you will need to escape a construct such as |
| this one (in a directory containing the files F<PERL.C>, F<PERL.EXE>, |
| F<PERL.H>, and F<PERL.OBJ>): |
| |
| $ perl -e "print join(' ',@ARGV)" perl.* |
| perl.c perl.exe perl.h perl.obj |
| |
| in the following triple quoted manner: |
| |
| $ perl -e "print join(' ',@ARGV)" """perl.*""" |
| perl.* |
| |
| In both the case of unquoted command line arguments or in calls |
| to C<glob()> VMS wildcard expansion is performed. (csh-style |
| wildcard expansion is available if you use C<File::Glob::glob>.) |
| If the wildcard filespec contains a device or directory |
| specification, then the resultant filespecs will also contain |
| a device and directory; otherwise, device and directory |
| information are removed. VMS-style resultant filespecs will |
| contain a full device and directory, while Unix-style |
| resultant filespecs will contain only as much of a directory |
| path as was present in the input filespec. For example, if |
| your default directory is Perl_Root:[000000], the expansion |
| of C<[.t]*.*> will yield filespecs like |
| "perl_root:[t]base.dir", while the expansion of C<t/*/*> will |
| yield filespecs like "t/base.dir". (This is done to match |
| the behavior of glob expansion performed by Unix shells.) |
| |
| Similarly, the resultant filespec will contain the file version |
| only if one was present in the input filespec. |
| |
| |
| =head2 Pipes |
| |
| Input and output pipes to Perl filehandles are supported; the |
| "file name" is passed to lib$spawn() for asynchronous |
| execution. You should be careful to close any pipes you have |
| opened in a Perl script, lest you leave any "orphaned" |
| subprocesses around when Perl exits. |
| |
| You may also use backticks to invoke a DCL subprocess, whose |
| output is used as the return value of the expression. The |
| string between the backticks is handled as if it were the |
| argument to the C<system> operator (see below). In this case, |
| Perl will wait for the subprocess to complete before continuing. |
| |
| The mailbox (MBX) that perl can create to communicate with a pipe |
| defaults to a buffer size of 8192 on 64-bit systems, 512 on VAX. The |
| default buffer size is adjustable via the logical name PERL_MBX_SIZE |
| provided that the value falls between 128 and the SYSGEN parameter |
| MAXBUF inclusive. For example, to set the mailbox size to 32767 use |
| C<$ENV{'PERL_MBX_SIZE'} = 32767;> and then open and use pipe constructs. |
| An alternative would be to issue the command: |
| |
| $ Define PERL_MBX_SIZE 32767 |
| |
| before running your wide record pipe program. A larger value may |
| improve performance at the expense of the BYTLM UAF quota. |
| |
| =head1 PERL5LIB and PERLLIB |
| |
| The PERL5LIB and PERLLIB logical names work as documented in L<perl>, |
| except that the element separator is '|' instead of ':'. The |
| directory specifications may use either VMS or Unix syntax. |
| |
| =head1 The Perl Forked Debugger |
| |
| The Perl forked debugger places the debugger commands and output in a |
| separate X-11 terminal window so that commands and output from multiple |
| processes are not mixed together. |
| |
| Perl on VMS supports an emulation of the forked debugger when Perl is |
| run on a VMS system that has X11 support installed. |
| |
| To use the forked debugger, you need to have the default display set to an |
| X-11 Server and some environment variables set that Unix expects. |
| |
| The forked debugger requires the environment variable C<TERM> to be C<xterm>, |
| and the environment variable C<DISPLAY> to exist. C<xterm> must be in |
| lower case. |
| |
| $define TERM "xterm" |
| |
| $define DISPLAY "hostname:0.0" |
| |
| Currently the value of C<DISPLAY> is ignored. It is recommended that it be set |
| to be the hostname of the display, the server and screen in Unix notation. In |
| the future the value of DISPLAY may be honored by Perl instead of using the |
| default display. |
| |
| It may be helpful to always use the forked debugger so that script I/O is |
| separated from debugger I/O. You can force the debugger to be forked by |
| assigning a value to the logical name <PERLDB_PIDS> that is not a process |
| identification number. |
| |
| $define PERLDB_PIDS XXXX |
| |
| |
| =head1 PERL_VMS_EXCEPTION_DEBUG |
| |
| The PERL_VMS_EXCEPTION_DEBUG being defined as "ENABLE" will cause the VMS |
| debugger to be invoked if a fatal exception that is not otherwise |
| handled is raised. The purpose of this is to allow debugging of |
| internal Perl problems that would cause such a condition. |
| |
| This allows the programmer to look at the execution stack and variables to |
| find out the cause of the exception. As the debugger is being invoked as |
| the Perl interpreter is about to do a fatal exit, continuing the execution |
| in debug mode is usually not practical. |
| |
| Starting Perl in the VMS debugger may change the program execution |
| profile in a way that such problems are not reproduced. |
| |
| The C<kill> function can be used to test this functionality from within |
| a program. |
| |
| In typical VMS style, only the first letter of the value of this logical |
| name is actually checked in a case insensitive mode, and it is considered |
| enabled if it is the value "T","1" or "E". |
| |
| This logical name must be defined before Perl is started. |
| |
| =head1 Command line |
| |
| =head2 I/O redirection and backgrounding |
| |
| Perl for VMS supports redirection of input and output on the |
| command line, using a subset of Bourne shell syntax: |
| |
| =over 4 |
| |
| =item * |
| |
| C<E<lt>file> reads stdin from C<file>, |
| |
| =item * |
| |
| C<E<gt>file> writes stdout to C<file>, |
| |
| =item * |
| |
| C<E<gt>E<gt>file> appends stdout to C<file>, |
| |
| =item * |
| |
| C<2E<gt>file> writes stderr to C<file>, |
| |
| =item * |
| |
| C<2E<gt>E<gt>file> appends stderr to C<file>, and |
| |
| =item * |
| |
| C<< 2>&1 >> redirects stderr to stdout. |
| |
| =back |
| |
| In addition, output may be piped to a subprocess, using the |
| character '|'. Anything after this character on the command |
| line is passed to a subprocess for execution; the subprocess |
| takes the output of Perl as its input. |
| |
| Finally, if the command line ends with '&', the entire |
| command is run in the background as an asynchronous |
| subprocess. |
| |
| =head2 Command line switches |
| |
| The following command line switches behave differently under |
| VMS than described in L<perlrun>. Note also that in order |
| to pass uppercase switches to Perl, you need to enclose |
| them in double-quotes on the command line, since the CRTL |
| downcases all unquoted strings. |
| |
| On newer 64 bit versions of OpenVMS, a process setting now |
| controls if the quoting is needed to preserve the case of |
| command line arguments. |
| |
| =over 4 |
| |
| =item -i |
| |
| If the C<-i> switch is present but no extension for a backup |
| copy is given, then inplace editing creates a new version of |
| a file; the existing copy is not deleted. (Note that if |
| an extension is given, an existing file is renamed to the backup |
| file, as is the case under other operating systems, so it does |
| not remain as a previous version under the original filename.) |
| |
| =item -S |
| |
| If the C<"-S"> or C<-"S"> switch is present I<and> the script |
| name does not contain a directory, then Perl translates the |
| logical name DCL$PATH as a searchlist, using each translation |
| as a directory in which to look for the script. In addition, |
| if no file type is specified, Perl looks in each directory |
| for a file matching the name specified, with a blank type, |
| a type of F<.pl>, and a type of F<.com>, in that order. |
| |
| =item -u |
| |
| The C<-u> switch causes the VMS debugger to be invoked |
| after the Perl program is compiled, but before it has |
| run. It does not create a core dump file. |
| |
| =back |
| |
| =head1 Perl functions |
| |
| As of the time this document was last revised, the following |
| Perl functions were implemented in the VMS port of Perl |
| (functions marked with * are discussed in more detail below): |
| |
| file tests*, abs, alarm, atan, backticks*, binmode*, bless, |
| caller, chdir, chmod, chown, chomp, chop, chr, |
| close, closedir, cos, crypt*, defined, delete, die, do, dump*, |
| each, endgrent, endpwent, eof, eval, exec*, exists, exit, exp, |
| fileno, flock getc, getgrent*, getgrgid*, getgrnam, getlogin, getppid, |
| getpwent*, getpwnam*, getpwuid*, glob, gmtime*, goto, |
| grep, hex, ioctl, import, index, int, join, keys, kill*, |
| last, lc, lcfirst, lchown*, length, link*, local, localtime, log, lstat, m//, |
| map, mkdir, my, next, no, oct, open, opendir, ord, pack, |
| pipe, pop, pos, print, printf, push, q//, qq//, qw//, |
| qx//*, quotemeta, rand, read, readdir, readlink*, redo, ref, rename, |
| require, reset, return, reverse, rewinddir, rindex, |
| rmdir, s///, scalar, seek, seekdir, select(internal), |
| select (system call)*, setgrent, setpwent, shift, sin, sleep, |
| socketpair, sort, splice, split, sprintf, sqrt, srand, stat, |
| study, substr, symlink*, sysread, system*, syswrite, tell, |
| telldir, tie, time, times*, tr///, uc, ucfirst, umask, |
| undef, unlink*, unpack, untie, unshift, use, utime*, |
| values, vec, wait, waitpid*, wantarray, warn, write, y/// |
| |
| The following functions were not implemented in the VMS port, |
| and calling them produces a fatal error (usually) or |
| undefined behavior (rarely, we hope): |
| |
| chroot, dbmclose, dbmopen, fork*, getpgrp, getpriority, |
| msgctl, msgget, msgsend, msgrcv, semctl, |
| semget, semop, setpgrp, setpriority, shmctl, shmget, |
| shmread, shmwrite, syscall |
| |
| The following functions are available on Perls compiled with Dec C |
| 5.2 or greater and running VMS 7.0 or greater: |
| |
| truncate |
| |
| The following functions are available on Perls built on VMS 7.2 or |
| greater: |
| |
| fcntl (without locking) |
| |
| The following functions may or may not be implemented, |
| depending on what type of socket support you've built into |
| your copy of Perl: |
| |
| accept, bind, connect, getpeername, |
| gethostbyname, getnetbyname, getprotobyname, |
| getservbyname, gethostbyaddr, getnetbyaddr, |
| getprotobynumber, getservbyport, gethostent, |
| getnetent, getprotoent, getservent, sethostent, |
| setnetent, setprotoent, setservent, endhostent, |
| endnetent, endprotoent, endservent, getsockname, |
| getsockopt, listen, recv, select(system call)*, |
| send, setsockopt, shutdown, socket |
| |
| The following function is available on Perls built on 64 bit OpenVMS v8.2 |
| with hard links enabled on an ODS-5 formatted build disk. CRTL support |
| is in principle available as of OpenVMS v7.3-1, and better configuration |
| support could detect this. |
| |
| link |
| |
| The following functions are available on Perls built on 64 bit OpenVMS |
| v8.2 and later. CRTL support is in principle available as of OpenVMS |
| v7.3-2, and better configuration support could detect this. |
| |
| getgrgid, getgrnam, getpwnam, getpwuid, |
| setgrent, ttyname |
| |
| The following functions are available on Perls built on 64 bit OpenVMS v8.2 |
| and later. |
| |
| statvfs, socketpair |
| |
| =over 4 |
| |
| =item File tests |
| |
| The tests C<-b>, C<-B>, C<-c>, C<-C>, C<-d>, C<-e>, C<-f>, |
| C<-o>, C<-M>, C<-s>, C<-S>, C<-t>, C<-T>, and C<-z> work as |
| advertised. The return values for C<-r>, C<-w>, and C<-x> |
| tell you whether you can actually access the file; this may |
| not reflect the UIC-based file protections. Since real and |
| effective UIC don't differ under VMS, C<-O>, C<-R>, C<-W>, |
| and C<-X> are equivalent to C<-o>, C<-r>, C<-w>, and C<-x>. |
| Similarly, several other tests, including C<-A>, C<-g>, C<-k>, |
| C<-l>, C<-p>, and C<-u>, aren't particularly meaningful under |
| VMS, and the values returned by these tests reflect whatever |
| your CRTL C<stat()> routine does to the equivalent bits in the |
| st_mode field. Finally, C<-d> returns true if passed a device |
| specification without an explicit directory (e.g. C<DUA1:>), as |
| well as if passed a directory. |
| |
| There are DECC feature logical names AND ODS-5 volume attributes that |
| also control what values are returned for the date fields. |
| |
| Note: Some sites have reported problems when using the file-access |
| tests (C<-r>, C<-w>, and C<-x>) on files accessed via DEC's DFS. |
| Specifically, since DFS does not currently provide access to the |
| extended file header of files on remote volumes, attempts to |
| examine the ACL fail, and the file tests will return false, |
| with C<$!> indicating that the file does not exist. You can |
| use C<stat> on these files, since that checks UIC-based protection |
| only, and then manually check the appropriate bits, as defined by |
| your C compiler's F<stat.h>, in the mode value it returns, if you |
| need an approximation of the file's protections. |
| |
| =item backticks |
| |
| Backticks create a subprocess, and pass the enclosed string |
| to it for execution as a DCL command. Since the subprocess is |
| created directly via C<lib$spawn()>, any valid DCL command string |
| may be specified. |
| |
| =item binmode FILEHANDLE |
| |
| The C<binmode> operator will attempt to insure that no translation |
| of carriage control occurs on input from or output to this filehandle. |
| Since this involves reopening the file and then restoring its |
| file position indicator, if this function returns FALSE, the |
| underlying filehandle may no longer point to an open file, or may |
| point to a different position in the file than before C<binmode> |
| was called. |
| |
| Note that C<binmode> is generally not necessary when using normal |
| filehandles; it is provided so that you can control I/O to existing |
| record-structured files when necessary. You can also use the |
| C<vmsfopen> function in the VMS::Stdio extension to gain finer |
| control of I/O to files and devices with different record structures. |
| |
| =item crypt PLAINTEXT, USER |
| |
| The C<crypt> operator uses the C<sys$hash_password> system |
| service to generate the hashed representation of PLAINTEXT. |
| If USER is a valid username, the algorithm and salt values |
| are taken from that user's UAF record. If it is not, then |
| the preferred algorithm and a salt of 0 are used. The |
| quadword encrypted value is returned as an 8-character string. |
| |
| The value returned by C<crypt> may be compared against |
| the encrypted password from the UAF returned by the C<getpw*> |
| functions, in order to authenticate users. If you're |
| going to do this, remember that the encrypted password in |
| the UAF was generated using uppercase username and |
| password strings; you'll have to upcase the arguments to |
| C<crypt> to insure that you'll get the proper value: |
| |
| sub validate_passwd { |
| my($user,$passwd) = @_; |
| my($pwdhash); |
| if ( !($pwdhash = (getpwnam($user))[1]) || |
| $pwdhash ne crypt("\U$passwd","\U$name") ) { |
| intruder_alert($name); |
| } |
| return 1; |
| } |
| |
| |
| =item die |
| |
| C<die> will force the native VMS exit status to be an SS$_ABORT code |
| if neither of the $! or $? status values are ones that would cause |
| the native status to be interpreted as being what VMS classifies as |
| SEVERE_ERROR severity for DCL error handling. |
| |
| When C<PERL_VMS_POSIX_EXIT> is active (see L</"$?"> below), the native VMS exit |
| status value will have either one of the C<$!> or C<$?> or C<$^E> or |
| the Unix value 255 encoded into it in a way that the effective original |
| value can be decoded by other programs written in C, including Perl |
| and the GNV package. As per the normal non-VMS behavior of C<die> if |
| either C<$!> or C<$?> are non-zero, one of those values will be |
| encoded into a native VMS status value. If both of the Unix status |
| values are 0, and the C<$^E> value is set one of ERROR or SEVERE_ERROR |
| severity, then the C<$^E> value will be used as the exit code as is. |
| If none of the above apply, the Unix value of 255 will be encoded into |
| a native VMS exit status value. |
| |
| Please note a significant difference in the behavior of C<die> in |
| the C<PERL_VMS_POSIX_EXIT> mode is that it does not force a VMS |
| SEVERE_ERROR status on exit. The Unix exit values of 2 through |
| 255 will be encoded in VMS status values with severity levels of |
| SUCCESS. The Unix exit value of 1 will be encoded in a VMS status |
| value with a severity level of ERROR. This is to be compatible with |
| how the VMS C library encodes these values. |
| |
| The minimum severity level set by C<die> in C<PERL_VMS_POSIX_EXIT> mode |
| may be changed to be ERROR or higher in the future depending on the |
| results of testing and further review. |
| |
| See L</"$?"> for a description of the encoding of the Unix value to |
| produce a native VMS status containing it. |
| |
| =item dump |
| |
| Rather than causing Perl to abort and dump core, the C<dump> |
| operator invokes the VMS debugger. If you continue to |
| execute the Perl program under the debugger, control will |
| be transferred to the label specified as the argument to |
| C<dump>, or, if no label was specified, back to the |
| beginning of the program. All other state of the program |
| (I<e.g.> values of variables, open file handles) are not |
| affected by calling C<dump>. |
| |
| =item exec LIST |
| |
| A call to C<exec> will cause Perl to exit, and to invoke the command |
| given as an argument to C<exec> via C<lib$do_command>. If the |
| argument begins with '@' or '$' (other than as part of a filespec), |
| then it is executed as a DCL command. Otherwise, the first token on |
| the command line is treated as the filespec of an image to run, and |
| an attempt is made to invoke it (using F<.Exe> and the process |
| defaults to expand the filespec) and pass the rest of C<exec>'s |
| argument to it as parameters. If the token has no file type, and |
| matches a file with null type, then an attempt is made to determine |
| whether the file is an executable image which should be invoked |
| using C<MCR> or a text file which should be passed to DCL as a |
| command procedure. |
| |
| =item fork |
| |
| While in principle the C<fork> operator could be implemented via |
| (and with the same rather severe limitations as) the CRTL C<vfork()> |
| routine, and while some internal support to do just that is in |
| place, the implementation has never been completed, making C<fork> |
| currently unavailable. A true kernel C<fork()> is expected in a |
| future version of VMS, and the pseudo-fork based on interpreter |
| threads may be available in a future version of Perl on VMS (see |
| L<perlfork>). In the meantime, use C<system>, backticks, or piped |
| filehandles to create subprocesses. |
| |
| =item getpwent |
| |
| =item getpwnam |
| |
| =item getpwuid |
| |
| These operators obtain the information described in L<perlfunc>, |
| if you have the privileges necessary to retrieve the named user's |
| UAF information via C<sys$getuai>. If not, then only the C<$name>, |
| C<$uid>, and C<$gid> items are returned. The C<$dir> item contains |
| the login directory in VMS syntax, while the C<$comment> item |
| contains the login directory in Unix syntax. The C<$gcos> item |
| contains the owner field from the UAF record. The C<$quota> |
| item is not used. |
| |
| =item gmtime |
| |
| The C<gmtime> operator will function properly if you have a |
| working CRTL C<gmtime()> routine, or if the logical name |
| SYS$TIMEZONE_DIFFERENTIAL is defined as the number of seconds |
| which must be added to UTC to yield local time. (This logical |
| name is defined automatically if you are running a version of |
| VMS with built-in UTC support.) If neither of these cases is |
| true, a warning message is printed, and C<undef> is returned. |
| |
| =item kill |
| |
| In most cases, C<kill> is implemented via the undocumented system |
| service C<$SIGPRC>, which has the same calling sequence as C<$FORCEX>, but |
| throws an exception in the target process rather than forcing it to call |
| C<$EXIT>. Generally speaking, C<kill> follows the behavior of the |
| CRTL's C<kill()> function, but unlike that function can be called from |
| within a signal handler. Also, unlike the C<kill> in some versions of |
| the CRTL, Perl's C<kill> checks the validity of the signal passed in and |
| returns an error rather than attempting to send an unrecognized signal. |
| |
| Also, negative signal values don't do anything special under |
| VMS; they're just converted to the corresponding positive value. |
| |
| =item qx// |
| |
| See the entry on C<backticks> above. |
| |
| =item select (system call) |
| |
| If Perl was not built with socket support, the system call |
| version of C<select> is not available at all. If socket |
| support is present, then the system call version of |
| C<select> functions only for file descriptors attached |
| to sockets. It will not provide information about regular |
| files or pipes, since the CRTL C<select()> routine does not |
| provide this functionality. |
| |
| =item stat EXPR |
| |
| Since VMS keeps track of files according to a different scheme |
| than Unix, it's not really possible to represent the file's ID |
| in the C<st_dev> and C<st_ino> fields of a C<struct stat>. Perl |
| tries its best, though, and the values it uses are pretty unlikely |
| to be the same for two different files. We can't guarantee this, |
| though, so caveat scriptor. |
| |
| =item system LIST |
| |
| The C<system> operator creates a subprocess, and passes its |
| arguments to the subprocess for execution as a DCL command. |
| Since the subprocess is created directly via C<lib$spawn()>, any |
| valid DCL command string may be specified. If the string begins with |
| '@', it is treated as a DCL command unconditionally. Otherwise, if |
| the first token contains a character used as a delimiter in file |
| specification (e.g. C<:> or C<]>), an attempt is made to expand it |
| using a default type of F<.Exe> and the process defaults, and if |
| successful, the resulting file is invoked via C<MCR>. This allows you |
| to invoke an image directly simply by passing the file specification |
| to C<system>, a common Unixish idiom. If the token has no file type, |
| and matches a file with null type, then an attempt is made to |
| determine whether the file is an executable image which should be |
| invoked using C<MCR> or a text file which should be passed to DCL |
| as a command procedure. |
| |
| If LIST consists of the empty string, C<system> spawns an |
| interactive DCL subprocess, in the same fashion as typing |
| B<SPAWN> at the DCL prompt. |
| |
| Perl waits for the subprocess to complete before continuing |
| execution in the current process. As described in L<perlfunc>, |
| the return value of C<system> is a fake "status" which follows |
| POSIX semantics unless the pragma C<use vmsish 'status'> is in |
| effect; see the description of C<$?> in this document for more |
| detail. |
| |
| =item time |
| |
| The value returned by C<time> is the offset in seconds from |
| 01-JAN-1970 00:00:00 (just like the CRTL's times() routine), in order |
| to make life easier for code coming in from the POSIX/Unix world. |
| |
| =item times |
| |
| The array returned by the C<times> operator is divided up |
| according to the same rules the CRTL C<times()> routine. |
| Therefore, the "system time" elements will always be 0, since |
| there is no difference between "user time" and "system" time |
| under VMS, and the time accumulated by a subprocess may or may |
| not appear separately in the "child time" field, depending on |
| whether C<times()> keeps track of subprocesses separately. Note |
| especially that the VAXCRTL (at least) keeps track only of |
| subprocesses spawned using C<fork()> and C<exec()>; it will not |
| accumulate the times of subprocesses spawned via pipes, C<system()>, |
| or backticks. |
| |
| =item unlink LIST |
| |
| C<unlink> will delete the highest version of a file only; in |
| order to delete all versions, you need to say |
| |
| 1 while unlink LIST; |
| |
| You may need to make this change to scripts written for a |
| Unix system which expect that after a call to C<unlink>, |
| no files with the names passed to C<unlink> will exist. |
| (Note: This can be changed at compile time; if you |
| C<use Config> and C<$Config{'d_unlink_all_versions'}> is |
| C<define>, then C<unlink> will delete all versions of a |
| file on the first call.) |
| |
| C<unlink> will delete a file if at all possible, even if it |
| requires changing file protection (though it won't try to |
| change the protection of the parent directory). You can tell |
| whether you've got explicit delete access to a file by using the |
| C<VMS::Filespec::candelete> operator. For instance, in order |
| to delete only files to which you have delete access, you could |
| say something like |
| |
| sub safe_unlink { |
| my($file,$num); |
| foreach $file (@_) { |
| next unless VMS::Filespec::candelete($file); |
| $num += unlink $file; |
| } |
| $num; |
| } |
| |
| (or you could just use C<VMS::Stdio::remove>, if you've installed |
| the VMS::Stdio extension distributed with Perl). If C<unlink> has to |
| change the file protection to delete the file, and you interrupt it |
| in midstream, the file may be left intact, but with a changed ACL |
| allowing you delete access. |
| |
| This behavior of C<unlink> is to be compatible with POSIX behavior |
| and not traditional VMS behavior. |
| |
| =item utime LIST |
| |
| This operator changes only the modification time of the file (VMS |
| revision date) on ODS-2 volumes and ODS-5 volumes without access |
| dates enabled. On ODS-5 volumes with access dates enabled, the |
| true access time is modified. |
| |
| =item waitpid PID,FLAGS |
| |
| If PID is a subprocess started by a piped C<open()> (see L<open>), |
| C<waitpid> will wait for that subprocess, and return its final status |
| value in C<$?>. If PID is a subprocess created in some other way (e.g. |
| SPAWNed before Perl was invoked), C<waitpid> will simply check once per |
| second whether the process has completed, and return when it has. (If |
| PID specifies a process that isn't a subprocess of the current process, |
| and you invoked Perl with the C<-w> switch, a warning will be issued.) |
| |
| Returns PID on success, -1 on error. The FLAGS argument is ignored |
| in all cases. |
| |
| =back |
| |
| =head1 Perl variables |
| |
| The following VMS-specific information applies to the indicated |
| "special" Perl variables, in addition to the general information |
| in L<perlvar>. Where there is a conflict, this information |
| takes precedence. |
| |
| =over 4 |
| |
| =item %ENV |
| |
| The operation of the C<%ENV> array depends on the translation |
| of the logical name F<PERL_ENV_TABLES>. If defined, it should |
| be a search list, each element of which specifies a location |
| for C<%ENV> elements. If you tell Perl to read or set the |
| element C<$ENV{>I<name>C<}>, then Perl uses the translations of |
| F<PERL_ENV_TABLES> as follows: |
| |
| =over 4 |
| |
| =item CRTL_ENV |
| |
| This string tells Perl to consult the CRTL's internal C<environ> |
| array of key-value pairs, using I<name> as the key. In most cases, |
| this contains only a few keys, but if Perl was invoked via the C |
| C<exec[lv]e()> function, as is the case for 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.) |
| |
| Don't try to clear C<%ENV> by saying C<%ENV = ();>, it will throw |
| a fatal error. This is equivalent to doing the following from DCL: |
| |
| DELETE/LOGICAL * |
| |
| You can imagine how bad things would be if, for example, the SYS$MANAGER |
| or SYS$SYSTEM logical names were deleted. |
| |
| At present, the first time you iterate over %ENV using |
| C<keys>, or C<values>, you will incur a time penalty as all |
| logical names are read, in order to fully populate %ENV. |
| Subsequent iterations will not reread logical names, so they |
| won't be as slow, but they also won't reflect any changes |
| to logical name tables caused by other programs. |
| |
| You do need to be careful with the logical names representing |
| process-permanent files, such as C<SYS$INPUT> and C<SYS$OUTPUT>. |
| The translations for these logical names are prepended with a |
| two-byte binary value (0x1B 0x00) that needs to be stripped off |
| if you wantto use it. (In previous versions of Perl it wasn't |
| possible to get the values of these logical names, as the null |
| byte acted as an end-of-string marker) |
| |
| =item $! |
| |
| The string value of C<$!> is that returned by the CRTL's |
| strerror() function, so it will include the VMS message for |
| VMS-specific errors. The numeric value of C<$!> is the |
| value of C<errno>, except if errno is EVMSERR, in which |
| case C<$!> contains the value of vaxc$errno. Setting C<$!> |
| always sets errno to the value specified. If this value is |
| EVMSERR, it also sets vaxc$errno to 4 (NONAME-F-NOMSG), so |
| that the string value of C<$!> won't reflect the VMS error |
| message from before C<$!> was set. |
| |
| =item $^E |
| |
| This variable provides direct access to VMS status values |
| in vaxc$errno, which are often more specific than the |
| generic Unix-style error messages in C<$!>. Its numeric value |
| is the value of vaxc$errno, and its string value is the |
| corresponding VMS message string, as retrieved by sys$getmsg(). |
| Setting C<$^E> sets vaxc$errno to the value specified. |
| |
| While Perl attempts to keep the vaxc$errno value to be current, if |
| errno is not EVMSERR, it may not be from the current operation. |
| |
| =item $? |
| |
| The "status value" returned in C<$?> is synthesized from the |
| actual exit status of the subprocess in a way that approximates |
| POSIX wait(5) semantics, in order to allow Perl programs to |
| portably test for successful completion of subprocesses. The |
| low order 8 bits of C<$?> are always 0 under VMS, since the |
| termination status of a process may or may not have been |
| generated by an exception. |
| |
| The next 8 bits contain the termination status of the program. |
| |
| If the child process follows the convention of C programs |
| compiled with the _POSIX_EXIT macro set, the status value will |
| contain the actual value of 0 to 255 returned by that program |
| on a normal exit. |
| |
| With the _POSIX_EXIT macro set, the Unix exit value of zero is |
| represented as a VMS native status of 1, and the Unix values |
| from 2 to 255 are encoded by the equation: |
| |
| VMS_status = 0x35a000 + (unix_value * 8) + 1. |
| |
| And in the special case of Unix value 1 the encoding is: |
| |
| VMS_status = 0x35a000 + 8 + 2 + 0x10000000. |
| |
| For other termination statuses, the severity portion of the |
| subprocess's exit status is used: if the severity was success or |
| informational, these bits are all 0; if the severity was |
| warning, they contain a value of 1; if the severity was |
| error or fatal error, they contain the actual severity bits, |
| which turns out to be a value of 2 for error and 4 for severe_error. |
| Fatal is another term for the severe_error status. |
| |
| As a result, C<$?> will always be zero if the subprocess's exit |
| status indicated successful completion, and non-zero if a |
| warning or error occurred or a program compliant with encoding |
| _POSIX_EXIT values was run and set a status. |
| |
| How can you tell the difference between a non-zero status that is |
| the result of a VMS native error status or an encoded Unix status? |
| You can not unless you look at the ${^CHILD_ERROR_NATIVE} value. |
| The ${^CHILD_ERROR_NATIVE} value returns the actual VMS status value |
| and check the severity bits. If the severity bits are equal to 1, |
| then if the numeric value for C<$?> is between 2 and 255 or 0, then |
| C<$?> accurately reflects a value passed back from a Unix application. |
| If C<$?> is 1, and the severity bits indicate a VMS error (2), then |
| C<$?> is from a Unix application exit value. |
| |
| In practice, Perl scripts that call programs that return _POSIX_EXIT |
| type status values will be expecting those values, and programs that |
| call traditional VMS programs will either be expecting the previous |
| behavior or just checking for a non-zero status. |
| |
| And success is always the value 0 in all behaviors. |
| |
| When the actual VMS termination status of the child is an error, |
| internally the C<$!> value will be set to the closest Unix errno |
| value to that error so that Perl scripts that test for error |
| messages will see the expected Unix style error message instead |
| of a VMS message. |
| |
| Conversely, when setting C<$?> in an END block, an attempt is made |
| to convert the POSIX value into a native status intelligible to |
| the operating system upon exiting Perl. What this boils down to |
| is that setting C<$?> to zero results in the generic success value |
| SS$_NORMAL, and setting C<$?> to a non-zero value results in the |
| generic failure status SS$_ABORT. See also L<perlport/exit>. |
| |
| With the C<PERL_VMS_POSIX_EXIT> logical name defined as "ENABLE", |
| setting C<$?> will cause the new value to be encoded into C<$^E> |
| so that either the original parent or child exit status values |
| 0 to 255 can be automatically recovered by C programs expecting |
| _POSIX_EXIT behavior. If both a parent and a child exit value are |
| non-zero, then it will be assumed that this is actually a VMS native |
| status value to be passed through. The special value of 0xFFFF is |
| almost a NOOP as it will cause the current native VMS status in the |
| C library to become the current native Perl VMS status, and is handled |
| this way as it is known to not be a valid native VMS status value. |
| It is recommend that only values in the range of normal Unix parent or |
| child status numbers, 0 to 255 are used. |
| |
| The pragma C<use vmsish 'status'> makes C<$?> reflect the actual |
| VMS exit status instead of the default emulation of POSIX status |
| described above. This pragma also disables the conversion of |
| non-zero values to SS$_ABORT when setting C<$?> in an END |
| block (but zero will still be converted to SS$_NORMAL). |
| |
| Do not use the pragma C<use vmsish 'status'> with C<PERL_VMS_POSIX_EXIT> |
| enabled, as they are at times requesting conflicting actions and the |
| consequence of ignoring this advice will be undefined to allow future |
| improvements in the POSIX exit handling. |
| |
| In general, with C<PERL_VMS_POSIX_EXIT> enabled, more detailed information |
| will be available in the exit status for DCL scripts or other native VMS tools, |
| and will give the expected information for Posix programs. It has not been |
| made the default in order to preserve backward compatibility. |
| |
| N.B. Setting C<DECC$FILENAME_UNIX_REPORT> implicitly enables |
| C<PERL_VMS_POSIX_EXIT>. |
| |
| =item $| |
| |
| Setting C<$|> for an I/O stream causes data to be flushed |
| all the way to disk on each write (I<i.e.> not just to |
| the underlying RMS buffers for a file). In other words, |
| it's equivalent to calling fflush() and fsync() from C. |
| |
| =back |
| |
| =head1 Standard modules with VMS-specific differences |
| |
| =head2 SDBM_File |
| |
| SDBM_File works properly on VMS. It has, however, one minor |
| difference. The database directory file created has a F<.sdbm_dir> |
| extension rather than a F<.dir> extension. F<.dir> files are VMS filesystem |
| directory files, and using them for other purposes could cause unacceptable |
| problems. |
| |
| =head1 Revision date |
| |
| Please see the git repository for revision history. |
| |
| =head1 AUTHOR |
| |
| Charles Bailey bailey@cor.newman.upenn.edu |
| Craig Berry craigberry@mac.com |
| Dan Sugalski dan@sidhe.org |
| John Malmberg wb8tyw@qsl.net |