The attached patch to perlio.c fixes the problem of errno getting set.
Jarkko Hietaniemi [Sun, 14 Jun 2009 16:53:22 +0000 (12:53 -0400)]
While I am firmly in the school of "do not look at $! except immediately
after a failure", I also agree that spuriously setting it is messy.  But
there is just no way of knowing where your errno might have been.

The problem was that PerlIO_fast_gets() (and other nearby similar
capability-checking PerlIO routines) set the errno (and it was being
called a lot, from sv_gets()).  I think setting the errno here was
a mistake: checking for "can has FOO" should not set external state,
such as the errno.  The patch removes that errno trashing from all those
routines.

perlio.c

index 10a32c1..4fe4fa7 100644 (file)
--- a/perlio.c
+++ b/perlio.c
@@ -1773,10 +1773,7 @@ PerlIO_has_base(PerlIO *f)
 
          if (tab)
               return (tab->Get_base != NULL);
-         SETERRNO(EINVAL, LIB_INVARG);
      }
-     else
-         SETERRNO(EBADF, SS_IVCHAN);
 
      return 0;
 }
@@ -1790,11 +1787,8 @@ PerlIO_fast_gets(PerlIO *f)
 
             if (tab)
                  return (tab->Set_ptrcnt != NULL);
-            SETERRNO(EINVAL, LIB_INVARG);
         }
     }
-    else
-        SETERRNO(EBADF, SS_IVCHAN);
 
     return 0;
 }
@@ -1807,10 +1801,7 @@ PerlIO_has_cntptr(PerlIO *f)
 
        if (tab)
             return (tab->Get_ptr != NULL && tab->Get_cnt != NULL);
-         SETERRNO(EINVAL, LIB_INVARG);
     }
-    else
-        SETERRNO(EBADF, SS_IVCHAN);
 
     return 0;
 }
@@ -1823,10 +1814,7 @@ PerlIO_canset_cnt(PerlIO *f)
 
          if (tab)
               return (tab->Set_ptrcnt != NULL);
-         SETERRNO(EINVAL, LIB_INVARG);
     }
-    else
-        SETERRNO(EBADF, SS_IVCHAN);
 
     return 0;
 }