Since 5.9.0 or so, it appears that there is no longer an stdio layer at
the bottom of the heap in the PerlIO layers, at least not by default,
which means the stdio slot in the PerlIO structure is always null. This
causes PerlIO_getname to give up the ghost, which causes
File::Copy::copy (when passed filehandles rather than names) and a
couple of other critical things to fail.

The attached patch makes PerlIO_getname work harder to obtain a FILE
gizmo and it does solve the problem. As I understand it, though, the
export will reopen the file and push an stdio layer, which seems a
pretty heavy price to pay when all I want to do is look up a bit of
metadata in the file header and not do any I/O, but I don't know of any
other way to do this.

The general problem is how to grab onto a file system gadget that native
services can use when starting with nothing but a Perl filehandle. If
there are examples in the core sources of how to do this, I can't find
them; w32_CopyFile, for example, doesn't appear to attempt it.

--- perlio.c;-0 Sun Nov  2 13:41:00 2003
+++ perlio.c    Thu Dec 11 14:21:50 2003
@@ -4718,9 +4718,16 @@
     dTHX;
     char *name = NULL;
 #ifdef VMS
+    bool exported = FALSE;
     FILE *stdio = PerlIOSelf(f, PerlIOStdio)->stdio;
-    if (stdio)
+    if (!stdio) {
+       stdio = PerlIO_exportFILE(f,0);
+       exported = TRUE;
+    }
+    if (stdio) {
        name = fgetname(stdio, buf);
+       if (exported) PerlIO_releaseFILE(f,stdio);
+    }
 #else
     Perl_croak(aTHX_ "Don't know how to get file name");
 #endif

Reply via email to