Re: [patch@35050] replace pathify_dirspec in VMS with new version
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
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
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
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
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
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
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
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
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
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
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