Re: [patch@35050] replace pathify_dirspec in VMS with new version

2008-12-07 Thread John E. Malmberg

John E. Malmberg wrote:
The mp_do_pathify_dirspec needed enhancements to more accurately parse 
VMS file specifications, and also to handle UNIX file specifications the 
same way that mp_do_tovmspath() does.


It was simpler to replace than to try to modify the existing routine.

In addition this is the start of fixing issues where routines can be 
called with a null thread context, by removing the thread context where 
it is not needed.


More patches will be following this.


An additional note, this patch may cause some tests in vmsfspec.t to 
fail.  That is because the old behavior of pathfiy_dirspec() was 
inconsistent with vmsify().


I am working on a new version of vmssfspec.t that handles both the 
traditional mode of perl and with the decc$efs_charset / 
decc$filename_unix_report modes activated.


-John
[EMAIL PROTECTED]
Personal Opinion Only


[patch@35055] VMS parsing not handling no-priv cases

2008-12-07 Thread John E. Malmberg
The VMS parsing routines were failing on files that the process 
currently did not have access to, instead of falling back to a syntax 
only check.


We may want to consider always falling back to a syntax only check as 
there may be more non-fatal return codes of these type.


-John
[EMAIL PROTECTED]
Personal Opinion Only
--- /ref2_root/perl/vms/vms.c   Sun Dec  7 08:47:36 2008
+++ vms/vms.c   Sun Dec  7 08:53:17 2008
@@ -5478,10 +5478,13 @@
 
 /* Could not find the file, try as syntax only if error is not fatal */
 rms_set_nam_nop(mynam, NAM$M_SYNCHK);
-if (retsts == RMS$_DNF || retsts == RMS$_DIR || retsts == RMS$_DEV) {
+if (retsts == RMS$_DNF ||
+ retsts == RMS$_DIR ||
+ retsts == RMS$_DEV ||
+ retsts == RMS$_PRV) {
   retsts = sys$parse(myfab,0,0);
   if (retsts  STS$K_SUCCESS) goto expanded;
-}  
+}
 
  /* Still could not parse the file specification */
 /*--*/
