Make vms.c's Perl_flex_fstat preserve errno on success.
authorCraig A. Berry <craigberry@mac.com>
Mon, 25 Mar 2013 01:39:38 +0000 (20:39 -0500)
committerCraig A. Berry <craigberry@mac.com>
Mon, 25 Mar 2013 01:39:38 +0000 (20:39 -0500)
The CRTL's fstat() sets errno to EVMSERR and vaxc$errno to RMS$_IOP
when called on a proccess-permanent file (i.e., stdin, stdout, or
stderr).  That error generally means a rewind operation on a file
that cannot be rewound.  It's odd that fstat is doing such a thing,
but we can at least protect ourselves from the effects of it by
saving errno and restoring it on a successful call.

This cures a couple of test failures and TODOs in t/io/errno.t.

t/io/errno.t
vms/vms.c

index dadc4e0..e9a6c09 100644 (file)
@@ -34,8 +34,6 @@ SKIP:
                for my $rs_code ('', '$/=undef', '$/=\2', '$/=\1024') {
                    TODO:
                    {
-                       local $::TODO = "We get RMS\$_IOP at EOF on VMS when \$/ is undef"
-                           if $^O eq 'VMS' && $rs_code eq '$/=undef';
                        is( runperl( prog => "$rs_code; $test_prog",
                                                 stdin => $test_in, stderr => 1),
                                $test_in,
index 58de70d..8cb3245 100644 (file)
--- a/vms/vms.c
+++ b/vms/vms.c
@@ -12068,6 +12068,7 @@ Perl_cando_by_name(pTHX_ I32 bit, bool effective, const char *fname)
 int
 Perl_flex_fstat(pTHX_ int fd, Stat_t *statbufp)
 {
+  dSAVE_ERRNO; /* fstat may set this even on success */
   if (!fstat(fd, &statbufp->crtl_stat)) {
     char *cptr;
     char *vms_filename;
@@ -12103,6 +12104,7 @@ Perl_flex_fstat(pTHX_ int fd, Stat_t *statbufp)
       statbufp->st_ctime = _toloc(statbufp->st_ctime);
     }
 #   endif
+    RESTORE_ERRNO;
     return 0;
   }
   return -1;