From d46f021e36854e800770363f716e7b4a846102ef Mon Sep 17 00:00:00 2001 From: "Craig A. Berry" Date: Fri, 22 Mar 2013 20:39:37 -0500 Subject: [PATCH] Restore errno after VMS hack in S_sv_gets_read_record. In 596a6cbd6bcaa8e6a4 I added a somewhat desperate hack to detect if a file is record-oriented so that we preserve record semantics when PL_rs has beeen set. I did it by calling fstat(), which is already a pretty icky thing to be doing on every record read, but it turns out things are even worse becaseu fstat() sets errno in some conditions where it's successful, specifically when the file is a Process-Permanent File (PPF), i.e., standard input or output. So save errno before the fstat and restore it before doing the read so if the read fails we get a proper errno. This gets t/io/errno.t passing. Side note: instead of fstat() here, we probably need to store a pointer to the FAB (File Access Block) in the PerlIO struct so all the metadata about the file is always accessible. This would require setting up completion routines in PerlIOUnix_open and PerlIOStdio_open. --- sv.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sv.c b/sv.c index 3f68d9c..4ed4349 100644 --- a/sv.c +++ b/sv.c @@ -7674,6 +7674,7 @@ S_sv_gets_read_record(pTHX_ SV *const sv, PerlIO *const fp, I32 append) #include int fd; Stat_t st; + dSAVE_ERRNO; /* With a true, record-oriented file on VMS, we need to use read directly * to ensure that we respect RMS record boundaries. The user is responsible @@ -7688,6 +7689,8 @@ S_sv_gets_read_record(pTHX_ SV *const sv, PerlIO *const fp, I32 append) || st.st_fab_rfm == FAB$C_VFC || st.st_fab_rfm == FAB$C_FIX)) { + /* fstat does the equivalent of SETERRNO(EVMSERR, RMS$_IOP) on PPFs. */ + RESTORE_ERRNO; bytesread = PerlLIO_read(fd, buffer, recsize); } else /* in-memory file from PerlIO::Scalar -- 1.8.3.1