@@ -6047,7 +6050,9 @@
   for (cp = trndir; *cp; cp++)
 if (islower(*cp)) { haslower = 1; break; }
   if (!((sts = sys$parse(dirfab))  STS$K_SUCCESS)) {
-if ((dirfab.fab$l_sts == RMS$_DIR) || (dirfab.fab$l_sts == RMS$_DNF)) {
+if ((dirfab.fab$l_sts == RMS$_DIR) ||
+(dirfab.fab$l_sts == RMS$_DNF) ||
+(dirfab.fab$l_sts == RMS$_PRV)) {
  rms_set_nam_nop(dirnam, NAM$M_SYNCHK);
   sts = sys$parse(dirfab)  STS$K_SUCCESS;
 }


[patch@35055] vms.c unixify refactor

2008-12-07 Thread John E. Malmberg
This patch makes a version of unixify available for calling with out an 
implicit context, which is needed for threaded perl as several routines 
do not have a thread context.


This is the second of a multi-part conversion to remove access 
violations when internal perl warning and error routines, and memory 
allocation routines are called with a null pointer for the implicit context.


By removing the implicit context from these routines, it will cause a 
compile time error on threaded perl should one of the affected routines 
sneak back into this code.


Patches to do:

* Refactor tounixpath, (unixpath)

* Refactor fileify_dirspec (fileify)

* Refactor tovmsspec, (vmsify)

* Refactor rmsexpand

* Refactor all cases where a implicit context is not needed
  and fix cases where a null context is present not to call
  internal perl routines that will access violate.

* fgetname needs a wrapper, it is not returning the correct
  names when DECC$FILENAME_UNIX_REPORT is enabled.

This is all needed for me to proceed with the testing of VMS perl in a 
UNIX compatible mode.  Currently most of the tests are passing.


-John
[EMAIL PROTECTED]
Personal Opinion Only
--- /ref3_root/perl/vms/vms.c   Sun Dec  7 09:19:05 2008
+++ vms/vms.c   Sun Dec  7 09:35:46 2008
@@ -296,6 +296,8 @@
 static char *mp_do_tounixspec(pTHX_ const char *, char *, int, int *);
 static char *mp_do_pathify_dirspec(pTHX_ const char *dir,char *buf, int ts, 
int *);
 
+static char * int_tounixspec(const char *spec, char *buf, int * utf8_fl);
+
 /* see system service docs for $TRNLNM -- NOT the same as LNM$_MAX_INDEX */
 #define PERL_LNM_MAX_ALLOWED_INDEX 127
 
@@ -6733,300 +6735,367 @@
 char *Perl_pathify_dirspec_utf8_ts(pTHX_ const char *dir, char *buf, int 
*utf8_fl)
 { return do_pathify_dirspec(dir,buf,1,utf8_fl); }
 
+/* Internal tounixspec routine that does not use a thread context */
+static char *
+int_tounixspec(const char *spec, char *buf, int * utf8_fl) {
 
-/*{{{ char *tounixspec[_ts](char *spec, char *buf, int *)*/
-static char *mp_do_tounixspec(pTHX_ const char *spec, char *buf, int ts, int * 
utf8_fl)
-{
-  static char __tounixspec_retbuf[VMS_MAXRSS];
-  char *dirend, *rslt, *cp1, *cp3, *tmp;
-  const char *cp2;
-  int devlen, dirlen, retlen = VMS_MAXRSS;
-  int expand = 1; /* guarantee room for leading and trailing slashes */
-  unsigned short int trnlnm_iter_count;
-  int cmp_rslt;
-  if (utf8_fl != NULL)
-*utf8_fl = 0;
-
-  if (spec == NULL) return NULL;
-  if (strlen(spec)  (VMS_MAXRSS-1)) return NULL;
-  if (buf) rslt = buf;
-  else if (ts) {
-Newx(rslt, VMS_MAXRSS, char);
-  }
-  else rslt = __tounixspec_retbuf;
+char *dirend, *cp1, *cp3, *tmp;
+const char *cp2;
+int devlen, dirlen, retlen = VMS_MAXRSS;
+int expand = 1; /* guarantee room for leading and trailing slashes */
+unsigned short int trnlnm_iter_count;
+int cmp_rslt;
+if (utf8_fl != NULL)
+*utf8_fl = 0;
 
-  /* New VMS specific format needs translation
-   * glob passes filenames with trailing '\n' and expects this preserved.
-   */
-  if (decc_posix_compliant_pathnames) {
-if (strncmp(spec, \^UP^, 5) == 0) {
-  char * uspec;
-  char *tunix;
-  int tunix_len;
-  int nl_flag;
-
-  tunix = PerlMem_malloc(VMS_MAXRSS);
-  if (tunix == NULL) _ckvmssts(SS$_INSFMEM);
-  strcpy(tunix, spec);
-  tunix_len = strlen(tunix);
-  nl_flag = 0;
-  if (tunix[tunix_len - 1] == '\n') {
-   tunix[tunix_len - 1] = '\';
-   tunix[tunix_len] = '\0';
-   tunix_len--;
-   nl_flag = 1;
-  }
-  uspec = decc$translate_vms(tunix);
-  PerlMem_free(tunix);
-  if ((int)uspec  0) {
-   strcpy(rslt,uspec);
-   if (nl_flag) {
- strcat(rslt,\n);
-   }
-   else {
- /* If we can not translate it, makemaker wants as-is */
- strcpy(rslt, spec);
-   }
-   return rslt;
-  }
+if (vms_debug_fileify) {
+if (spec == NULL)
+fprintf(stderr, int_tounixspec: spec = NULL\n);
+else
+fprintf(stderr, int_tounixspec: spec = %s\n, spec);
+}
+
+if (spec == NULL) {
+set_errno(EINVAL);
+set_vaxc_errno(SS$_BADPARAM);
+return NULL;
+}
+if (strlen(spec)  (VMS_MAXRSS-1)) {
+set_errno(E2BIG);
+set_vaxc_errno(SS$_BUFFEROVF);
+return NULL;
 }
-  }
 
-  cmp_rslt = 0; /* Presume VMS */
-  cp1 = strchr(spec, '/');
-  if (cp1 == NULL)
-cmp_rslt = 0;
+/* New VMS specific format needs translation
+ * glob passes filenames with trailing '\n' and expects this preserved.
+ */
+if (decc_posix_compliant_pathnames) {
+if (strncmp(spec, \^UP^, 5) == 0) {
+char * uspec;
+char *tunix;
+int tunix_len;
+int nl_flag;
+
+tunix = PerlMem_malloc(VMS_MAXRSS);
+if (tunix == NULL)
+_ckvmssts_noperl(SS$_INSFMEM);
+strcpy(tunix, spec);
+

Re: [patch@35050] replace pathify_dirspec in VMS with new version

2008-12-07 Thread Craig A. Berry


On Dec 7, 2008, at 8:46 AM, John E. Malmberg wrote:


John E. Malmberg wrote:
The mp_do_pathify_dirspec needed enhancements to more accurately  
parse VMS file specifications, and also to handle UNIX file  
specifications the same way that mp_do_tovmspath() does.

It was simpler to replace than to try to modify the existing routine.
In addition this is the start of fixing issues where routines can  
be called with a null thread context, by removing the thread  
context where it is not needed.

More patches will be following this.


An additional note, this patch may cause some tests in vmsfspec.t to  
fail.  That is because the old behavior of pathfiy_dirspec() was  
inconsistent with vmsify().




Specifically:

not ok 92 - pathify('/__down_/__the_/__garden_/__path_.'): '/__down_/ 
__the_/__garden_/__path__/'

# Failed at [.lib]vmsfspec.t line 24
#  got '/__down_/__the_/__garden_/__path__/'
# expected ''
...
not ok 94 - pathify('/__down_/__the_/__garden_.__path_'): '/__down_/ 
__the_/__gardenpath_/'

# Failed at [.lib]vmsfspec.t line 24
#  got '/__down_/__the_/__gardenpath_/'
# expected ''
...
not ok 106 - pathify('__path_.notdir'): '__path__notdir/'
# Failed at [.lib]vmsfspec.t line 24
#  got '__path__notdir/'
# expected ''

I am working on a new version of vmssfspec.t that handles both the  
traditional mode of perl and with the decc$efs_charset / decc 
$filename_unix_report modes activated.




How does this plan address the failures above?

Craig A. Berry
mailto:[EMAIL PROTECTED]

... getting out of a sonnet is much more
 difficult than getting in.
 Brad Leithauser



Re: [patch@35050] replace pathify_dirspec in VMS with new version

2008-12-07 Thread Nicholas Clark
On Sun, Dec 07, 2008 at 08:46:52AM -0600, John E. Malmberg wrote:

 An additional note, this patch may cause some tests in vmsfspec.t to 
 fail.  That is because the old behavior of pathfiy_dirspec() was 
 inconsistent with vmsify().

On Sun, Dec 07, 2008 at 10:15:39AM -0600, John E. Malmberg wrote:

 This is all needed for me to proceed with the testing of VMS perl in a 
 UNIX compatible mode.  Currently most of the tests are passing.

My view (and on matters VMS specific I'm going to defer to Craig, if he
differs) is that if a needed change temporarily makes a known subset of
tests fail, then it should include a patch to make exactly those tests
TODO tests.

Else, whoever wants to apply it, or look at the code afterwards, has no idea
whether the tests they see failing are expected or unexpected.

If they don't know that tests are expected to fail, they waste time reporting
things that are actually known to be that way (temporarily)

And if they do know that tests are expected to fail, then they don't report
failures even if they are in unrelated areas.


Hence why I'd much prefer the list of these are expected to fail, and that
list to be supplied in code form.

Nicholas Clark


Re: [patch@35050] replace pathify_dirspec in VMS with new version

2008-12-07 Thread Craig A. Berry


On Dec 7, 2008, at 12:46 PM, John E. Malmberg wrote:


Nicholas Clark wrote:

On Sun, Dec 07, 2008 at 08:46:52AM -0600, John E. Malmberg wrote:
An additional note, this patch may cause some tests in vmsfspec.t  
to fail.  That is because the old behavior of pathfiy_dirspec()  
was inconsistent with vmsify().

On Sun, Dec 07, 2008 at 10:15:39AM -0600, John E. Malmberg wrote:
This is all needed for me to proceed with the testing of VMS perl  
in a UNIX compatible mode.  Currently most of the tests are passing.
My view (and on matters VMS specific I'm going to defer to Craig,  
if he
differs) is that if a needed change temporarily makes a known  
subset of
tests fail, then it should include a patch to make exactly those  
tests

TODO tests.


I don't differ, except what I think we're seeing here is a change in  
behavior, not temporary TODOs.



Point taken,

Attached is vms/ext/filespec.t that changes those tests to be passing.


The documentation for VMS::Filespec::pathify says, the file type and  
version, if specified, must be .DIR;1. For compatibility with Unix  
usage, the type and version may also be omitted.  The tests have  
enforced this behavior since before 5.004.  You're proposing to change  
the behavior so that a file type that is not .DIR is no longer  
considered a file type at all and the dot would then be considered  
part of the filename rather than the start of the type field.  That  
could easily break existing code and doesn't seem to me like the way  
to go.


Now if the dot is escaped and is thus unambiguously just an actual dot  
rather than a directory or file type delimiter that's a different  
story.  We should support and test for those cases, something like:


__path_^.actualdot pathify __path_.actualdot/



--- /rsync_root/perl/vms/ext/filespec.t Thu Mar 15 20:43:30 2007
+++ /ref1_root/perl/vms/ext/filespec.t  Sun Dec  7 12:35:53 2008
@@ -100,14 +100,14 @@
__down_:[__the_.__garden_]__path_  pathify __down_: 
[__the_.__garden_.__path_]
__down_:[__the_.__garden_]__path_. pathify # N.B. trailing . ==  
null type

__down_:[__the_]__garden_.__path_  pathify undef
-/__down_/__the_/__garden_/__path_. pathify # N.B. trailing .  
== null type

-/__down_/__the_/__garden_.__path_  pathify undef
+/__down_/__the_/__garden_/__path_. pathify /__down_/__the_/ 
__garden_/__path__/
+/__down_/__the_/__garden_.__path_  pathify /__down_/__the_/ 
__gardenpath_/

__down_:[__the_.__garden_]__path_.dir;2pathify #N.B. ;2
__path_pathify __path_/
/__down_/__the_/__garden_/.pathify /__down_/__the_/__garden_/./
/__down_/__the_/__garden_/..   pathify /__down_/__the_/__garden_/../
/__down_/__the_/__garden_/...  pathify /__down_/__the_/__garden_/.../
-__path_.notdir pathify undef
+__path_.notdir pathify __path__notdir/

# Both VMS/Unix and file/path conversions
__down_:[__the_.__garden_]__path_.dir;1unixpath/ 
__down_/__the_/__garden_/__path_/



Craig A. Berry
mailto:[EMAIL PROTECTED]

... getting out of a sonnet is much more
 difficult than getting in.
 Brad Leithauser



Re: [patch@35050] replace pathify_dirspec in VMS with new version

2008-12-07 Thread John E. Malmberg

Craig A. Berry wrote:


On Dec 7, 2008, at 12:46 PM, John E. Malmberg wrote:


Point taken,

Attached is vms/ext/filespec.t that changes those tests to be passing.


The documentation for VMS::Filespec::pathify says, the file type and 
version, if specified, must be .DIR;1. For compatibility with Unix 
usage, the type and version may also be omitted.  The tests have 
enforced this behavior since before 5.004.  You're proposing to change 
the behavior so that a file type that is not .DIR is no longer 
considered a file type at all and the dot would then be considered part 
of the filename rather than the start of the type field.  That could 
easily break existing code and doesn't seem to me like the way to go.


This is for UNIX format file specifications, which normally should not 
have a .dir on them when they are directories.


The new behavior is not inconsistent with the existing documentation, 
except that the old routine does not work for EFS characters.


Now if the dot is escaped and is thus unambiguously just an actual dot 
rather than a directory or file type delimiter that's a different 
story.  We should support and test for those cases, something like:


__path_^.actualdot pathify __path_.actualdot/


The '^' escape character is only present on VMS format file 
specifications.  With out any directory delimiter characters present, 
pathify assumes that this is a UNIX directory.


With a Unix directory syntax if .DIR is not present, the behavior of 
pathify would normally to be just put a '/' on the specification. 
Removing the .dir is needed because it may be present.


The following demonstrates the existing behavior is inconsistent:

$ perl -v

This is perl, v5.10.0 built for VMS_AXP

$ perl -e print VMS::Filespec::vmsify('foo/bar./')
[.foo.bar_]
$

$ perl -e print VMS::Filespec::vmspath('foo/bar.')
$
[Nothing output]

Those two sample one liners should have produced the same output.

$ define decc$efs_charset ENABLE
$ perl -e print VMS::Filespec::vmsify('foo/bar./')
[.foo.bar^.]

$ perl -e print VMS::Filespec::vmspath('foo/bar.')
$
[Nothing output]

As should these two examples.

So while it is change in behavior, the older tested behavior appears to 
be incorrect as it will cause file specifications that are accepted in 
other routines to be rejected.


I do not think this would be noticed in existing programs other than the 
test routines because such file specifications are rare on a VMS system, 
and that if someone had encountered one of them, they would have had to 
modify their perl program to not use pathify, unixpath, or vmspath.


-John
[EMAIL PROTECTED]
Personal Opinion Only


[patch@35055] vms.c vmsify refactor

2008-12-07 Thread John E. Malmberg
This patch makes a version of vmsify and vmspath available for calling 
with out an implicit context, which is needed for threaded perl as 
several routines do not have or need an implicit context.


This is the fourth of a multi-part conversion to remove access 
violations when internal perl warning and error routines, and memory 
allocation routines are called with a null pointer for the implicit context.


By removing the implicit context from these routines, it will cause a 
compile time error on threaded perl should one of the affected routines 
sneak back into this code.


-John
[EMAIL PROTECTED]
Personal Opinion Only
--- /ref5_root/perl/vms/vms.c   Sun Dec  7 14:10:15 2008
+++ vms/vms.c   Sun Dec  7 15:56:16 2008
@@ -296,7 +296,10 @@
 static char *mp_do_tounixspec(pTHX_ const char *, char *, int, int *);
 static char *mp_do_pathify_dirspec(pTHX_ const char *dir,char *buf, int ts, 
int *);
 
+static char *int_tovmsspec
+   (const char *path, char *buf, int dir_flag, int * utf8_flag);
 static char * int_tounixspec(const char *spec, char *buf, int * utf8_fl);
+static char * int_tovmspath(const char *path, char *buf, int * utf8_fl);
 
 /* see system service docs for $TRNLNM -- NOT the same as LNM$_MAX_INDEX */
 #define PERL_LNM_MAX_ALLOWED_INDEX 127
@@ -8107,58 +8110,65 @@
 }
 
 
+
 /*{{{ char *tovmsspec[_ts](char *path, char *buf, int * utf8_flag)*/
-static char *mp_do_tovmsspec
-   (pTHX_ const char *path, char *buf, int ts, int dir_flag, int * utf8_flag) {
-  static char __tovmsspec_retbuf[VMS_MAXRSS];
-  char *rslt, *dirend;
-  char *lastdot;
-  char *vms_delim;
-  register char *cp1;
-  const char *cp2;
-  unsigned long int infront = 0, hasdir = 1;
-  int rslt_len;
-  int no_type_seen;
-  char * v_spec, * r_spec, * d_spec, * n_spec, * e_spec, * vs_spec;
-  int sts, v_len, r_len, d_len, n_len, e_len, vs_len;
-
-  if (path == NULL) return NULL;
-  rslt_len = VMS_MAXRSS-1;
-  if (buf) rslt = buf;
-  else if (ts) Newx(rslt, VMS_MAXRSS, char);
-  else rslt = __tovmsspec_retbuf;
-
-  /* '.' and '..' are [] and [-] for a quick check */
-  if (path[0] == '.') {
-if (path[1] == '\0') {
-  strcpy(rslt,[]);
-  if (utf8_flag != NULL)
-   *utf8_flag = 0;
-  return rslt;
+static char *int_tovmsspec
+   (const char *path, char *buf, int dir_flag, int * utf8_flag) {
+char *dirend;
+char *lastdot;
+char *vms_delim;
+register char *cp1;
+const char *cp2;
+unsigned long int infront = 0, hasdir = 1;
+int rslt_len;
+int no_type_seen;
+char * v_spec, * r_spec, * d_spec, * n_spec, * e_spec, * vs_spec;
+int sts, v_len, r_len, d_len, n_len, e_len, vs_len;
+
+if (vms_debug_fileify) {
+if (path == NULL)
+fprintf(stderr, int_tovmsspec: path = NULL\n);
+else
+fprintf(stderr, int_tovmsspec: path = %s\n, path);
 }
-else {
-  if (path[1] == '.'  path[2] == '\0') {
-   strcpy(rslt,[-]);
-   if (utf8_flag != NULL)
-  *utf8_flag = 0;
-   return rslt;
-  }
+
+if (path == NULL) {
+set_errno(EINVAL);
+set_vaxc_errno(SS$_BADPARAM);
+return NULL;
 }
-  }
+rslt_len = VMS_MAXRSS-1;
 
-   /* Posix specifications are now a native VMS format */
-  /*--*/
+/* '.' and '..' are [] and [-] for a quick check */
+if (path[0] == '.') {
+if (path[1] == '\0') {
+strcpy(buf, []);
+if (utf8_flag != NULL)
+*utf8_flag = 0;
+return buf;
+} else {
+if (path[1] == '.'  path[2] == '\0') {
+strcpy(buf, [-]);
+if (utf8_flag != NULL)
+*utf8_flag = 0;
+return buf;
+}
+}
+}
+
+ /* Posix specifications are now a native VMS format */
+/*--*/
 #if __CRTL_VER = 8020  !defined(__VAX)
-  if (decc_posix_compliant_pathnames) {
-if (strncmp(path,\^UP^,5) == 0) {
-  posix_to_vmsspec_hardway(rslt, rslt_len, path, dir_flag, utf8_flag);
-  return rslt;
+if (decc_posix_compliant_pathnames) {
+if (strncmp(path,\^UP^,5) == 0) {
+posix_to_vmsspec_hardway(buf, rslt_len, path, dir_flag, utf8_flag);
+return buf;
+}
 }
-  }
 #endif
 
-  /* This is really the only way to see if this is already in VMS format */
-  sts = vms_split_path
+/* This is really the only way to see if this is already in VMS format */
+sts = vms_split_path
(path,
v_spec,
v_len,
@@ -8172,7 +8182,7 @@
e_len,
vs_spec,
vs_len);
-  if (sts == 0) {
+if (sts == 0) {
 /* FIX-ME - If dir_flag is non-zero, then this is a mp_do_vmspath()
replacement, because the above parse just took care of most of
what is needed to do vmspath when the specification is already
@@ -8183,13 +8193,17 @@
the result.
  */
 
-/* If VMS 

[patch@35055] vms.c fileify refactor

2008-12-07 Thread John E. Malmberg
This patch makes a version of fileify available for calling with out an 
implicit context, which is needed for threaded perl as several routines 
do not have or need an implicit context.


This is the fifth of a multi-part conversion to remove access violations 
when internal perl warning and error routines, and memory allocation 
routines are called with a null pointer for the implicit context.


By removing the implicit context from these routines, it will cause a 
compile time error on threaded perl should one of the affected routines 
sneak back into this code.


-John
[EMAIL PROTECTED]
Personal Opinion Only
--- /ref6_root/perl/vms/vms.c   Sun Dec  7 16:34:04 2008
+++ vms/vms.c   Sun Dec  7 16:43:36 2008
@@ -298,6 +298,7 @@
 
 static char *int_tovmsspec
(const char *path, char *buf, int dir_flag, int * utf8_flag);
+static char * int_fileify_dirspec(const char *dir, char *buf, int *utf8_fl);
 static char * int_tounixspec(const char *spec, char *buf, int * utf8_fl);
 static char * int_tovmspath(const char *path, char *buf, int * utf8_fl);
 
@@ -5792,50 +5793,55 @@
 ** found in the Perl standard distribution.
  */
 
-/*{{{ char *fileify_dirspec[_ts](char *dir, char *buf, int * utf8_fl)*/
-static char *mp_do_fileify_dirspec(pTHX_ const char *dir,char *buf,int ts, int 
*utf8_fl)
-{
-static char __fileify_retbuf[VMS_MAXRSS];
+static char * 
+int_fileify_dirspec(const char *dir, char *buf, int *utf8_fl) {
+
 unsigned long int dirlen, retlen, addmfd = 0, hasfilename = 0;
-char *retspec, *cp1, *cp2, *lastdir;
+char *cp1, *cp2, *lastdir;
 char *trndir, *vmsdir;
 unsigned short int trnlnm_iter_count;
 int sts;
 if (utf8_fl != NULL)
-   *utf8_fl = 0;
+*utf8_fl = 0;
 
 if (!dir || !*dir) {
-  set_errno(EINVAL); set_vaxc_errno(SS$_BADPARAM); return NULL;
+set_errno(EINVAL);
+set_vaxc_errno(SS$_BADPARAM);
+return NULL;
 }
 dirlen = strlen(dir);
-while (dirlen  dir[dirlen-1] == '/') --dirlen;
+while (dirlen  dir[dirlen-1] == '/')
+--dirlen;
 if (!dirlen) { /* We had Unixish '/' -- substitute top of current tree */
-  if (!decc_posix_compliant_pathnames  decc_disable_posix_root) {
-dir = /sys$disk;
-dirlen = 9;
-  }
-  else
-   dirlen = 1;
+if (!decc_posix_compliant_pathnames  decc_disable_posix_root) {
+dir = /sys$disk;
+dirlen = 9;
+} else {
+dirlen = 1;
+}
 }
 if (dirlen  (VMS_MAXRSS - 1)) {
-  set_errno(ENAMETOOLONG); set_vaxc_errno(RMS$_SYN);
-  return NULL;
+set_errno(ENAMETOOLONG);
+set_vaxc_errno(SS$_BUFFEROVF);
+return NULL;
 }
 trndir = PerlMem_malloc(VMS_MAXRSS + 1);
-if (trndir == NULL) _ckvmssts(SS$_INSFMEM);
+if (trndir == NULL)
+_ckvmssts_noperl(SS$_INSFMEM);
 if (!strpbrk(dir+1,/]:)  
-   (!decc_posix_compliant_pathnames  decc_disable_posix_root)) {
-  strcpy(trndir,*dir == '/' ? dir + 1: dir);
-  trnlnm_iter_count = 0;
-  while (!strpbrk(trndir,/]:)  my_trnlnm(trndir,trndir,0)) {
-trnlnm_iter_count++; 
-if (trnlnm_iter_count = PERL_LNM_MAX_ITER) break;
-  }
-  dirlen = strlen(trndir);
-}
-else {
-  strncpy(trndir,dir,dirlen);
-  trndir[dirlen] = '\0';
+(!decc_posix_compliant_pathnames  decc_disable_posix_root)) {
+strcpy(trndir,*dir == '/' ? dir + 1: dir);
+trnlnm_iter_count = 0;
+while (!strpbrk(trndir,/]:) 
+   simple_trnlnm(trndir, trndir, VMS_MAXRSS)) {
+trnlnm_iter_count++; 
+if (trnlnm_iter_count = PERL_LNM_MAX_ITER)
+break;
+}
+dirlen = strlen(trndir);
+} else {
+strncpy(trndir,dir,dirlen);
+trndir[dirlen] = '\0';
 }
 
 /* At this point we are done with *dir and use *trndir which is a
@@ -5849,444 +5855,487 @@
  * does something useful.
  */
 if (dirlen = 2  !strcmp(trndir+dirlen-2,.])) {
-  trndir[--dirlen] = '\0';
-  trndir[dirlen-1] = ']';
+trndir[--dirlen] = '\0';
+trndir[dirlen-1] = ']';
 }
 if (dirlen = 2  !strcmp(trndir+dirlen-2,.)) {
-  trndir[--dirlen] = '\0';
-  trndir[dirlen-1] = '';
+trndir[--dirlen] = '\0';
+trndir[dirlen-1] = '';
 }
 
-if ((cp1 = strrchr(trndir,']')) != NULL || (cp1 = strrchr(trndir,'')) != 
NULL) {
-  /* If we've got an explicit filename, we can just shuffle the string. */
-  if (*(cp1+1)) hasfilename = 1;
-  /* Similarly, we can just back up a level if we've got multiple levels
- of explicit directories in a VMS spec which ends with directories. */
-  else {
-for (cp2 = cp1; cp2  trndir; cp2--) {
- if (*cp2 == '.') {
-   if ((cp2 - 1  trndir)  (*(cp2 - 1) != '^')) {
-/* fix-me, can not scan EFS file specs backward like this */
-  *cp2 = *cp1; *cp1 = '\0';
-  hasfilename = 

[patch@35055] vms.c rmsexpand refactor

2008-12-07 Thread John E. Malmberg
This patch makes a version of rmsexpand available for calling with out 
an implicit context, which is needed for threaded perl as several 
routines do not have or need an implicit context.


This is the sixth of a multi-part conversion to remove access violations 
when internal perl warning and error routines, and memory allocation 
routines are called with a null pointer for the implicit context.


By removing the implicit context from these routines, it will cause a 
compile time error on threaded perl should one of the affected routines 
sneak back into this code.


Hopefully this is the last big patch for a while.

-John
[EMAIL PROTECTED]
Personal Opinion Only
--- /ref7_root/perl/vms/vms.c   Sun Dec  7 17:20:31 2008
+++ vms/vms.c   Sun Dec  7 17:31:53 2008
@@ -296,6 +296,10 @@
 static char *mp_do_tounixspec(pTHX_ const char *, char *, int, int *);
 static char *mp_do_pathify_dirspec(pTHX_ const char *dir,char *buf, int ts, 
int *);
 
+static char *  int_rmsexpand_vms(
+const char * filespec, char * outbuf, unsigned opts);
+static char * int_rmsexpand_tovms(
+const char * filespec, char * outbuf, unsigned opts);
 static char *int_tovmsspec
(const char *path, char *buf, int dir_flag, int * utf8_flag);
 static char * int_fileify_dirspec(const char *dir, char *buf, int *utf8_fl);
@@ -5364,384 +5368,478 @@
 static char *mp_do_tounixspec(pTHX_ const char *, char *, int, int *);
 
 static char *
-mp_do_rmsexpand
-   (pTHX_ const char *filespec,
+int_rmsexpand
+   (const char *filespec,
 char *outbuf,
-int ts,
 const char *defspec,
 unsigned opts,
 int * fs_utf8,
 int * dfs_utf8)
 {
-  static char __rmsexpand_retbuf[VMS_MAXRSS];
-  char * vmsfspec, *tmpfspec;
-  char * esa, *cp, *out = NULL;
-  char * tbuf;
-  char * esal = NULL;
-  char * outbufl;
-  struct FAB myfab = cc$rms_fab;
-  rms_setup_nam(mynam);
-  STRLEN speclen;
-  unsigned long int retsts, trimver, trimtype, haslower = 0, isunix = 0;
-  int sts;
+char * ret_spec;
+const char * in_spec;
+char * spec_buf;
+const char * def_spec;
+char * vmsfspec, *vmsdefspec;
+char * esa;
+char * esal = NULL;
+char * outbufl;
+struct FAB myfab = cc$rms_fab;
+rms_setup_nam(mynam);
+STRLEN speclen;
+unsigned long int retsts, trimver, trimtype, haslower = 0, isunix = 0;
+int sts;
 
-  /* temp hack until UTF8 is actually implemented */
-  if (fs_utf8 != NULL)
-*fs_utf8 = 0;
+/* temp hack until UTF8 is actually implemented */
+if (fs_utf8 != NULL)
+*fs_utf8 = 0;
 
-  if (!filespec || !*filespec) {
-set_vaxc_errno(LIB$_INVARG); set_errno(EINVAL);
-return NULL;
-  }
-  if (!outbuf) {
-if (ts) out = Newx(outbuf,VMS_MAXRSS,char);
-elseoutbuf = __rmsexpand_retbuf;
-  }
+if (!filespec || !*filespec) {
+set_vaxc_errno(LIB$_INVARG); set_errno(EINVAL);
+return NULL;
+}
 
-  vmsfspec = NULL;
-  tmpfspec = NULL;
-  outbufl = NULL;
-
-  isunix = 0;
-  if ((opts  PERL_RMSEXPAND_M_VMS_IN) == 0) {
-isunix = is_unix_filespec(filespec);
-if (isunix) {
-  vmsfspec = PerlMem_malloc(VMS_MAXRSS);
-  if (vmsfspec == NULL) _ckvmssts(SS$_INSFMEM);
-  if (do_tovmsspec(filespec,vmsfspec,0,fs_utf8) == NULL) {
-   PerlMem_free(vmsfspec);
-   if (out)
-  Safefree(out);
-   return NULL;
-  }
-  filespec = vmsfspec;
+vmsfspec = NULL;
+vmsdefspec = NULL;
+outbufl = NULL;
+
+in_spec = filespec;
+isunix = 0;
+if ((opts  PERL_RMSEXPAND_M_VMS_IN) == 0) {
+
+/* If this is a UNIX file spec, convert it to VMS */
+isunix = is_unix_filespec(filespec);
+if (isunix) {
+char * ret_spec;
+vmsfspec = PerlMem_malloc(VMS_MAXRSS);
+if (vmsfspec == NULL)
+_ckvmssts_noperl(SS$_INSFMEM);
 
-  /* Unless we are forcing to VMS format, a UNIX input means
-   * UNIX output, and that requires long names to be used
-   */
+ret_spec = int_tovmsspec(filespec, vmsfspec, 0, fs_utf8);
+if (ret_spec == NULL) {
+PerlMem_free(vmsfspec);
+return NULL;
+}
+in_spec = (const char *)vmsfspec;
+
+/* Unless we are forcing to VMS format, a UNIX input means
+ * UNIX output, and that requires long names to be used
+ */
 #if !defined(__VAX)  defined(NAML$C_MAXRSS)
-  if ((opts  PERL_RMSEXPAND_M_VMS) == 0)
-   opts |= PERL_RMSEXPAND_M_LONG;
-  else
+if ((opts  PERL_RMSEXPAND_M_VMS) == 0)
+opts |= PERL_RMSEXPAND_M_LONG;
+else
 #endif
-   isunix = 0;
-  }
+isunix = 0;
+}
 }
 
-  rms_set_fna(myfab, mynam, (char *)filespec, strlen(filespec)); /* cast ok */
-  rms_bind_fab_nam(myfab, mynam);
+rms_set_fna(myfab, mynam, (char *)in_spec, strlen(in_spec)); /* cast ok */
+rms_bind_fab_nam(myfab, mynam);
 
-  if (defspec  *defspec) {
-int t_isunix;
-t_isunix = 

Re: [patch@35055] vms.c rmsexpand refactor

2008-12-07 Thread Craig A. Berry


On Dec 7, 2008, at 6:44 PM, John E. Malmberg wrote:

This patch makes a version of rmsexpand available for calling with  
out an implicit context, which is needed for threaded perl as  
several routines do not have or need an implicit context.


This is the sixth of a multi-part conversion to remove access  
violations when internal perl warning and error routines, and memory  
allocation routines are called with a null pointer for the implicit  
context.



I will look at these, test them, and -- if all goes well -- apply  
them, but it's likely to take me a while to get to them.  In general I  
agree with the principle that routines that can be called very early  
in start-up before thread context is initialized do need to be  
cautious about trying to access that context.  I will just make a  
preliminary comment that it's very hard to see what's going on by  
reading the patches because they consist mostly of changes to non- 
significant whitespace.


Craig A. Berry
mailto:[EMAIL PROTECTED]

... getting out of a sonnet is much more
 difficult than getting in.
 Brad Leithauser