diff options
author | Perl 5 Porters <perl5-porters@africa.nicoh.com> | 1996-11-26 20:48:00 +1200 |
---|---|---|
committer | Chip Salzenberg <chip@atlantic.net> | 1996-11-26 20:48:00 +1200 |
commit | bbce6d69784bf43b0e69e8d312042d65f258af23 (patch) | |
tree | eb5810e67656c19b6fb34dd0160c9131f24f65d1 /vms | |
parent | 6d82b38436d2a39ffb7413e68ad91495cd645fff (diff) | |
download | perl-bbce6d69784bf43b0e69e8d312042d65f258af23.tar.gz |
[inseparable changes from patch from perl5.003_08 to perl5.003_09]
CORE LANGUAGE CHANGES
Subject: Lexical locales
From: Chip Salzenberg <chip@atlantic.net>
Files: too many to list
make effectiveness of locales depend on C<use locale>
Subject: Lexical scoping cleanup
From: Chip Salzenberg <chip@atlantic.net>
Files: many... but mostly perly.y and toke.c
tighten scoping of lexical variables, somewhat on the
new constructs and somewhat on the old
Subject: memory corruption / security bug in sysread,syswrite + patch
Date: Mon, 25 Nov 1996 21:46:31 +0200 (EET)
From: Jarkko Hietaniemi <jhi@cc.hut.fi>
Files: MANIFEST pod/perldiag.pod pod/perlfunc.pod pp_sys.c t/op/sysio.t
Msg-ID: <199611251946.VAA30459@alpha.hut.fi>
(applied based on p5p patch as commit d7090df90a9cb89c83787d916e40d92a616b146d)
DOCUMENTATION
Subject: perldiag documentation patch.
Date: Wed, 20 Nov 96 16:07:28 GMT
From: Paul Marquess <pmarquess@bfsec.bt.co.uk>
Files: pod/perldiag.pod
private-msgid: <9611201607.AA12729@claudius.bfsec.bt.co.uk>
Subject: a missing perldiag entry
Date: Thu, 21 Nov 1996 15:24:02 -0500
From: Gurusamy Sarathy <gsar@engin.umich.edu>
Files: pod/perldiag.pod
private-msgid: <199611212024.PAA15758@aatma.engin.umich.edu>
Subject: perlfunc patch
Date: Wed, 20 Nov 96 14:04:08 GMT
From: Paul Marquess <pmarquess@bfsec.bt.co.uk>
Files: pod/perlfunc.pod
Following on from the patch to make uc, lc etc default to $_ (as per
Camel II), here is a followup patch to perlfunc that documents the
change. I think I have documented all the other cases where $_
defaulting works as well.
p5p-msgid: <9611201404.AA12477@claudius.bfsec.bt.co.uk>
OTHER CORE CHANGES
Subject: Properly prototype safe{malloc,calloc,realloc,free}.
From: Chip Salzenberg <chip@atlantic.net>
Files: proto.h
Subject: UnixWare 2.1 fix for perl5.003_08 - cope with fp->_cnt < -1, allow debugging
Date: Wed, 20 Nov 1996 14:27:06 +0100
From: John Hughes <john@AtlanTech.COM>
Files: sv.c
UnixWare 2.1 has no fp->_base so most of the debugging stuff in sv_gets just
core dumps.
Also, for some unknown reason fp->_cnt is sometimes < -1, screwing up the
initial SvGROW in svgets.
Appart from that its io is std.
p5p-msgid: <01BBD6EE.E915C860@malvinas.AtlanTech.COM>
Subject: die -> croak
Date: Thu, 21 Nov 1996 16:11:21 -0500
From: Gurusamy Sarathy <gsar@engin.umich.edu>
Files: pp_ctl.c
private-msgid: <199611212111.QAA17070@aatma.engin.umich.edu>
Subject: Cleanup of {,un}pack('w').
From: Chip Salzenberg <chip@atlantic.net>
Files: pp.c
Subject: Cleanups from Ilya.
From: Chip Salzenberg <chip@atlantic.net>
Files: gv.c malloc.c pod/perlguts.pod pp_ctl.c
Subject: Fix for unpack('w') on 64-bit systems.
From: Chip Salzenberg <chip@atlantic.net>
Files: pp.c
Subject: Re: LC_NUMERIC support is ready + performance
Date: Mon, 25 Nov 1996 22:08:27 -0500 (EST)
From: Ilya Zakharevich <ilya@math.ohio-state.edu>
Files: sv.c
Chip Salzenberg writes:
>
> Having thought about the use of our own gcvt() and atof(), I've run
> away in horror. It's just too hairy.
>
> So I've implemented the only viable alternative I know of: Toggling
> LC_NUMERIC to/from "C" as needed.
>
> Patch follows.
>
> I think _09 is *very* close.
Since _09 is going to be alpha anyway, I reiterate my question:
Is there any reason to not include my hash/array performance
patches in _09?
Btw, here is the next performance patch. It makes PADTMP values
stealable too. I do not do by setting TEMP flags on them, since it
would be a very distributed patch, and it would break some places
which check for TEMP for some other reasons (yes, I checked ;-).
This patch decreases *twice* the memory usage of
perl -e '$a = "a" x 1e6; 1'
Enjoy,
p5p-msgid: <199611260308.WAA02677@monk.mps.ohio-state.edu>
Subject: Hash key sharing improvements from Ilya.
From: Chip Salzenberg <chip@atlantic.net>
Files: hv.c hv.h proto.h
Subject: Mortal stack pre-allocation from Ilya.
From: Chip Salzenberg <chip@atlantic.net>
Files: pp.c pp.h pp_ctl.c pp_hot.c pp_sys.c
PORTABILITY
Subject: VMS patches post-5.003_08
Date: Fri, 22 Nov 1996 18:16:31 -0500 (EST)
From: Charles Bailey <bailey@hmivax.humgen.upenn.edu>
Files: lib/ExtUtils/MM_Unix.pm lib/ExtUtils/MM_VMS.pm lib/ExtUtils/MakeMaker.pm lib/File/Path.pm mg.c pp_ctl.c utils/h2xs.PL vms/config.vms vms/descrip.mms vms/gen_shrfls.pl vms/genconfig.pl vms/perlvms.pod vms/vms.c vms/vmsish.h
Here're diffs to bring a base 5.003_08 up to the current VMS working
sources. Nearly all of the changes are VMS-specific, and comprise
miscellaneous bugfixes accumulated since 5.003_07, rather than any
particular problem with 5.003_08. I'm posting them here since some
of the patches change core files, and I'd like to insure that I
haven't accidentally created problems for anyone else.
With these and a couple of of the small patches already send to p5p,
5.003_08 builds clean and passes all tests under VMS.
Thanks, Chip, for all the work.
p5p-msgid: <1996Nov22.181631.1603238@hmivax.humgen.upenn.edu>
Diffstat (limited to 'vms')
-rw-r--r-- | vms/config.vms | 24 | ||||
-rw-r--r-- | vms/descrip.mms | 9 | ||||
-rw-r--r-- | vms/gen_shrfls.pl | 13 | ||||
-rw-r--r-- | vms/genconfig.pl | 2 | ||||
-rw-r--r-- | vms/perlvms.pod | 13 | ||||
-rw-r--r-- | vms/vms.c | 253 | ||||
-rw-r--r-- | vms/vmsish.h | 7 |
7 files changed, 217 insertions, 104 deletions
diff --git a/vms/config.vms b/vms/config.vms index 792c893b00..b8132add97 100644 --- a/vms/config.vms +++ b/vms/config.vms @@ -8,10 +8,10 @@ * GenConfig.pl when producing Config.pm. * * config.h for VMS - * Version: 5.003_07 + * Version: 5.003_08 */ -/* Configuration time: 22-Mar-1996 14:45 +/* Configuration time: 19-Nov-1996 23:34 * Configured by: Charles Bailey bailey@genetics.upenn.edu * Target system: 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_00307" /**/ +#define ARCHLIB_EXP "/perl_root/lib/VMS_VAX/5_00308" /**/ #define ARCHLIB ARCHLIB_EXP /*config-skip*/ /* CPPSTDIN: @@ -1117,6 +1117,24 @@ */ #undef HAS_STRCOLL /**/ +/* HAS_STRTOD: + * This symbol, if defined, indicates that the strtod routine is + * available to translate strings to doubles. + */ +#define HAS_STRTOD /**/ + +/* HAS_STRTOL: + * This symbol, if defined, indicates that the strtol routine is + * available to translate strings to integers. + */ +#define HAS_STRTOL /**/ + +/* HAS_STRTOUL: + * This symbol, if defined, indicates that the strtoul routine is + * available to translate strings to integers. + */ +#define HAS_STRTOUL /**/ + /* HAS_STRXFRM: * This symbol, if defined, indicates that the strxfrm() routine is * available to compare strings using collating information. diff --git a/vms/descrip.mms b/vms/descrip.mms index a162ad03bc..35e59ee53f 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_00307# +PERL_VERSION = 5_00308# ARCHDIR = [.lib.$(ARCH).$(PERL_VERSION)] @@ -1565,9 +1565,9 @@ cleanlis : - If F$Search("*.Map").nes."" Then Delete/NoConfirm/Log *.Map;* tidy : cleanlis - - If F$Search("*.Opt;-1").nes."" Then Purge/NoConfirm/Log *.Opt - - If F$Search("*$(O);-1").nes."" Then Purge/NoConfirm/Log *$(O) - - If F$Search("*$(E);-1").nes."" Then Purge/NoConfirm/Log *$(E) + - If F$Search("[...]*.Opt;-1").nes."" Then Purge/NoConfirm/Log [...]*.Opt + - If F$Search("[...]*$(O);-1").nes."" Then Purge/NoConfirm/Log [...]*$(O) + - If F$Search("[...]*$(E);-1").nes."" Then Purge/NoConfirm/Log [...]*$(E) - If F$Search("Config.H;-1").nes."" Then Purge/NoConfirm/Log Config.H - If F$Search("Config.SH;-1").nes."" Then Purge/NoConfirm/Log Config.SH - If F$Search("perly.c;-1").nes."" Then Purge/NoConfirm/Log perly.c @@ -1592,6 +1592,7 @@ tidy : cleanlis - 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)*.* - If F$Search("[.utils]*.;-1").nes."" Then Purge/NoConfirm/Log [.utils]*. + - If F$Search("[.lib]perlbug.;-1").nes."" Then Purge/NoConfirm/Log [.lib]perlbug. - If F$Search("[.lib.pod]*.;-1").nes."" Then Purge/NoConfirm/Log [.lib.pod]*. clean : tidy diff --git a/vms/gen_shrfls.pl b/vms/gen_shrfls.pl index 8753893b8d..c9f51ab992 100644 --- a/vms/gen_shrfls.pl +++ b/vms/gen_shrfls.pl @@ -330,7 +330,7 @@ if ($isvax) { print DRVR "\$ Set Verify\n"; print DRVR "\$ If F\$Search(\"$libperl\").eqs.\"\" Then Library/Object/Create $libperl\n"; do { - $incstr .= ",perlshr_gbl$marord"; + push(@symfiles,"perlshr_gbl$marord"); print DRVR "\$ Macro/NoDebug/Object=PerlShr_Gbl${marord}$objsuffix PerlShr_Gbl$marord.Mar\n"; print DRVR "\$ Library/Object/Replace/Log $libperl PerlShr_Gbl${marord}$objsuffix\n"; } while (--$marord); @@ -345,6 +345,17 @@ if ($isvax) { close DRVR; } +# Initial hack to permit building of compatible shareable images for a +# given version of Perl. +if ($ENV{PERLSHR_USE_GSMATCH}) { + my $major = int($] * 1000) & 0xFF; # range 0..255 + my $minor = int(($] * 1000 - $major) * 100 + 0.5) & 0xFF; # range 0..255 + print OPTBLD "GSMATCH=LEQUAL,$major,$minor\n"; + foreach (@symfiles) { + print OPTBLD "CLUSTER=\$\$TRANSFER_VECTOR,,,$_.$objsuffix\n"; + } +} +else { $incstr .= ',' . join(',',@symfiles); } # Include object modules and RTLs in options file # Linker wants /Include and /Library on different lines print OPTBLD "$libperl/Include=($incstr)\n"; diff --git a/vms/genconfig.pl b/vms/genconfig.pl index d2ab5777de..924fa08dc6 100644 --- a/vms/genconfig.pl +++ b/vms/genconfig.pl @@ -324,7 +324,7 @@ if (open(PL,"${outdir}patchlevel.h")) { else { warn "Can't read ${outdir}patchlevel.h - skipping 'PATCHLEVEL'"; } # simple pager support for perldoc -if (`most` =~ /IVVERB/) { +if (`most not..file` =~ /IVVERB/) { $pager = 'more'; if (`more nl:` =~ /IVVERB/) { $pager = 'type/page'; } } diff --git a/vms/perlvms.pod b/vms/perlvms.pod index b56d202a7b..e065b08baa 100644 --- a/vms/perlvms.pod +++ b/vms/perlvms.pod @@ -140,13 +140,16 @@ 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.Auto.>I<Arch>.I<Extname>F<]> directory of 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>, followed by the Perl version number, and I<Extname> -is the name of the extension, with each C<::> translated to C<.>). +F<VMS_AXP>, and I<Extname> is the name of the extension, with +each C<::> translated to C<.>). (See the MakeMaker documentation +for more details on installation options for extensions.) However, it can be manually placed in any of several locations: - - the F<[.Lib.Auto.>I<Extname>F<]> subdirectory of one of - the directories in C<@INC>, or + - the F<[.Lib.Auto.>I<Arch>I<$PVers>I<Extname>F<]> subdirectory + of one of the directories in C<@INC> (where I<PVers> + is the version of Perl you're using, as supplied in C<$]>, + with '.' converted to '_'), or - one of the directories in C<@INC>, or - a directory which the extensions Perl library module passes to the DynaLoader when asking it to map @@ -322,6 +322,7 @@ my_crypt(const char *textpasswd, const char *usrname) /*}}}*/ +static char *do_rmsexpand(char *, char *, int, char *, unsigned); static char *do_fileify_dirspec(char *, char *, int); static char *do_tovmsspec(char *, char *, int); @@ -353,7 +354,7 @@ do_rmdir(char *name) int kill_file(char *name) { - char vmsname[NAM$C_MAXRSS+1]; + char vmsname[NAM$C_MAXRSS+1], rspec[NAM$C_MAXRSS+1]; unsigned long int jpicode = JPI$_UIC, type = ACL$C_FILE; unsigned long int cxt = 0, aclsts, fndsts, rmsts = -1; struct dsc$descriptor_s fildsc = {0, DSC$K_DTYPE_T, DSC$K_CLASS_S, 0}; @@ -374,7 +375,12 @@ kill_file(char *name) lcklst[2] = {{sizeof newace, ACL$C_WLOCK_ACL, &newace, 0},{0,0,0,0}}, ulklst[2] = {{sizeof newace, ACL$C_UNLOCK_ACL, &newace, 0},{0,0,0,0}}; - if (!remove(name)) return 0; /* Can we just get rid of it? */ + /* Expand the input spec using RMS, since the CRTL remove() and + * system services won't do this by themselves, so we may miss + * a file "hiding" behind a logical name or search list. */ + if (do_tovmsspec(name,vmsname,0) == NULL) return -1; + if (do_rmsexpand(vmsname,rspec,1,NULL,0) == NULL) return -1; + if (!remove(rspec)) return 0; /* Can we just get rid of it? */ /* If not, can changing protections help? */ if (vaxc$errno != RMS$_PRV) return -1; @@ -383,9 +389,8 @@ kill_file(char *name) * to delete the file. */ _ckvmssts(lib$getjpi(&jpicode,0,0,&(oldace.myace$l_ident),0,0)); - if (do_tovmsspec(name,vmsname,0) == NULL) return -1; - fildsc.dsc$w_length = strlen(vmsname); - fildsc.dsc$a_pointer = vmsname; + fildsc.dsc$w_length = strlen(rspec); + fildsc.dsc$a_pointer = rspec; cxt = 0; newace.myace$l_ident = oldace.myace$l_ident; if (!((aclsts = sys$change_acl(0,&type,&fildsc,lcklst,0,0,0)) & 1)) { @@ -758,6 +763,28 @@ I32 my_pclose(FILE *fp) /* get here => no such pipe open */ croak("No such pipe open"); + /* If we were writing to a subprocess, insure that someone reading from + * the mailbox gets an EOF. It looks like a simple fclose() doesn't + * produce an EOF record in the mailbox. */ + if (info->mode != 'r') { + char devnam[NAM$C_MAXRSS+1], *cp; + unsigned long int chan, iosb[2], retsts, retsts2; + struct dsc$descriptor devdsc = {0, DSC$K_DTYPE_T, DSC$K_CLASS_S, devnam}; + + if (fgetname(info->fp,devnam)) { + /* It oughta be a mailbox, so fgetname should give just the device + * name, but just in case . . . */ + if ((cp = strrchr(devnam,':')) != NULL) *(cp+1) = '\0'; + devdsc.dsc$w_length = strlen(devnam); + _ckvmssts(sys$assign(&devdsc,&chan,0,0)); + retsts = sys$qiow(0,chan,IO$_WRITEOF,iosb,0,0,0,0,0,0,0,0); + if (retsts & 1) retsts = iosb[0]; + retsts2 = sys$dassgn(chan); /* Be sure to deassign the channel */ + if (retsts & 1) retsts = retsts2; + _ckvmssts(retsts); + } + else _ckvmssts(vaxc$errno); /* Should never happen */ + } PerlIO_close(info->fp); if (info->done) retsts = info->completion; @@ -844,6 +871,108 @@ my_gconvert(double val, int ndig, int trail, char *buf) } /*}}}*/ + +/*{{{char *do_rmsexpand(char *fspec, char *out, int ts, char *def, unsigned opts)*/ +/* Shortcut for common case of simple calls to $PARSE and $SEARCH + * to expand file specification. Allows for a single default file + * specification and a simple mask of options. If outbuf is non-NULL, + * it must point to a buffer at least NAM$C_MAXRSS bytes long, into which + * the resultant file specification is placed. If outbuf is NULL, the + * resultant file specification is placed into a static buffer. + * The third argument, if non-NULL, is taken to be a default file + * specification string. The fourth argument is unused at present. + * rmesexpand() returns the address of the resultant string if + * successful, and NULL on error. + */ +static char * +do_rmsexpand(char *filespec, char *outbuf, int ts, char *defspec, unsigned opts) +{ + static char __rmsexpand_retbuf[NAM$C_MAXRSS+1]; + char esa[NAM$C_MAXRSS], *cp, *out = NULL; + struct FAB myfab = cc$rms_fab; + struct NAM mynam = cc$rms_nam; + STRLEN speclen; + unsigned long int retsts, haslower = 0; + + if (!filespec || !*filespec) { + set_vaxc_errno(LIB$_INVARG); set_errno(EINVAL); + return NULL; + } + if (!outbuf) { + if (ts) out = New(7019,outbuf,NAM$C_MAXRSS+1,char); + else outbuf = __rmsexpand_retbuf; + } + + myfab.fab$l_fna = filespec; + myfab.fab$b_fns = strlen(filespec); + myfab.fab$l_nam = &mynam; + + if (defspec && *defspec) { + myfab.fab$l_dna = defspec; + myfab.fab$b_dns = strlen(defspec); + } + + mynam.nam$l_esa = esa; + mynam.nam$b_ess = sizeof esa; + mynam.nam$l_rsa = outbuf; + mynam.nam$b_rss = NAM$C_MAXRSS; + + retsts = sys$parse(&myfab,0,0); + if (!(retsts & 1)) { + if (retsts == RMS$_DNF || retsts == RMS$_DIR || + retsts == RMS$_DEV || retsts == RMS$_DEV) { + mynam.nam$b_nop |= NAM$M_SYNCHK; + retsts = sys$parse(&myfab,0,0); + if (retsts & 1) goto expanded; + } + if (out) Safefree(out); + set_vaxc_errno(retsts); + if (retsts == RMS$_PRV) set_errno(EACCES); + else if (retsts == RMS$_DEV) set_errno(ENODEV); + else if (retsts == RMS$_DIR) set_errno(ENOTDIR); + else set_errno(EVMSERR); + return NULL; + } + retsts = sys$search(&myfab,0,0); + if (!(retsts & 1) && retsts != RMS$_FNF) { + if (out) Safefree(out); + set_vaxc_errno(retsts); + if (retsts == RMS$_PRV) set_errno(EACCES); + else set_errno(EVMSERR); + return NULL; + } + + /* If the input filespec contained any lowercase characters, + * downcase the result for compatibility with Unix-minded code. */ + expanded: + for (out = myfab.fab$l_fna; *out; out++) + if (islower(*out)) { haslower = 1; break; } + if (mynam.nam$b_rsl) { out = outbuf; speclen = mynam.nam$b_rsl; } + else { out = esa; speclen = mynam.nam$b_esl; } + if (!(mynam.nam$l_fnb & NAM$M_EXP_VER) && + (!defspec || !*defspec || !strchr(myfab.fab$l_dna,';'))) + speclen = mynam.nam$l_ver - out; + /* If we just had a directory spec on input, $PARSE "helpfully" + * adds an empty name and type for us */ + if (mynam.nam$l_name == mynam.nam$l_type && + mynam.nam$l_ver == mynam.nam$l_type + 1 && + !(mynam.nam$l_fnb & NAM$M_EXP_NAME)) + speclen = mynam.nam$l_name - out; + out[speclen] = '\0'; + if (haslower) __mystrtolower(out); + + /* Have we been working with an expanded, but not resultant, spec? */ + if (!mynam.nam$b_rsl) strcpy(outbuf,esa); + return outbuf; +} +/*}}}*/ +/* External entry points */ +char *rmsexpand(char *spec, char *buf, char *def, unsigned opt) +{ return do_rmsexpand(spec,buf,0,def,opt); } +char *rmsexpand_ts(char *spec, char *buf, char *def, unsigned opt) +{ return do_rmsexpand(spec,buf,1,def,opt); } + + /* ** The following routines are provided to make life easier when ** converting among VMS-style and Unix-style directory specifications. @@ -3258,10 +3387,13 @@ cando_by_name(I32 bit, I32 effective, char *fname) } retsts = sys$check_access(&objtyp,&namdsc,&usrdsc,armlst); - if (retsts == SS$_NOPRIV || retsts == SS$_NOSUCHOBJECT || - retsts == RMS$_FNF || retsts == RMS$_DIR || - retsts == RMS$_DEV) { - set_errno(retsts == SS$_NOPRIV ? EACCES : ENOENT); set_vaxc_errno(retsts); + if (retsts == SS$_NOPRIV || retsts == SS$_NOSUCHOBJECT || + retsts == SS$_INVFILFOROP || retsts == RMS$_FNF || + retsts == RMS$_DIR || retsts == RMS$_DEV) { + set_vaxc_errno(retsts); + if (retsts == SS$_NOPRIV) set_errno(EACCES); + else if (retsts == SS$_INVFILFOROP) set_errno(EINVAL); + else set_errno(ENOENT); return FALSE; } if (retsts == SS$_NORMAL) { @@ -3309,10 +3441,8 @@ int flex_stat(char *fspec, struct mystat *statbufp) { char fileified[NAM$C_MAXRSS+1]; - int retval,myretval; - struct mystat tmpbuf; + int retval = -1; - if (statbufp == &statcache) do_tovmsspec(fspec,namecache,0); if (is_null_device(fspec)) { /* Fake a stat() for the null device */ memset(statbufp,0,sizeof *statbufp); @@ -3325,22 +3455,19 @@ flex_stat(char *fspec, struct mystat *statbufp) return 0; } - if (do_fileify_dirspec(fspec,fileified,0) == NULL) myretval = -1; - else { - myretval = stat(fileified,(stat_t *) &tmpbuf); - } - retval = stat(fspec,(stat_t *) statbufp); - if (!myretval) { - if (retval == -1) { - *statbufp = tmpbuf; - retval = 0; - } - else if (!retval) { /* Dir with same name. Substitute it. */ - statbufp->st_mode &= ~S_IFDIR; - statbufp->st_mode |= tmpbuf.st_mode & S_IFDIR; - strcpy(namecache,fileified); - } + /* Try for a directory name first. If fspec contains a filename without + * a type (e.g. sea:[dark.dark]water), and both sea:[wine.dark]water.dir + * and sea:[wine.dark]water. exist, we prefer the directory here. + * Similarly, sea:[wine.dark] returns the result for sea:[wine]dark.dir, + * not sea:[wine.dark]., if the latter exists. If the intended target is + * the file with null type, specify this by calling flex_stat() with + * a '.' at the end of fspec. + */ + if (do_fileify_dirspec(fspec,fileified,0) != NULL) { + retval = stat(fileified,(stat_t *) 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); return retval; @@ -3583,71 +3710,17 @@ void rmsexpand_fromperl(CV *cv) { dXSARGS; - char esa[NAM$C_MAXRSS], rsa[NAM$C_MAXRSS], *cp, *out; - struct FAB myfab = cc$rms_fab; - struct NAM mynam = cc$rms_nam; - STRLEN speclen; - unsigned long int retsts, haslower = 0; + char *fspec, *defspec = NULL, *rslt; - if (items > 2) croak("Usage: VMS::Filespec::rmsexpand(spec[,defspec])"); + if (!items || items > 2) + croak("Usage: VMS::Filespec::rmsexpand(spec[,defspec])"); + fspec = SvPV(ST(0),na); + if (!fspec || !*fspec) XSRETURN_UNDEF; + if (items == 2) defspec = SvPV(ST(1),na); - myfab.fab$l_fna = SvPV(ST(0),speclen); - myfab.fab$b_fns = speclen; - myfab.fab$l_nam = &mynam; - - if (items == 2) { - myfab.fab$l_dna = SvPV(ST(1),speclen); - myfab.fab$b_dns = speclen; - } - - mynam.nam$l_esa = esa; - mynam.nam$b_ess = sizeof esa; - mynam.nam$l_rsa = rsa; - mynam.nam$b_rss = sizeof rsa; - - retsts = sys$parse(&myfab,0,0); - if (!(retsts & 1)) { - if (retsts == RMS$_DNF || retsts == RMS$_DIR || - retsts == RMS$_DEV || retsts == RMS$_DEV) { - mynam.nam$b_nop |= NAM$M_SYNCHK; - retsts = sys$parse(&myfab,0,0); - if (retsts & 1) goto expanded; - } - set_vaxc_errno(retsts); - if (retsts == RMS$_PRV) set_errno(EACCES); - else if (retsts == RMS$_DEV) set_errno(ENODEV); - else if (retsts == RMS$_DIR) set_errno(ENOTDIR); - else set_errno(EVMSERR); - XSRETURN_UNDEF; - } - retsts = sys$search(&myfab,0,0); - if (!(retsts & 1) && retsts != RMS$_FNF) { - set_vaxc_errno(retsts); - if (retsts == RMS$_PRV) set_errno(EACCES); - else set_errno(EVMSERR); - XSRETURN_UNDEF; - } - - /* If the input filespec contained any lowercase characters, - * downcase the result for compatibility with Unix-minded code. */ - expanded: - for (out = myfab.fab$l_fna; *out; out++) - if (islower(*out)) { haslower = 1; break; } - if (mynam.nam$b_rsl) { out = rsa; speclen = mynam.nam$b_rsl; } - else { out = esa; speclen = mynam.nam$b_esl; } - if (!(mynam.nam$l_fnb & NAM$M_EXP_VER) && - (items == 1 || !strchr(myfab.fab$l_dna,';'))) - speclen = mynam.nam$l_ver - out; - /* If we just had a directory spec on input, $PARSE "helpfully" - * adds an empty name and type for us */ - if (mynam.nam$l_name == mynam.nam$l_type && - mynam.nam$l_ver == mynam.nam$l_type + 1 && - !(mynam.nam$l_fnb & NAM$M_EXP_NAME)) - speclen = mynam.nam$l_name - out; - out[speclen] = '\0'; - if (haslower) __mystrtolower(out); - - ST(0) = sv_2mortal(newSVpv(out, speclen)); + rslt = do_rmsexpand(fspec,NULL,1,defspec,0); + ST(0) = sv_newmortal(); + if (rslt != NULL) sv_usepvn(ST(0),rslt,strlen(rslt)); XSRETURN(1); } diff --git a/vms/vmsish.h b/vms/vmsish.h index a362374e1c..a7f4e8980a 100644 --- a/vms/vmsish.h +++ b/vms/vmsish.h @@ -51,6 +51,9 @@ #include <unixio.h> #include <unixlib.h> #include <file.h> /* it's not <sys/file.h>, so don't use I_SYS_FILE */ +#ifdef __DECC +# include <unistd.h> /* DECC has this; VAXC and gcc don't */ +#endif /* Our own contribution to PerlShr's global symbols . . . */ #ifdef EMBED @@ -64,6 +67,8 @@ # define do_rmdir Perl_do_rmdir # define kill_file Perl_kill_file # define my_utime Perl_my_utime +# define rmsexpand Perl_rmsexpand +# define rmsexpand_ts Perl_rmsexpand_ts # define fileify_dirspec Perl_fileify_dirspec # define fileify_dirspec_ts Perl_fileify_dirspec_ts # define pathify_dirspec Perl_pathify_dirspec @@ -413,6 +418,8 @@ char * my_gconvert _((double, int, int, char *)); int do_rmdir _((char *)); int kill_file _((char *)); int my_utime _((char *, struct utimbuf *)); +char * rmsexpand _((char *, char *, char *, unsigned)); +char * rmsexpand_ts _((char *, char *, char *, unsigned)); char * fileify_dirspec _((char *, char *)); char * fileify_dirspec_ts _((char *, char *)); char * pathify_dirspec _((char *, char *)); |