summaryrefslogtreecommitdiff
path: root/vms
diff options
context:
space:
mode:
authorPerl 5 Porters <perl5-porters@africa.nicoh.com>1996-11-26 20:48:00 +1200
committerChip Salzenberg <chip@atlantic.net>1996-11-26 20:48:00 +1200
commitbbce6d69784bf43b0e69e8d312042d65f258af23 (patch)
treeeb5810e67656c19b6fb34dd0160c9131f24f65d1 /vms
parent6d82b38436d2a39ffb7413e68ad91495cd645fff (diff)
downloadperl-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.vms24
-rw-r--r--vms/descrip.mms9
-rw-r--r--vms/gen_shrfls.pl13
-rw-r--r--vms/genconfig.pl2
-rw-r--r--vms/perlvms.pod13
-rw-r--r--vms/vms.c253
-rw-r--r--vms/vmsish.h7
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
diff --git a/vms/vms.c b/vms/vms.c
index 9a4b55e445..b6f163f868 100644
--- a/vms/vms.c
+++ b/vms/vms.c
@@ -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 *));