The attached patch to perlio.c fixes the problem of errno getting set.
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.