diff options
author | Perl 5 Porters <perl5-porters@africa.nicoh.com> | 1997-02-18 13:22:00 +1200 |
---|---|---|
committer | Chip Salzenberg <chip@atlantic.net> | 1997-02-18 13:22:00 +1200 |
commit | ff0cee690d2ef6ba882e59dd4baaa0c944adb7a2 (patch) | |
tree | 91b3d734c5c24df3e5127c9974064d91ec428678 /vms | |
parent | f65adc383296c14b415f0ade0cf7fc4a27049a24 (diff) | |
download | perl-ff0cee690d2ef6ba882e59dd4baaa0c944adb7a2.tar.gz |
[inseparable changes from patch from perl5.003_26 to perl5.003_27]
BUILD PROCESS
Subject: Fix eval "" in Configure
Date: Fri, 14 Feb 1997 13:09:53 -0500
From: John L. Allen <allen@gateway.grumman.com>
Files: Configure
Subject: Re: Configure problem on IRIX - me dumb
p5p-msgid: <9702141809.AA17001@gateway.grumman.com>
Subject: Don't link with -lsfio if sfio is not requested
From: Chip Salzenberg <chip@perl.com>
Files: Configure
Subject: perl5.003_26 Configure change "win" for AIX 4
Date: Fri, 14 Feb 1997 13:59:02 -0600 (CST)
From: Tim Mooney <mooney@dogbert.cc.ndsu.NoDak.edu>
Files: Configure
p5p-msgid: <Pine.OSF.3.95.970214135751.32654A-100000@dogbert.cc.ndsu.NoDak.edu>
private-msgid: <Pine.OSF.3.95.970214135751.32654A-100000@dogbert.cc.ndsu.NoD
CORE LANGUAGE CHANGES
Subject: Better looks_like_number() function [sv.c]
Date: Fri, 14 Feb 1997 18:08:52 +0100
From: Gisle Aas <aas@bergen.sn.no>
Files: sv.c
Msg-ID: <199702141708.SAA17546@bergen.sn.no>
(applied based on p5p patch as commit 8dbaa58ee2aba7cc22d84199a674c58bbf108b46)
Subject: Remove redundant functions UNIVERSAL::{class,is_instance}
Date: 14 Feb 1997 15:52:21 +0000
From: Gisle Aas <aas@bergen.sn.no>
Files: pod/perldelta.pod pod/perlobj.pod t/op/universal.t universal.c
Msg-ID: <hwwsbpeq2.fsf@bergen.sn.no>
(applied based on p5p patch as commit 77bb9b23081b62119e8fbe9f5655b8802e4537ae)
Subject: Allow C<setpgrp $$>
Date: 16 Feb 1997 23:19:12 -0500
From: Roderick Schertler <roderick@gate.net>
Files: pp_sys.c
Msg-ID: <pzraigyshr.fsf@eeyore.ibcinc.com>
(applied based on p5p patch as commit 3d2573a84a1aa655d5da58c57b3fc20e04d40f9f)
Subject: Fix syntax error on C<&$1>
From: Chip Salzenberg <chip@perl.com>
Files: toke.c
Subject: Fix grep() with refs in array context
From: Chip Salzenberg <chip@perl.com>
Files: pp.c
CORE PORTABILITY
Subject: Eliminate $^S; add C<use vmsish qw(status exit time)>
Date: Mon, 17 Feb 1997 02:45:26 -0500 (EST)
From: Charles Bailey <bailey@HMIVAX.HUMGEN.UPENN.EDU>
Files: MANIFEST gv.c lib/English.pm lib/ExtUtils/MM_VMS.pm lib/ExtUtils/Mksymlists.pm lib/ExtUtils/xsubpp mg.c op.c perl.c perl.h pod/perldelta.pod pod/perlmod.pod pod/perlvar.pod pp_ctl.c pp_sys.c utils/perldoc.PL vms/Makefile vms/config.vms vms/descrip.mms vms/ext/Stdio/Stdio.pm vms/ext/Stdio/Stdio.xs vms/ext/XSSymSet.pm vms/ext/vmsish.pm vms/vms.c vms/vmsish.h win32/makedef.pl
private-msgid: <01IFI9CFKL0S004R2V@hmivax.humgen.upenn.edu>
LIBRARY AND EXTENSIONS
Subject: Remove Fatal.pm
From: Chip Salzenberg <chip@perl.com>
Files: MANIFEST lib/Fatal.pm pod/perldelta.pod pod/perlmod.pod pod/roffitall t/lib/fatal.t
Subject: Refresh MakeMaker to 5.40
From: Andy Dougherty <doughera@lafcol.lafayette.edu>
Files: lib/ExtUtils/Liblist.pm lib/ExtUtils/MM_Unix.pm lib/ExtUtils/MakeMaker.pm lib/ExtUtils/Mksymlists.pm
OTHER CORE CHANGES
Subject: Fix core dump when embedding
From: Chip Salzenberg <chip@perl.com>
Files: perl.c
Subject: Re: Fragile signals
Date: Thu, 13 Feb 1997 01:44:39 -0500 (EST)
From: Ilya Zakharevich <ilya@math.ohio-state.edu>
Files: mg.c
Msg-ID: <199702130644.BAA07572@monk.mps.ohio-state.edu>
(applied based on p5p patch as commit 09df8c7df7dfc9853902f1fdd8a6d95f53be66fc)
Subject: Make format strings correspond exactly to parameters
Date: 13 Feb 1997 17:24:31 -0500
From: Roderick Schertler <roderick@gate.net>
Files: doio.c ext/DB_File/DB_File.xs ext/Opcode/Opcode.xs gv.c op.c perl.c pp_ctl.c pp_sys.c regcomp.c toke.c
Msg-ID: <pz7mkc1h0g.fsf@eeyore.ibcinc.com>
(applied based on p5p patch as commit bf81aadd817bdea29720b072eef945df2da8463b)
Subject: Don't try to attach 'o' magic to read-only values
From: Chip Salzenberg <chip@perl.com>
Files: sv.c
Subject: Fix carriage-return message
From: Chip Salzenberg <chip@perl.com>
Files: toke.c
Subject: In <=>, test for equality first
From: Chip Salzenberg <chip@perl.com>
Files: pp.c
Subject: Don't mark sv_{true,false} PADTMP
From: Chip Salzenberg <chip@perl.com>
Files: op.c
Diffstat (limited to 'vms')
-rw-r--r-- | vms/Makefile | 37 | ||||
-rw-r--r-- | vms/config.vms | 9 | ||||
-rw-r--r-- | vms/descrip.mms | 39 | ||||
-rw-r--r-- | vms/ext/Stdio/Stdio.pm | 6 | ||||
-rw-r--r-- | vms/ext/Stdio/Stdio.xs | 10 | ||||
-rw-r--r-- | vms/ext/XSSymSet.pm | 239 | ||||
-rw-r--r-- | vms/ext/vmsish.pm | 76 | ||||
-rw-r--r-- | vms/test.com | 4 | ||||
-rw-r--r-- | vms/vms.c | 478 | ||||
-rw-r--r-- | vms/vmsish.h | 26 |
10 files changed, 695 insertions, 229 deletions
diff --git a/vms/Makefile b/vms/Makefile index d5e6553c59..c137113b7f 100644 --- a/vms/Makefile +++ b/vms/Makefile @@ -32,7 +32,7 @@ ARCH = VMS_VAX OBJVAL = $@ # Updated by fndvers.com -- do not edit by hand -PERL_VERSION = 5_00326# +PERL_VERSION = 5_00327# ARCHDIR = [.lib.$(ARCH).$(PERL_VERSION)] @@ -159,6 +159,9 @@ CRTLOPTS =,$(CRTL)/Options $(XSUBPP) $< >$(MMS$SOURCE_NAME).c $(CC) $(CFLAGS) $(MMS$SOURCE_NAME).c +# Modules which must be installed before we can build extensions +LIBPREREQ = $(ARCHDIR)Config.pm [.lib]DynaLoader.pm [.lib]vmsish.pm [.lib.VMS]Filespec.pm [.lib.ExtUtils]XSSymSet.pm + utils1 = [.lib.pod]perldoc.com [.lib.ExtUtils]Miniperl.pm [.utils]c2ph.com [.utils]h2ph.com [.utils]h2xs.com [.lib]perlbug.com utils2 = [.lib]splain.com [.utils]pl2pm.com @@ -168,7 +171,7 @@ base : miniperl perl @ $(NOOP) extras : Fcntl IO Opcode $(POSIX) libmods utils podxform @ $(NOOP) -libmods : [.lib]Config.pm $(ARCHDIR)Config.pm [.lib]DynaLoader.pm [.lib.VMS]Filespec.pm +libmods : $(LIBPREREQ) @ $(NOOP) utils : $(utils1) $(utils2) @ $(NOOP) @@ -178,12 +181,12 @@ x2p : [.x2p]a2p$(E) [.x2p]s2p.com [.x2p]find2perl.com @ $(NOOP) pod1 = [.lib.pod]perl.pod [.lib.pod]perlapio.pod [.lib.pod]perlbook.pod [.lib.pod]perlbot.pod [.lib.pod]perlcall.pod -pod2 = [.lib.pod]perldata.pod [.lib.pod]perldebug.pod [.lib.pod]perldiag.pod [.lib.pod]perldsc.pod +pod2 = [.lib.pod]perldata.pod [.lib.pod]perldebug.pod [.lib.pod]perldelta.pod [.lib.pod]perldiag.pod [.lib.pod]perldsc.pod pod3 = [.lib.pod]perlembed.pod [.lib.pod]perlform.pod [.lib.pod]perlfunc.pod [.lib.pod]perlguts.pod pod4 = [.lib.pod]perlipc.pod [.lib.pod]perllocale.pod [.lib.pod]perllol.pod [.lib.pod]perlmod.pod [.lib.pod]perlobj.pod -pod5 = [.lib.pod]perlop.pod [.lib.pod]perlpod.pod [.lib.pod]perlre.pod -pod6 = [.lib.pod]perlref.pod [.lib.pod]perlrun.pod [.lib.pod]perlsec.pod [.lib.pod]perlstyle.pod -pod7 = [.lib.pod]perlsub.pod [.lib.pod]perlsyn.pod [.lib.pod]perltie.pod [.lib.pod]perltoc.pod +pod5 = [.lib.pod]perlop.pod [.lib.pod]perlpod.pod [.lib.pod]perlre.pod [.lib.pod]perlref.pod [.lib.pod]perlrun.pod +pod6 = [.lib.pod]perlsec.pod [.lib.pod]perlstyle.pod [.lib.pod]perlsub.pod [.lib.pod]perlsyn.pod +pod7 = [.lib.pod]perltie.pod [.lib.pod]perltoc.pod [.lib.pod]perltoot.pod pod8 = [.lib.pod]perltrap.pod [.lib.pod]perlvar.pod [.lib.pod]perlxs.pod [.lib.pod]perlxstut.pod perlpods : $(pod1) $(pod2) $(pod3) $(pod4) $(pod5) $(pod6) $(pod7) $(pod8) [.lib.pod]perlvms.pod @@ -245,7 +248,7 @@ $(ARCHDIR)config.pm : [.lib]config.pm @ Delete/NoLog/NoConfirm genconfig.opt; $(MINIPERL) ConfigPM. -[.ext.dynaloader]dl_vms.c : [.ext.dynaloader]dl_vms.xs $(MINIPERL_EXE) +[.ext.dynaloader]dl_vms.c : [.ext.dynaloader]dl_vms.xs [.lib.ExtUtils]XSSymSet.pm $(MINIPERL_EXE) $(XSUBPP) [.ext.dynaloader]dl_vms.xs >$@ [.ext.dynaloader]dl_vms$(O) : [.ext.dynaloader]dl_vms.c @@ -284,7 +287,7 @@ Opcode : [.lib]Opcode.pm [.lib]ops.pm [.lib]Safe.pm [.lib.auto.Opcode]Opcode$(E) # Add "-I[--.lib]" t $(MINIPERL) so we use this copy of lib after C<chdir> # ${@} necessary to distract different versions of MM[SK]/make -[.ext.Opcode]Makefile : [.ext.Opcode]Makefile.PL $(ARCHDIR)Config.pm [.lib.VMS]Filespec.pm [.lib]DynaLoader.pm $(DBG)perlshr$(E) +[.ext.Opcode]Makefile : [.ext.Opcode]Makefile.PL $(LIBPREREQ) $(DBG)perlshr$(E) $(MINIPERL) "-I[--.lib]" -e "chdir('[.ext.Opcode]') or die $!; do 'Makefile.PL'; print ${@} if ${@};" "INST_LIB=[--.lib]" "INST_ARCHLIB=[--.lib]" Fcntl : [.lib]Fcntl.pm [.lib.auto.Fcntl]Fcntl$(E) @@ -303,7 +306,7 @@ Fcntl : [.lib]Fcntl.pm [.lib.auto.Fcntl]Fcntl$(E) # Add "-I[--.lib]" t $(MINIPERL) so we use this copy of lib after C<chdir> # ${@} necessary to distract different versions of MM[SK]/make -[.ext.Fcntl]Makefile : [.ext.Fcntl]Makefile.PL $(ARCHDIR)Config.pm [.lib.VMS]Filespec.pm [.lib]DynaLoader.pm $(DBG)perlshr$(E) +[.ext.Fcntl]Makefile : [.ext.Fcntl]Makefile.PL $(LIBPREREQ) $(DBG)perlshr$(E) $(MINIPERL) "-I[--.lib]" -e "chdir('[.ext.Fcntl]') or die $!; do 'Makefile.PL'; print ${@} if ${@};" "INST_LIB=[--.lib]" "INST_ARCHLIB=[--.lib]" POSIX : [.lib]POSIX.pm [.lib.auto.POSIX]POSIX$(E) @@ -322,7 +325,7 @@ POSIX : [.lib]POSIX.pm [.lib.auto.POSIX]POSIX$(E) # Add "-I[--.lib]" t $(MINIPERL) so we use this copy of lib after C<chdir> # ${@} necessary to distract different versions of MM[SK]/make -[.ext.POSIX]Makefile : [.ext.POSIX]Makefile.PL $(ARCHDIR)Config.pm [.lib.VMS]Filespec.pm [.lib]DynaLoader.pm $(DBG)perlshr$(E) +[.ext.POSIX]Makefile : [.ext.POSIX]Makefile.PL $(LIBPREREQ) $(DBG)perlshr$(E) $(MINIPERL) "-I[--.lib]" -e "chdir('[.ext.POSIX]') or die $!; do 'Makefile.PL'; print ${@} if ${@};" "INST_LIB=[--.lib]" "INST_ARCHLIB=[--.lib]" IO : [.lib]IO.pm [.lib.IO]File.pm [.lib.IO]Handle.pm [.lib.IO]Pipe.pm [.lib.IO]Seekable.pm [.lib.IO]Socket.pm [.lib.auto.IO]IO$(E) @@ -371,13 +374,20 @@ IO : [.lib]IO.pm [.lib.IO]File.pm [.lib.IO]Handle.pm [.lib.IO]Pipe.pm [.lib.IO]S # Add "-I[--.lib]" t $(MINIPERL) so we use this copy of lib after C<chdir> # ${@} necessary to distract different versions of MM[SK]/make -[.ext.IO]Makefile : [.ext.IO]Makefile.PL $(ARCHDIR)Config.pm [.lib.VMS]Filespec.pm [.lib]DynaLoader.pm $(DBG)perlshr$(E) +[.ext.IO]Makefile : [.ext.IO]Makefile.PL $(LIBPREREQ) $(DBG)perlshr$(E) $(MINIPERL) "-I[--.lib]" -e "chdir('[.ext.IO]') or die $!; do 'Makefile.PL'; print ${@} if ${@};" "INST_LIB=[--.lib]" "INST_ARCHLIB=[--.lib]" +[.lib]vmsish.pm : [.vms.ext]vmsish.pm + Copy/Log/NoConfirm [.vms.ext]vmsish.pm $@ + [.lib.VMS]Filespec.pm : [.vms.ext]Filespec.pm @ If f$$Search("[.lib]VMS.Dir").eqs."" Then Create/Directory [.lib.VMS] Copy/Log/NoConfirm [.vms.ext]Filespec.pm $@ +[.lib.ExtUtils]XSSymSet.pm : [.vms.ext]XSSymSet.pm + @ If f$$Search("[.lib]VMS.Dir").eqs."" Then Create/Directory [.lib.VMS] + Copy/Log/NoConfirm [.vms.ext]XSSymSet.pm $@ + [.lib.pod]perldoc.com : [.utils]perldoc.PL $(ARCHDIR)Config.pm @ If f$$Search("[.lib]pod.dir").eqs."" Then Create/Directory [.lib.pod] $(MINIPERL) [.utils]perldoc.PL @@ -445,7 +455,7 @@ IO : [.lib]IO.pm [.lib.IO]File.pm [.lib.IO]Handle.pm [.lib.IO]Pipe.pm [.lib.IO]S $(MINIPERL) [.pod]pod2text.PL Rename/Log [.pod]pod2text.com $@ -preplibrary : $(MINIPERL_EXE) $(ARCHDIR)Config.pm [.lib]DynaLoader.pm [.lib.VMS]Filespec.pm $(SOCKPM) +preplibrary : $(MINIPERL_EXE) $(LIBPREREQ) $(SOCKPM) @ Write sys$$Output "Autosplitting Perl library . . ." @ Create/Directory [.lib.auto] @ $(MINIPERL) -e "use AutoSplit; autosplit_lib_modules(@ARGV)" [.lib]*.pm [.lib.*]*.pm @@ -1483,6 +1493,8 @@ tidy : cleanlis - If f$$Search("[.Lib]Socket.pm;-1").nes."" Then Purge/NoConfirm/Log [.Lib]Socket.pm - If f$$Search("[.Lib]Config.pm;-1").nes."" Then Purge/NoConfirm/Log [.Lib]Config.pm - If f$$Search("$(ARCHDIR)Config.pm;-1").nes."" Then Purge/NoConfirm/Log $(ARCHDIR)Config.pm + - If f$$Search("[.lib.ExtUtils]Miniperl.pm").nes."" Then Purge/NoConfirm/Log [.lib.ExtUtils]Miniperl.pm;* + - If f$$Search("[.lib.ExtUtils]XSSymSet.pm").nes."" Then Purge/NoConfirm/Log [.lib.ExtUtils]XSSymSet.pm;* - If f$$Search("[.Lib.VMS]*.*;-1").nes."" Then Purge/NoConfirm/Log [.Lib.VMS]*.* - If f$$Search("[.Lib.Pod]*.Pod;-1").nes."" Then Purge/NoConfirm/Log [.Lib.Pod]*.Pod - If f$$Search("$(ARCHCORE)*.*").nes."" Then Purge/NoConfirm/Log $(ARCHCORE)*.* @@ -1548,6 +1560,7 @@ realclean : clean - If f$$Search("[.x2p]*.com").nes."" Then Delete/NoConfirm/Log [.x2p]*.com;* - If f$$Search("$(ARCHDIR)Config.pm").nes."" Then Delete/NoConfirm/Log $(ARCHDIR)Config.pm;* - If f$$Search("[.lib.ExtUtils]Miniperl.pm").nes."" Then Delete/NoConfirm/Log [.lib.ExtUtils]Miniperl.pm;* + - If f$$Search("[.lib.ExtUtils]XSSymSet.pm").nes."" Then Delete/NoConfirm/Log [.lib.ExtUtils]XSSymSet.pm;* - If f$$Search("[.lib.pod]*.pod").nes."" Then Delete/NoConfirm/Log [.lib.pod]*.pod;* - If f$$Search("[.lib.pod]perldoc.com").nes."" Then Delete/NoConfirm/Log [.lib.pod]perldoc.com;* - If f$$Search("[.lib.pod]pod2*.com").nes."" Then Delete/NoConfirm/Log [.lib.pod]pod2*.com;* diff --git a/vms/config.vms b/vms/config.vms index 41f0fa56f8..76596afb3d 100644 --- a/vms/config.vms +++ b/vms/config.vms @@ -76,7 +76,7 @@ * when Perl is built. Please do not change it by hand; make * any changes to FndVers.Com instead. */ -#define ARCHLIB_EXP "/perl_root/lib/VMS_VAX/5_00326" /**/ +#define ARCHLIB_EXP "/perl_root/lib/VMS_VAX/5_00327" /**/ #define ARCHLIB ARCHLIB_EXP /*config-skip*/ /* ARCHNAME: @@ -114,17 +114,24 @@ */ #undef HAS_BCMP /**/ +#include <string.h> /* Check whether new DECC has #defined bcopy and bzero */ /* HAS_BCOPY: * This symbol is defined if the bcopy() routine is available to * copy blocks of memory. */ #undef HAS_BCOPY /**/ +#ifdef bcopy +# define HAS_BCOPY /*config-skip*/ +#endif /* HAS_BZERO: * This symbol is defined if the bzero() routine is available to * set a memory block to 0. */ #undef HAS_BZERO /**/ +#ifdef bzero +# define HAS_BZERO /*config-skip*/ +#endif /* CASTNEGFLOAT: * This symbol is defined if the C compiler can cast negative diff --git a/vms/descrip.mms b/vms/descrip.mms index c15db049e6..d3ac365eb2 100644 --- a/vms/descrip.mms +++ b/vms/descrip.mms @@ -65,7 +65,7 @@ OBJVAL = $(MMS$TARGET_NAME)$(O) .endif # Updated by fndvers.com -- do not edit by hand -PERL_VERSION = 5_00326# +PERL_VERSION = 5_00327# ARCHDIR = [.lib.$(ARCH).$(PERL_VERSION)] @@ -265,6 +265,9 @@ CRTLOPTS =,$(CRTL)/Options $(CC) $(CFLAGS) $(MMS$SOURCE_NAME).c .endif +# Modules which must be installed before we can build extensions +LIBPREREQ = $(ARCHDIR)Config.pm [.lib]DynaLoader.pm [.lib]vmsish.pm [.lib.VMS]Filespec.pm [.lib.ExtUtils]XSSymSet.pm + utils1 = [.lib.pod]perldoc.com [.lib.ExtUtils]Miniperl.pm [.utils]c2ph.com [.utils]h2ph.com [.utils]h2xs.com [.lib]perlbug.com utils2 = [.lib]splain.com [.utils]pl2pm.com @@ -274,7 +277,7 @@ base : miniperl perl @ $(NOOP) extras : Fcntl IO Opcode $(POSIX) libmods utils podxform @ $(NOOP) -libmods : [.lib]Config.pm $(ARCHDIR)Config.pm [.lib]DynaLoader.pm [.lib.VMS]Filespec.pm +libmods : $(LIBPREREQ) @ $(NOOP) utils : $(utils1) $(utils2) @ $(NOOP) @@ -284,12 +287,12 @@ x2p : [.x2p]a2p$(E) [.x2p]s2p.com [.x2p]find2perl.com @ $(NOOP) pod1 = [.lib.pod]perl.pod [.lib.pod]perlapio.pod [.lib.pod]perlbook.pod [.lib.pod]perlbot.pod [.lib.pod]perlcall.pod -pod2 = [.lib.pod]perldata.pod [.lib.pod]perldebug.pod [.lib.pod]perldiag.pod [.lib.pod]perldsc.pod +pod2 = [.lib.pod]perldata.pod [.lib.pod]perldebug.pod [.lib.pod]perldelta.pod [.lib.pod]perldiag.pod [.lib.pod]perldsc.pod pod3 = [.lib.pod]perlembed.pod [.lib.pod]perlform.pod [.lib.pod]perlfunc.pod [.lib.pod]perlguts.pod pod4 = [.lib.pod]perlipc.pod [.lib.pod]perllocale.pod [.lib.pod]perllol.pod [.lib.pod]perlmod.pod [.lib.pod]perlobj.pod -pod5 = [.lib.pod]perlop.pod [.lib.pod]perlpod.pod [.lib.pod]perlre.pod -pod6 = [.lib.pod]perlref.pod [.lib.pod]perlrun.pod [.lib.pod]perlsec.pod [.lib.pod]perlstyle.pod -pod7 = [.lib.pod]perlsub.pod [.lib.pod]perlsyn.pod [.lib.pod]perltie.pod [.lib.pod]perltoc.pod +pod5 = [.lib.pod]perlop.pod [.lib.pod]perlpod.pod [.lib.pod]perlre.pod [.lib.pod]perlref.pod [.lib.pod]perlrun.pod +pod6 = [.lib.pod]perlsec.pod [.lib.pod]perlstyle.pod [.lib.pod]perlsub.pod [.lib.pod]perlsyn.pod +pod7 = [.lib.pod]perltie.pod [.lib.pod]perltoc.pod [.lib.pod]perltoot.pod pod8 = [.lib.pod]perltrap.pod [.lib.pod]perlvar.pod [.lib.pod]perlxs.pod [.lib.pod]perlxstut.pod perlpods : $(pod1) $(pod2) $(pod3) $(pod4) $(pod5) $(pod6) $(pod7) $(pod8) [.lib.pod]perlvms.pod @@ -366,7 +369,7 @@ $(ARCHDIR)config.pm : [.lib]config.pm @ Delete/NoLog/NoConfirm genconfig.opt; $(MINIPERL) ConfigPM. -[.ext.dynaloader]dl_vms.c : [.ext.dynaloader]dl_vms.xs $(MINIPERL_EXE) +[.ext.dynaloader]dl_vms.c : [.ext.dynaloader]dl_vms.xs [.lib.ExtUtils]XSSymSet.pm $(MINIPERL_EXE) $(XSUBPP) $(MMS$SOURCE) >$(MMS$TARGET) [.ext.dynaloader]dl_vms$(O) : [.ext.dynaloader]dl_vms.c @@ -405,7 +408,7 @@ Opcode : [.lib]Opcode.pm [.lib]ops.pm [.lib]Safe.pm [.lib.auto.Opcode]Opcode$(E) # Add "-I[--.lib]" t $(MINIPERL) so we use this copy of lib after C<chdir> # ${@} necessary to distract different versions of MM[SK]/make -[.ext.Opcode]Descrip.MMS : [.ext.Opcode]Makefile.PL $(ARCHDIR)Config.pm [.lib.VMS]Filespec.pm [.lib]DynaLoader.pm $(DBG)perlshr$(E) +[.ext.Opcode]Descrip.MMS : [.ext.Opcode]Makefile.PL $(LIBPREREQ) $(DBG)perlshr$(E) $(MINIPERL) "-I[--.lib]" -e "chdir('[.ext.Opcode]') or die $!; do 'Makefile.PL'; print ${@} if ${@};" "INST_LIB=[--.lib]" "INST_ARCHLIB=[--.lib]" Fcntl : [.lib]Fcntl.pm [.lib.auto.Fcntl]Fcntl$(E) @@ -424,7 +427,7 @@ Fcntl : [.lib]Fcntl.pm [.lib.auto.Fcntl]Fcntl$(E) # Add "-I[--.lib]" t $(MINIPERL) so we use this copy of lib after C<chdir> # ${@} necessary to distract different versions of MM[SK]/make -[.ext.Fcntl]Descrip.MMS : [.ext.Fcntl]Makefile.PL $(ARCHDIR)Config.pm [.lib.VMS]Filespec.pm [.lib]DynaLoader.pm $(DBG)perlshr$(E) +[.ext.Fcntl]Descrip.MMS : [.ext.Fcntl]Makefile.PL $(LIBPREREQ) $(DBG)perlshr$(E) $(MINIPERL) "-I[--.lib]" -e "chdir('[.ext.Fcntl]') or die $!; do 'Makefile.PL'; print ${@} if ${@};" "INST_LIB=[--.lib]" "INST_ARCHLIB=[--.lib]" POSIX : [.lib]POSIX.pm [.lib.auto.POSIX]POSIX$(E) @@ -443,7 +446,7 @@ POSIX : [.lib]POSIX.pm [.lib.auto.POSIX]POSIX$(E) # Add "-I[--.lib]" t $(MINIPERL) so we use this copy of lib after C<chdir> # ${@} necessary to distract different versions of MM[SK]/make -[.ext.POSIX]Descrip.MMS : [.ext.POSIX]Makefile.PL $(ARCHDIR)Config.pm [.lib.VMS]Filespec.pm [.lib]DynaLoader.pm $(DBG)perlshr$(E) +[.ext.POSIX]Descrip.MMS : [.ext.POSIX]Makefile.PL $(LIBPREREQ) $(DBG)perlshr$(E) $(MINIPERL) "-I[--.lib]" -e "chdir('[.ext.POSIX]') or die $!; do 'Makefile.PL'; print ${@} if ${@};" "INST_LIB=[--.lib]" "INST_ARCHLIB=[--.lib]" IO : [.lib]IO.pm [.lib.IO]File.pm [.lib.IO]Handle.pm [.lib.IO]Pipe.pm [.lib.IO]Seekable.pm [.lib.IO]Socket.pm [.lib.auto.IO]IO$(E) @@ -492,13 +495,20 @@ IO : [.lib]IO.pm [.lib.IO]File.pm [.lib.IO]Handle.pm [.lib.IO]Pipe.pm [.lib.IO]S # Add "-I[--.lib]" t $(MINIPERL) so we use this copy of lib after C<chdir> # ${@} necessary to distract different versions of MM[SK]/make -[.ext.IO]Descrip.MMS : [.ext.IO]Makefile.PL $(ARCHDIR)Config.pm [.lib.VMS]Filespec.pm [.lib]DynaLoader.pm $(DBG)perlshr$(E) +[.ext.IO]Descrip.MMS : [.ext.IO]Makefile.PL $(LIBPREREQ) $(DBG)perlshr$(E) $(MINIPERL) "-I[--.lib]" -e "chdir('[.ext.IO]') or die $!; do 'Makefile.PL'; print ${@} if ${@};" "INST_LIB=[--.lib]" "INST_ARCHLIB=[--.lib]" +[.lib]vmsish.pm : [.vms.ext]vmsish.pm + Copy/Log/NoConfirm $(MMS$SOURCE) $(MMS$TARGET) + [.lib.VMS]Filespec.pm : [.vms.ext]Filespec.pm @ If F$Search("[.lib]VMS.Dir").eqs."" Then Create/Directory [.lib.VMS] Copy/Log/NoConfirm $(MMS$SOURCE) $(MMS$TARGET) +[.lib.ExtUtils]XSSymSet.pm : [.vms.ext]XSSymSet.pm + @ If F$Search("[.lib]VMS.Dir").eqs."" Then Create/Directory [.lib.VMS] + Copy/Log/NoConfirm $(MMS$SOURCE) $(MMS$TARGET) + [.lib.pod]perldoc.com : [.utils]perldoc.PL $(ARCHDIR)Config.pm @ If F$Search("[.lib]pod.dir").eqs."" Then Create/Directory [.lib.pod] $(MINIPERL) $(MMS$SOURCE) @@ -566,7 +576,7 @@ IO : [.lib]IO.pm [.lib.IO]File.pm [.lib.IO]Handle.pm [.lib.IO]Pipe.pm [.lib.IO]S $(MINIPERL) $(MMS$SOURCE) Rename/Log [.pod]pod2text.com $(MMS$TARGET) -preplibrary : $(MINIPERL_EXE) $(ARCHDIR)Config.pm [.lib]DynaLoader.pm [.lib.VMS]Filespec.pm $(SOCKPM) +preplibrary : $(MINIPERL_EXE) $(LIBPREREQ) $(SOCKPM) @ Write Sys$Output "Autosplitting Perl library . . ." @ Create/Directory [.lib.auto] @ $(MINIPERL) -e "use AutoSplit; autosplit_lib_modules(@ARGV)" [.lib]*.pm [.lib.*]*.pm @@ -720,7 +730,7 @@ $(SOCKOBJ) : $(SOCKC) $(SOCKH) [.ext.Socket]Socket$(O) : [.ext.Socket]Socket.c $(CC) $(CFLAGS) /Object=$(MMS$TARGET) $(MMS$SOURCE) -[.ext.Socket]Socket.c : [.ext.Socket]Socket.xs $(MINIPERL_EXE) +[.ext.Socket]Socket.c : [.ext.Socket]Socket.xs [.lib.ExtUtils]XSSymSet.pm $(MINIPERL_EXE) $(XSUBPP) $(MMS$SOURCE) >$(MMS$TARGET) .endif # !LINK_ONLY @@ -1639,6 +1649,8 @@ tidy : cleanlis - If F$Search("[.Lib]Socket.pm;-1").nes."" Then Purge/NoConfirm/Log [.Lib]Socket.pm - If F$Search("[.Lib]Config.pm;-1").nes."" Then Purge/NoConfirm/Log [.Lib]Config.pm - If F$Search("$(ARCHDIR)Config.pm;-1").nes."" Then Purge/NoConfirm/Log $(ARCHDIR)Config.pm + - If F$Search("[.lib.ExtUtils]Miniperl.pm").nes."" Then Purge/NoConfirm/Log [.lib.ExtUtils]Miniperl.pm;* + - If F$Search("[.lib.ExtUtils]XSSymSet.pm").nes."" Then Purge/NoConfirm/Log [.lib.ExtUtils]XSSymSet.pm;* - If F$Search("[.Lib.VMS]*.*;-1").nes."" Then Purge/NoConfirm/Log [.Lib.VMS]*.* - If F$Search("[.Lib.Pod]*.Pod;-1").nes."" Then Purge/NoConfirm/Log [.Lib.Pod]*.Pod - If F$Search("$(ARCHCORE)*.*").nes."" Then Purge/NoConfirm/Log $(ARCHCORE)*.* @@ -1714,6 +1726,7 @@ realclean : clean - If F$Search("[.x2p]*.com").nes."" Then Delete/NoConfirm/Log [.x2p]*.com;* - If F$Search("$(ARCHDIR)Config.pm").nes."" Then Delete/NoConfirm/Log $(ARCHDIR)Config.pm;* - If F$Search("[.lib.ExtUtils]Miniperl.pm").nes."" Then Delete/NoConfirm/Log [.lib.ExtUtils]Miniperl.pm;* + - If F$Search("[.lib.ExtUtils]XSSymSet.pm").nes."" Then Delete/NoConfirm/Log [.lib.ExtUtils]XSSymSet.pm;* - If F$Search("[.lib.pod]*.pod").nes."" Then Delete/NoConfirm/Log [.lib.pod]*.pod;* - If F$Search("[.lib.pod]perldoc.com").nes."" Then Delete/NoConfirm/Log [.lib.pod]perldoc.com;* - If F$Search("[.lib.pod]pod2*.com").nes."" Then Delete/NoConfirm/Log [.lib.pod]pod2*.com;* diff --git a/vms/ext/Stdio/Stdio.pm b/vms/ext/Stdio/Stdio.pm index ad16af366f..516e678e2c 100644 --- a/vms/ext/Stdio/Stdio.pm +++ b/vms/ext/Stdio/Stdio.pm @@ -1,8 +1,8 @@ # VMS::Stdio - VMS extensions to Perl's stdio calls # # Author: Charles Bailey bailey@genetics.upenn.edu -# Version: 2.01 -# Revised: 10-Dec-1996 +# Version: 2.02 +# Revised: 15-Feb-1997 package VMS::Stdio; @@ -12,7 +12,7 @@ use Carp '&croak'; use DynaLoader (); use Exporter (); -$VERSION = '2.01'; +$VERSION = '2.02'; @ISA = qw( Exporter DynaLoader IO::File ); @EXPORT = qw( &O_APPEND &O_CREAT &O_EXCL &O_NDELAY &O_NOWAIT &O_RDONLY &O_RDWR &O_TRUNC &O_WRONLY ); diff --git a/vms/ext/Stdio/Stdio.xs b/vms/ext/Stdio/Stdio.xs index 200268c7f1..b10fec0d48 100644 --- a/vms/ext/Stdio/Stdio.xs +++ b/vms/ext/Stdio/Stdio.xs @@ -1,8 +1,8 @@ /* VMS::Stdio - VMS extensions to stdio routines * - * Version: 2.0 + * Version: 2.02 * Author: Charles Bailey bailey@genetics.upenn.edu - * Revised: 28-Feb-1996 + * Revised: 15-Feb-1997 * */ @@ -127,7 +127,8 @@ flush(sv) CODE: FILE *fp = Nullfp; if (SvOK(sv)) fp = IoIFP(sv_2io(sv)); - ST(0) = fflush(fp) ? &sv_undef : &sv_yes; + if (fflush(fp)) { ST(0) = &sv_undef; } + else { clearerr(fp); ST(0) = &sv_yes; } char * getname(fp) @@ -157,7 +158,8 @@ sync(fp) FILE * fp PROTOTYPE: $ CODE: - ST(0) = fsync(fileno(fp)) ? &sv_undef : &sv_yes; + if (fsync(fileno(fp))) { ST(0) = &sv_undef; } + else { clearerr(fp); ST(0) = &sv_yes; } char * tmpnam() diff --git a/vms/ext/XSSymSet.pm b/vms/ext/XSSymSet.pm new file mode 100644 index 0000000000..868a303c01 --- /dev/null +++ b/vms/ext/XSSymSet.pm @@ -0,0 +1,239 @@ +package ExtUtils::XSSymSet; + +use Carp qw( &carp ); +use strict; +use vars qw( $VERSION ); +$VERSION = '1.0'; + + +sub new { + my($pkg,$maxlen,$silent) = @_; + $maxlen ||= 31; + $silent ||= 0; + my($obj) = { '__M@xLen' => $maxlen, '__S!lent' => $silent }; + bless $obj, $pkg; +} + + +sub trimsym { + my($self,$name,$maxlen,$silent) = @_; + + unless (defined $maxlen) { + if (ref $self) { $maxlen ||= $self->{'__M@xLen'}; } + $maxlen ||= 31; + } + unless (defined $silent) { + if (ref $self) { $silent ||= $self->{'__S!lent'}; } + $silent ||= 0; + } + return $name if (length $name <= $maxlen); + + my $trimmed = $name; + # First, just try to remove duplicated delimiters + $trimmed =~ s/__/_/g; + if (length $trimmed > $maxlen) { + # Next, all duplicated chars + $trimmed =~ s/(.)\1+/$1/g; + if (length $trimmed > $maxlen) { + my $squeezed = $trimmed; + my($xs,$prefix,$func) = $trimmed =~ /^(XS_)?(.*)_([^_]*)$/; + if (length $func <= 12) { # Try to preserve short function names + my $frac = int(length $prefix / (length $trimmed - $maxlen) + 0.5); + my $pat = '([^_])'; + if ($frac > 1) { $pat .= '[^A-Z_]{' . ($frac - 1) . '}'; } + $prefix =~ s/$pat/$1/g; + $squeezed = "$xs$prefix" . "_$func"; + if (length $squeezed > $maxlen) { + $pat =~ s/A-Z//; + $prefix =~ s/$pat/$1/g; + $squeezed = "$xs$prefix" . "_$func"; + } + } + else { + my $frac = int(length $trimmed / (length $trimmed - $maxlen) + 0.5); + my $pat = '([^_])'; + if ($frac > 1) { $pat .= '[^A-Z_]{' . ($frac - 1) . '}'; } + $squeezed = "$prefix$func"; + $squeezed =~ s/$pat/$1/g; + if (length "$xs$squeezed" > $maxlen) { + $pat =~ s/A-Z//; + $squeezed =~ s/$pat/$1/g; + } + $squeezed = "$xs$squeezed"; + } + if (length $squeezed <= $maxlen) { $trimmed = $squeezed; } + else { + my $frac = int((length $trimmed - $maxlen) / length $trimmed + 0.5); + my $pat = '(.).{$frac}'; + $trimmed =~ s/$pat/$1/g; + } + } + } + carp "Warning: long symbol $name\n\ttrimmed to $trimmed\n\t" unless $silent; + return $trimmed; +} + + +sub addsym { + my($self,$sym,$maxlen,$silent) = @_; + my $trimmed = $self->get_trimmed($sym); + + return $trimmed if defined $trimmed; + + $maxlen ||= $self->{'__M@xLen'} || 31; + $silent ||= $self->{'__S!lent'} || 0; + $trimmed = $self->trimsym($sym,$maxlen,1); + if (exists $self->{$trimmed}) { + my($i) = "00"; + $trimmed = $self->trimsym($sym,$maxlen-3,$silent); + while (exists $self->{"${trimmed}_$i"}) { $i++; } + carp "Warning: duplicate symbol $trimmed\n\tchanged to ${trimmed}_$i\n\t(original was $sym)\n\t" + unless $silent; + $trimmed .= "_$i"; + } + elsif (not $silent and $trimmed ne $sym) { + carp "Warning: long symbol $sym\n\ttrimmed to $trimmed\n\t"; + } + $self->{$trimmed} = $sym; + $self->{'__N+Map'}->{$sym} = $trimmed; + $trimmed; +} + + +sub delsym { + my($self,$sym) = @_; + my $trimmed = $self->{'__N+Map'}->{$sym}; + if (defined $trimmed) { + delete $self->{'__N+Map'}->{$sym}; + delete $self->{$trimmed}; + } + $trimmed; +} + + +sub get_trimmed { + my($self,$sym) = @_; + $self->{'__N+Map'}->{$sym}; +} + + +sub get_orig { + my($self,$trimmed) = @_; + $self->{$trimmed}; +} + + +sub all_orig { (keys %{$_[0]->{'__N+Map'}}); } +sub all_trimmed { (grep { /^\w+$/ } keys %{$_[0]}); } + +__END__ + +=head1 NAME + +VMS::XSSymSet - keep sets of symbol names palatable to the VMS linker + +=head1 SYNOPSIS + + use VMS::XSSymSet; + + $set = new VMS::XSSymSet; + while ($sym = make_symbol()) { $set->addsym($sym); } + foreach $safesym ($set->all_trimmed) { + print "Processing $safesym (derived from ",$self->get_orig($safesym),")\n"; + do_stuff($safesym); + } + + $safesym = VMS::XSSymSet->trimsym($onesym); + +=head1 DESCRIPTION + +Since the VMS linker distinguishes symbols based only on the first 31 +characters of their names, it is occasionally necessary to shorten +symbol names in order to avoid collisions. (This is especially true of +names generated by xsubpp, since prefixes generated by nested package +names can become quite long.) C<VMS::XSSymSet> provides functions to +shorten names in a consistent fashion, and to track a set of names to +insure that each is unique. While designed with F<xsubpp> in mind, it +may be used with any set of strings. + +This package supplies the following functions, all of which should be +called as methods. + +=over 4 + +=item new([$maxlen[,$silent]]) + +Creates an empty C<VMS::XSSymset> set of symbols. This function may be +called as a static method or via an existing object. If C<$maxlen> or +C<$silent> are specified, they are used as the defaults for maximum +name length and warning behavior in future calls to addsym() or +trimsym() via this object. + +=item addsym($name[,$maxlen[,$silent]]) + +Creates a symbol name from C<$name>, using the methods described +under trimsym(), which is unique in this set of symbols, and returns +the new name. C<$name> and its resultant are added to the set, and +any future calls to addsym() specifying the same C<$name> will return +the same result, regardless of the value of C<$maxlen> specified. +Unless C<$silent> is true, warnings are output if C<$name> had to be +trimmed or changed in order to avoid collision with an existing symbol +name. C<$maxlen> and C<$silent> default to the values specified when +this set of symbols was created. This method must be called via an +existing object. + +=item trimsym($name[,$maxlen[,$silent]]) + +Creates a symbol name C<$maxlen> or fewer characters long from +C<$name> and returns it. If C<$name> is too long, it first tries to +shorten it by removing duplicate characters, then by periodically +removing non-underscore characters, and finally, if necessary, by +periodically removing characters of any type. C<$maxlen> defaults +to 31. Unless C<$silent> is true, a warning is output if C<$name> +is altered in any way. This function may be called either as a +static method or via an existing object, but in the latter case no +check is made to insure that the resulting name is unique in the +set of symbols. + +=item delsym($name) + +Removes C<$name> from the set of symbols, where C<$name> is the +original symbol name passed previously to addsym(). If C<$name> +existed in the set of symbols, returns its "trimmed" equivalent, +otherwise returns C<undef>. This method must be called via an +existing object. + +=item get_orig($trimmed) + +Returns the original name which was trimmed to C<$trimmed> by a +previous call to addsym(), or C<undef> if C<$trimmed> does not +correspond to a member of this set of symbols. This method must be +called via an existing object. + +=item get_trimmed($name) + +Returns the trimmed name which was generated from C<$name> by a +previous call to addsym(), or C<undef> if C<$name> is not a member +of this set of symbols. This method must be called via an +existing object. + +=item all_orig() + +Returns a list containing all of the original symbol names +from this set. + +=item all_trimmed() + +Returns a list containing all of the trimmed symbol names +from this set. + +=back + +=head1 AUTHOR + +Charles Bailey E<lt>I<bailey@genetics.upenn.edu>E<gt> + +=head1 REVISION + +Last revised 14-Feb-1997, for Perl 5.004. + diff --git a/vms/ext/vmsish.pm b/vms/ext/vmsish.pm new file mode 100644 index 0000000000..851d576e79 --- /dev/null +++ b/vms/ext/vmsish.pm @@ -0,0 +1,76 @@ +package vmsish; + +=head1 NAME + +vmsish - Perl pragma to control VMS-specific language features + +=head1 SYNOPSIS + + use vmsish; + + use vmsish 'status'; # or '$?' + use vmsish 'exit'; + use vmsish 'time'; + + use vmsish; + no vmsish 'time'; + +=head1 DESCRIPTION + +If no import list is supplied, all possible VMS-specific features are +assumed. Currently, there are three VMS-specific features available: +'status' (a.k.a '$?'), 'exit', and 'time'. + +=over 6 + +=item C<vmsish status> + +This makes C<$?> and C<system> return the native VMS exit status +instead of emulating the POSIX exit status. + +=item C<vmsish exit> + +This makes C<exit 1> produce a successful exit (with status SS$_NORMAL), +instead of emulating UNIX exit(), which considers C<exit 1> to indicate +an error. As with the CRTL's exit() function, C<exit 0> is also mapped +to an exit status of SS$_NORMAL, and any other argument to exit() is +used directly as Perl's exit status. + +=item C<vmsish time> + +This makes all times relative to the local time zone, instead of the +default of Universal Time (a.k.a Greenwich Mean Time, or GMT). + +=back + +See L<perlmod/Pragmatic Modules>. + +=cut + +if ($^O ne 'VMS') { + require Carp; + Carp::croak("This isn't VMS"); +} + +sub bits { + my $bits = 0; + my $sememe; + foreach $sememe (@_) { + $bits |= 0x01000000, next if $sememe eq 'status' || $sememe eq '$?'; + $bits |= 0x02000000, next if $sememe eq 'exit'; + $bits |= 0x04000000, next if $sememe eq 'time'; + } + $bits; +} + +sub import { + shift; + $^H |= bits(@_ ? @_ : qw(status exit time)); +} + +sub unimport { + shift; + $^H &= ~ bits(@_ ? @_ : qw(status exit time)); +} + +1; diff --git a/vms/test.com b/vms/test.com index 72354d2823..50a98caf00 100644 --- a/vms/test.com +++ b/vms/test.com @@ -27,7 +27,7 @@ $ Copy/Log/NoConfirm [-]Perl'exe' []Perl. $ $! Make the environment look a little friendlier to tests which assume Unix $ cat = "Type" -$ Macro/NoDebug/Object=Echo.Obj Sys$Input +$ Macro/NoDebug/NoList/Object=Echo.Obj Sys$Input .title echo .psect data,wrt,noexe dsc: @@ -67,7 +67,7 @@ $ Macro/NoDebug/Object=Echo.Obj Sys$Input movl #1,r0 ret .end echo -$ Link/NoTrace/Exe=Echo.Exe Echo.Obj; +$ Link/NoMap/NoTrace/Exe=Echo.Exe Echo.Obj; $ Delete/Log/NoConfirm Echo.Obj;* $ echo = "$" + F$Parse("Echo.Exe") $ @@ -2,8 +2,8 @@ * * VMS-specific routines for perl5 * - * Last revised: 29-Jan-1997 by Charles Bailey bailey@genetics.upenn.edu - * Version: 5.3.24 + * Last revised: 15-Feb-1997 by Charles Bailey bailey@genetics.upenn.edu + * Version: 5.3.27 */ #include <acedef.h> @@ -453,163 +453,6 @@ kill_file(char *name) } /* end of kill_file() */ /*}}}*/ -/* my_utime - update modification time of a file - * calling sequence is identical to POSIX utime(), but under - * VMS only the modification time is changed; ODS-2 does not - * maintain access times. Restrictions differ from the POSIX - * definition in that the time can be changed as long as the - * caller has permission to execute the necessary IO$_MODIFY $QIO; - * no separate checks are made to insure that the caller is the - * owner of the file or has special privs enabled. - * Code here is based on Joe Meadows' FILE utility. - */ - -/* Adjustment from Unix epoch (01-JAN-1970 00:00:00.00) - * to VMS epoch (01-JAN-1858 00:00:00.00) - * in 100 ns intervals. - */ -static const long int utime_baseadjust[2] = { 0x4beb4000, 0x7c9567 }; - -/*{{{int my_utime(char *path, struct utimbuf *utimes)*/ -int my_utime(char *file, struct utimbuf *utimes) -{ - register int i; - long int bintime[2], len = 2, lowbit, unixtime, - secscale = 10000000; /* seconds --> 100 ns intervals */ - unsigned long int chan, iosb[2], retsts; - char vmsspec[NAM$C_MAXRSS+1], rsa[NAM$C_MAXRSS], esa[NAM$C_MAXRSS]; - struct FAB myfab = cc$rms_fab; - struct NAM mynam = cc$rms_nam; -#if defined (__DECC) && defined (__VAX) - /* VAX DEC C atrdef.h has unsigned type for pointer member atr$l_addr, - * at least through VMS V6.1, which causes a type-conversion warning. - */ -# pragma message save -# pragma message disable cvtdiftypes -#endif - struct atrdef myatr[2] = {{sizeof bintime, ATR$C_REVDATE, bintime}, {0,0,0}}; - struct fibdef myfib; -#if defined (__DECC) && defined (__VAX) - /* This should be right after the declaration of myatr, but due - * to a bug in VAX DEC C, this takes effect a statement early. - */ -# pragma message restore -#endif - struct dsc$descriptor fibdsc = {sizeof(myfib), DSC$K_DTYPE_Z, DSC$K_CLASS_S,(char *) &myfib}, - devdsc = {0,DSC$K_DTYPE_T, DSC$K_CLASS_S,0}, - fnmdsc = {0,DSC$K_DTYPE_T, DSC$K_CLASS_S,0}; - - if (file == NULL || *file == '\0') { - set_errno(ENOENT); - set_vaxc_errno(LIB$_INVARG); - return -1; - } - if (do_tovmsspec(file,vmsspec,0) == NULL) return -1; - - if (utimes != NULL) { - /* Convert Unix time (seconds since 01-JAN-1970 00:00:00.00) - * to VMS quadword time (100 nsec intervals since 01-JAN-1858 00:00:00.00). - * Since time_t is unsigned long int, and lib$emul takes a signed long int - * as input, we force the sign bit to be clear by shifting unixtime right - * one bit, then multiplying by an extra factor of 2 in lib$emul(). - */ - lowbit = (utimes->modtime & 1) ? secscale : 0; - unixtime = (long int) utimes->modtime; - unixtime >> 1; secscale << 1; - retsts = lib$emul(&secscale, &unixtime, &lowbit, bintime); - if (!(retsts & 1)) { - set_errno(EVMSERR); - set_vaxc_errno(retsts); - return -1; - } - retsts = lib$addx(bintime,utime_baseadjust,bintime,&len); - if (!(retsts & 1)) { - set_errno(EVMSERR); - set_vaxc_errno(retsts); - return -1; - } - } - else { - /* Just get the current time in VMS format directly */ - retsts = sys$gettim(bintime); - if (!(retsts & 1)) { - set_errno(EVMSERR); - set_vaxc_errno(retsts); - return -1; - } - } - - myfab.fab$l_fna = vmsspec; - myfab.fab$b_fns = (unsigned char) strlen(vmsspec); - myfab.fab$l_nam = &mynam; - mynam.nam$l_esa = esa; - mynam.nam$b_ess = (unsigned char) sizeof esa; - mynam.nam$l_rsa = rsa; - mynam.nam$b_rss = (unsigned char) sizeof rsa; - - /* Look for the file to be affected, letting RMS parse the file - * specification for us as well. I have set errno using only - * values documented in the utime() man page for VMS POSIX. - */ - retsts = sys$parse(&myfab,0,0); - if (!(retsts & 1)) { - set_vaxc_errno(retsts); - if (retsts == RMS$_PRV) set_errno(EACCES); - else if (retsts == RMS$_DIR) set_errno(ENOTDIR); - else set_errno(EVMSERR); - return -1; - } - retsts = sys$search(&myfab,0,0); - if (!(retsts & 1)) { - set_vaxc_errno(retsts); - if (retsts == RMS$_PRV) set_errno(EACCES); - else if (retsts == RMS$_FNF) set_errno(ENOENT); - else set_errno(EVMSERR); - return -1; - } - - devdsc.dsc$w_length = mynam.nam$b_dev; - devdsc.dsc$a_pointer = (char *) mynam.nam$l_dev; - - retsts = sys$assign(&devdsc,&chan,0,0); - if (!(retsts & 1)) { - set_vaxc_errno(retsts); - if (retsts == SS$_IVDEVNAM) set_errno(ENOTDIR); - else if (retsts == SS$_NOPRIV) set_errno(EACCES); - else if (retsts == SS$_NOSUCHDEV) set_errno(ENOTDIR); - else set_errno(EVMSERR); - return -1; - } - - fnmdsc.dsc$a_pointer = mynam.nam$l_name; - fnmdsc.dsc$w_length = mynam.nam$b_name + mynam.nam$b_type + mynam.nam$b_ver; - - memset((void *) &myfib, 0, sizeof myfib); -#ifdef __DECC - for (i=0;i<3;i++) myfib.fib$w_fid[i] = mynam.nam$w_fid[i]; - for (i=0;i<3;i++) myfib.fib$w_did[i] = mynam.nam$w_did[i]; - /* This prevents the revision time of the file being reset to the current - * time as a result of our IO$_MODIFY $QIO. */ - myfib.fib$l_acctl = FIB$M_NORECORD; -#else - for (i=0;i<3;i++) myfib.fib$r_fid_overlay.fib$w_fid[i] = mynam.nam$w_fid[i]; - for (i=0;i<3;i++) myfib.fib$r_did_overlay.fib$w_did[i] = mynam.nam$w_did[i]; - myfib.fib$r_acctl_overlay.fib$l_acctl = FIB$M_NORECORD; -#endif - retsts = sys$qiow(0,chan,IO$_MODIFY,iosb,0,0,&fibdsc,&fnmdsc,0,0,myatr,0); - _ckvmssts(sys$dassgn(chan)); - if (retsts & 1) retsts = iosb[0]; - if (!(retsts & 1)) { - set_vaxc_errno(retsts); - if (retsts == SS$_NOPRIV) set_errno(EACCES); - else set_errno(EVMSERR); - return -1; - } - - return 0; -} /* end of my_utime() */ -/*}}}*/ - static void create_mbx(unsigned short int *chan, struct dsc$descriptor_s *namdsc) { @@ -3231,56 +3074,285 @@ void my_endpwent() /*}}}*/ -/* my_gmtime - * If the CRTL has a real gmtime(), use it, else look for the logical - * name SYS$TIMEZONE_DIFFERENTIAL used by the native UTC routines on - * VMS >= 6.0. Can be manually defined under earlier versions of VMS - * to translate to the number of seconds which must be added to UTC - * to get to the local time of the system. - * Contributed by Chuck Lane <lane@duphy4.physics.drexel.edu> +/* Used for UTC calculation in my_gmtime(), my_localtime(), my_time(), + * my_utime(), and flex_stat(), all of which operate on UTC unless + * VMSISH_TIMES is true. + */ +/* method used to handle UTC conversions: + * 1 == CRTL gmtime(); 2 == SYS$TIMEZONE_DIFFERENTIAL; 3 == no correction */ +static int gmtime_emulation_type; +/* number of secs to add to UTC POSIX-style time to get local time */ +static long int utc_offset_secs; -/*{{{struct tm *my_gmtime(const time_t *time)*/ -/* We #defined 'gmtime' as 'my_gmtime' in vmsish.h. #undef it here - * so we can call the CRTL's routine to see if it works. +/* We #defined 'gmtime', 'localtime', and 'time' as 'my_gmtime' etc. + * in vmsish.h. #undef them here so we can call the CRTL routines + * directly. */ #undef gmtime -struct tm * -my_gmtime(const time_t *time) +#undef localtime +#undef time + +/* my_time(), my_localtime(), my_gmtime() + * By default traffic in UTC time values, suing CRTL gmtime() or + * SYS$TIMEZONE_DIFFERENTIAL to determine offset from local time zone. + * Contributed by Chuck Lane <lane@duphy4.physics.drexel.edu> + * Modified by Charles Bailey <bailey@genetics.upenn.edu> + */ + +/*{{{time_t my_time(time_t *timep)*/ +time_t my_time(time_t *timep) { - static int gmtime_emulation_type; - static long int utc_offset_secs; - char *p; time_t when; if (gmtime_emulation_type == 0) { + struct tm *tm_p; + time_t base = 15 * 86400; /* 15jan71; to avoid month ends */ + gmtime_emulation_type++; - when = 300000000; - if (gmtime(&when) == NULL) { /* CRTL gmtime() is just a stub */ + if ((tm_p = gmtime(&base)) == NULL) { /* CRTL gmtime() is a fake */ + char *off; + gmtime_emulation_type++; - if ((p = my_getenv("SYS$TIMEZONE_DIFFERENTIAL")) == NULL) + if ((off = my_getenv("SYS$TIMEZONE_DIFFERENTIAL")) == NULL) { gmtime_emulation_type++; - else - utc_offset_secs = atol(p); + warn("no UTC offset information; assuming local time is UTC"); + } + else { utc_offset_secs = atol(off); } + } + else { /* We've got a working gmtime() */ + struct tm gmt, local; + + gmt = *tm_p; + tm_p = localtime(&base); + local = *tm_p; + utc_offset_secs = (local.tm_mday - gmt.tm_mday) * 86400; + utc_offset_secs += (local.tm_hour - gmt.tm_hour) * 3600; + utc_offset_secs += (local.tm_min - gmt.tm_min) * 60; + utc_offset_secs += (local.tm_sec - gmt.tm_sec); } } - switch (gmtime_emulation_type) { - case 1: - return gmtime(time); - case 2: - when = *time - utc_offset_secs; - return localtime(&when); - default: - warn("gmtime not supported on this system"); - return NULL; - } + when = time(NULL); + if ( +# ifdef VMSISH_TIME + !VMSISH_TIME && +# endif + when != -1) when -= utc_offset_secs; + if (timep != NULL) *timep = when; + return when; + +} /* end of my_time() */ +/*}}}*/ + + +/*{{{struct tm *my_gmtime(const time_t *timep)*/ +struct tm * +my_gmtime(const time_t *timep) +{ + char *p; + time_t when; + + if (gmtime_emulation_type == 0) (void) my_time(NULL); /* Init UTC */ + + when = *timep; +# ifdef VMSISH_TIME + if (VMSISH_TIME) when -= utc_offset_secs; /* Input was local time */ +# endif + /* CRTL localtime() wants local time as input, so does no tz correction */ + return localtime(&when); + } /* end of my_gmtime() */ -/* Reset definition for later calls */ -#define gmtime(t) my_gmtime(t) /*}}}*/ +/*{{{struct tm *my_localtime(const time_t *timep)*/ +struct tm * +my_localtime(const time_t *timep) +{ + time_t when; + + if (gmtime_emulation_type == 0) (void) my_time(NULL); /* Init UTC */ + + when = *timep; +# ifdef VMSISH_TIME + if (!VMSISH_TIME) when += utc_offset_secs; /* Input was UTC */ +# endif + /* CRTL localtime() wants local time as input, so does no tz correction */ + return localtime(&when); + +} /* end of my_localtime() */ +/*}}}*/ + +/* Reset definitions for later calls */ +#define gmtime(t) my_gmtime(t) +#define localtime(t) my_localtime(t) +#define time(t) my_time(t) + + +/* my_utime - update modification time of a file + * calling sequence is identical to POSIX utime(), but under + * VMS only the modification time is changed; ODS-2 does not + * maintain access times. Restrictions differ from the POSIX + * definition in that the time can be changed as long as the + * caller has permission to execute the necessary IO$_MODIFY $QIO; + * no separate checks are made to insure that the caller is the + * owner of the file or has special privs enabled. + * Code here is based on Joe Meadows' FILE utility. + */ + +/* Adjustment from Unix epoch (01-JAN-1970 00:00:00.00) + * to VMS epoch (01-JAN-1858 00:00:00.00) + * in 100 ns intervals. + */ +static const long int utime_baseadjust[2] = { 0x4beb4000, 0x7c9567 }; + +/*{{{int my_utime(char *path, struct utimbuf *utimes)*/ +int my_utime(char *file, struct utimbuf *utimes) +{ + register int i; + long int bintime[2], len = 2, lowbit, unixtime, + secscale = 10000000; /* seconds --> 100 ns intervals */ + unsigned long int chan, iosb[2], retsts; + char vmsspec[NAM$C_MAXRSS+1], rsa[NAM$C_MAXRSS], esa[NAM$C_MAXRSS]; + struct FAB myfab = cc$rms_fab; + struct NAM mynam = cc$rms_nam; +#if defined (__DECC) && defined (__VAX) + /* VAX DEC C atrdef.h has unsigned type for pointer member atr$l_addr, + * at least through VMS V6.1, which causes a type-conversion warning. + */ +# pragma message save +# pragma message disable cvtdiftypes +#endif + struct atrdef myatr[2] = {{sizeof bintime, ATR$C_REVDATE, bintime}, {0,0,0}}; + struct fibdef myfib; +#if defined (__DECC) && defined (__VAX) + /* This should be right after the declaration of myatr, but due + * to a bug in VAX DEC C, this takes effect a statement early. + */ +# pragma message restore +#endif + struct dsc$descriptor fibdsc = {sizeof(myfib), DSC$K_DTYPE_Z, DSC$K_CLASS_S,(char *) &myfib}, + devdsc = {0,DSC$K_DTYPE_T, DSC$K_CLASS_S,0}, + fnmdsc = {0,DSC$K_DTYPE_T, DSC$K_CLASS_S,0}; + + if (file == NULL || *file == '\0') { + set_errno(ENOENT); + set_vaxc_errno(LIB$_INVARG); + return -1; + } + if (do_tovmsspec(file,vmsspec,0) == NULL) return -1; + + if (utimes != NULL) { + /* Convert Unix time (seconds since 01-JAN-1970 00:00:00.00) + * to VMS quadword time (100 nsec intervals since 01-JAN-1858 00:00:00.00). + * Since time_t is unsigned long int, and lib$emul takes a signed long int + * as input, we force the sign bit to be clear by shifting unixtime right + * one bit, then multiplying by an extra factor of 2 in lib$emul(). + */ + lowbit = (utimes->modtime & 1) ? secscale : 0; + unixtime = (long int) utimes->modtime; +# ifdef VMSISH_TIME + if (!VMSISH_TIME) { /* Input was UTC; convert to local for sys svc */ + if (!gmtime_emulation_type) (void) time(NULL); /* Initialize UTC */ + unixtime += utc_offset_secs; + } +# endif + unixtime >> 1; secscale << 1; + retsts = lib$emul(&secscale, &unixtime, &lowbit, bintime); + if (!(retsts & 1)) { + set_errno(EVMSERR); + set_vaxc_errno(retsts); + return -1; + } + retsts = lib$addx(bintime,utime_baseadjust,bintime,&len); + if (!(retsts & 1)) { + set_errno(EVMSERR); + set_vaxc_errno(retsts); + return -1; + } + } + else { + /* Just get the current time in VMS format directly */ + retsts = sys$gettim(bintime); + if (!(retsts & 1)) { + set_errno(EVMSERR); + set_vaxc_errno(retsts); + return -1; + } + } + + myfab.fab$l_fna = vmsspec; + myfab.fab$b_fns = (unsigned char) strlen(vmsspec); + myfab.fab$l_nam = &mynam; + mynam.nam$l_esa = esa; + mynam.nam$b_ess = (unsigned char) sizeof esa; + mynam.nam$l_rsa = rsa; + mynam.nam$b_rss = (unsigned char) sizeof rsa; + + /* Look for the file to be affected, letting RMS parse the file + * specification for us as well. I have set errno using only + * values documented in the utime() man page for VMS POSIX. + */ + retsts = sys$parse(&myfab,0,0); + if (!(retsts & 1)) { + set_vaxc_errno(retsts); + if (retsts == RMS$_PRV) set_errno(EACCES); + else if (retsts == RMS$_DIR) set_errno(ENOTDIR); + else set_errno(EVMSERR); + return -1; + } + retsts = sys$search(&myfab,0,0); + if (!(retsts & 1)) { + set_vaxc_errno(retsts); + if (retsts == RMS$_PRV) set_errno(EACCES); + else if (retsts == RMS$_FNF) set_errno(ENOENT); + else set_errno(EVMSERR); + return -1; + } + + devdsc.dsc$w_length = mynam.nam$b_dev; + devdsc.dsc$a_pointer = (char *) mynam.nam$l_dev; + + retsts = sys$assign(&devdsc,&chan,0,0); + if (!(retsts & 1)) { + set_vaxc_errno(retsts); + if (retsts == SS$_IVDEVNAM) set_errno(ENOTDIR); + else if (retsts == SS$_NOPRIV) set_errno(EACCES); + else if (retsts == SS$_NOSUCHDEV) set_errno(ENOTDIR); + else set_errno(EVMSERR); + return -1; + } + + fnmdsc.dsc$a_pointer = mynam.nam$l_name; + fnmdsc.dsc$w_length = mynam.nam$b_name + mynam.nam$b_type + mynam.nam$b_ver; + + memset((void *) &myfib, 0, sizeof myfib); +#ifdef __DECC + for (i=0;i<3;i++) myfib.fib$w_fid[i] = mynam.nam$w_fid[i]; + for (i=0;i<3;i++) myfib.fib$w_did[i] = mynam.nam$w_did[i]; + /* This prevents the revision time of the file being reset to the current + * time as a result of our IO$_MODIFY $QIO. */ + myfib.fib$l_acctl = FIB$M_NORECORD; +#else + for (i=0;i<3;i++) myfib.fib$r_fid_overlay.fib$w_fid[i] = mynam.nam$w_fid[i]; + for (i=0;i<3;i++) myfib.fib$r_did_overlay.fib$w_did[i] = mynam.nam$w_did[i]; + myfib.fib$r_acctl_overlay.fib$l_acctl = FIB$M_NORECORD; +#endif + retsts = sys$qiow(0,chan,IO$_MODIFY,iosb,0,0,&fibdsc,&fnmdsc,0,0,myatr,0); + _ckvmssts(sys$dassgn(chan)); + if (retsts & 1) retsts = iosb[0]; + if (!(retsts & 1)) { + set_vaxc_errno(retsts); + if (retsts == SS$_NOPRIV) set_errno(EACCES); + else set_errno(EVMSERR); + return -1; + } + + return 0; +} /* end of my_utime() */ +/*}}}*/ + /* * flex_stat, flex_fstat * basic stat, but gets it right when asked to stat @@ -3525,6 +3597,16 @@ flex_fstat(int fd, struct mystat *statbufp) if (!fstat(fd,(stat_t *) statbufp)) { if (statbufp == &statcache) *namecache == '\0'; statbufp->st_dev = encode_dev(statbufp->st_devnam); +# ifdef VMSISH_TIME + if (!VMSISH_TIME) { /* Return UTC instead of local time */ +# else + if (1) { +# endif + if (!gmtime_emulation_type) (void)time(NULL); + statbufp->st_mtime -= utc_offset_secs; + statbufp->st_atime -= utc_offset_secs; + statbufp->st_ctime -= utc_offset_secs; + } return 0; } return -1; @@ -3569,7 +3651,19 @@ flex_stat(char *fspec, struct mystat *statbufp) if (!retval && statbufp == &statcache) strcpy(namecache,fileified); } if (retval) retval = stat(fspec,(stat_t *) statbufp); - if (!retval) statbufp->st_dev = encode_dev(statbufp->st_devnam); + if (!retval) { + statbufp->st_dev = encode_dev(statbufp->st_devnam); +# ifdef VMSISH_TIME + if (!VMSISH_TIME) { /* Return UTC instead of local time */ +# else + if (1) { +# endif + if (!gmtime_emulation_type) (void)time(NULL); + statbufp->st_mtime -= utc_offset_secs; + statbufp->st_atime -= utc_offset_secs; + statbufp->st_ctime -= utc_offset_secs; + } + } return retval; } /* end of flex_stat() */ diff --git a/vms/vmsish.h b/vms/vmsish.h index ad3f1e10a5..cab319dc04 100644 --- a/vms/vmsish.h +++ b/vms/vmsish.h @@ -100,6 +100,8 @@ # define vmsreaddirversions Perl_vmsreaddirversions # define getredirection Perl_getredirection # define my_gmtime Perl_my_gmtime +# define my_localtime Perl_my_localtime +# define my_time Perl_my_time # define cando_by_name Perl_cando_by_name # define flex_fstat Perl_flex_fstat # define flex_stat Perl_flex_stat @@ -175,6 +177,21 @@ # define set_vaxc_errno(v) (vaxc$errno = (v)) #endif +/* Support for 'vmsish' behaviors enabled with C<use vmsish> pragma */ + +#define COMPLEX_STATUS 1 /* We track both "POSIX" and VMS values */ + +#define HINT_S_VMSISH 24 +#define HINT_M_VMSISH_STATUS 0x01000000 /* system, $? return VMS status */ +#define HINT_M_VMSISH_EXIT 0x02000000 /* exit(1) ==> SS$_NORMAL */ +#define HINT_M_VMSISH_TIME 0x04000000 /* times are local, not UTC */ +#define NATIVE_HINTS (hints >> HINT_S_VMSISH) /* used in op.c */ + +#define TEST_VMSISH(h) (curcop->op_private & ((h) >> HINT_S_VMSISH)) +#define VMSISH_STATUS TEST_VMSISH(HINT_M_VMSISH_STATUS) +#define VMSISH_EXIT TEST_VMSISH(HINT_M_VMSISH_EXIT) +#define VMSISH_TIME TEST_VMSISH(HINT_M_VMSISH_TIME) + /* Handy way to vet calls to VMS system services and RTL routines. */ #define _ckvmssts(call) STMT_START { register unsigned long int __ckvms_sts; \ if (!((__ckvms_sts=(call))&1)) { \ @@ -294,9 +311,12 @@ struct utimbuf { /* Prior to VMS 7.0, the CRTL gmtime() routine was a stub which always * returned NULL. Substitute our own routine, which uses the logical * SYS$TIMEZONE_DIFFERENTIAL, whcih the native UTC support routines - * in VMS 6.0 or later use.* + * in VMS 6.0 or later use. We also add shims for time() and localtime() + * so we can run on UTC by default. */ #define gmtime(t) my_gmtime(t) +#define localtime(t) my_localtime(t) +#define time(t) my_time(t) /* VMS doesn't use a real sys_nerr, but we need this when scanning for error * messages in text strings . . . @@ -489,7 +509,9 @@ long telldir _((DIR *)); void seekdir _((DIR *, long)); void closedir _((DIR *)); void vmsreaddirversions _((DIR *, int)); -struct tm *my_gmtime _((const time_t *)); +struct tm * my_gmtime _((const time_t *)); +struct tm * my_localtime _((const time_t *)); +time_t my_time _((time_t *)); I32 cando_by_name _((I32, I32, char *)); int flex_fstat _((int, struct stat *)); int flex_stat _((char *, struct stat *)); |