Make readdir on VMS only unixify when asked.
authorCraig A. Berry <craigberry@mac.com>
Fri, 15 Feb 2013 00:10:55 +0000 (18:10 -0600)
committerCraig A. Berry <craigberry@mac.com>
Fri, 15 Feb 2013 03:41:20 +0000 (21:41 -0600)
We've been making our home-grown readdir implementation convert
all its results to Unix format since a096370a74e8.  Since readdir
returns relative paths, the usual volume and directory syntax
differences that distinguish VMS and Unix paths don't really apply.

But what does apply is whether the escaping of extended characters
is passed through or removed, and converting to Unix syntax removes
those escapes.  In order to enable extended filename syntax, though,
we're really going to need the escapes.  For example, rmdir will
not be able to remove a directory foo.bar if it's referred to as
[.foo.bar] because a dot is the traditional directory delimiter.
The directory needs to be specified as [.foo^.bar] for rmdir to
delete it successfully.

So make readdir return filespecs in native format unless explicitly
requested to report all filenames in Unix format.

vms/vms.c

index a5f092b..9a0ab4b 100644 (file)
--- a/vms/vms.c
+++ b/vms/vms.c
@@ -9986,12 +9986,12 @@ Perl_opendir(pTHX_ const char *name)
     dd->context = 0;
     dd->count = 0;
     dd->flags = 0;
-    /* By saying we always want the result of readdir() in unix format, we 
-     * are really saying we want all the escapes removed.  Otherwise the caller,
-     * having no way to know whether it's already in VMS format, might send it
-     * through tovmsspec again, thus double escaping.
+    /* By saying we want the result of readdir() in unix format, we are really
+     * saying we want all the escapes removed, translating characters that
+     * must be escaped in a VMS-format name to their unescaped form, which is
+     * presumably allowed in a Unix-format name.
      */
-    dd->flags = PERL_VMSDIR_M_UNIXSPECS;
+    dd->flags = decc_filename_unix_report ? PERL_VMSDIR_M_UNIXSPECS : 0;
     dd->pat.dsc$a_pointer = dd->pattern;
     dd->pat.dsc$w_length = strlen(dd->pattern);
     dd->pat.dsc$b_dtype = DSC$K_DTYPE_T;