PerlIOUnix_read(pTHX_ PerlIO *f, void *vbuf, Size_t count)
{
int fd = PerlIOSelf(f, PerlIOUnix)->fd;
- if (!(PerlIOBase(f)->flags & PERLIO_F_CANREAD))
+ if (!(PerlIOBase(f)->flags & PERLIO_F_CANREAD) ||
+ PerlIOBase(f)->flags & (PERLIO_F_EOF|PERLIO_F_ERROR)) {
return 0;
+ }
while (1) {
SSize_t len = PerlLIO_read(fd, vbuf, count);
if (len >= 0 || errno != EINTR) {
IV
PerlIOStdio_fileno(pTHX_ PerlIO *f)
{
- return PerlSIO_fileno(PerlIOSelf(f, PerlIOStdio)->stdio);
+ FILE *s;
+ if (PerlIOValid(f) && (s = PerlIOSelf(f, PerlIOStdio)->stdio)) {
+ return PerlSIO_fileno(s);
+ }
+ errno = EBADF;
+ return -1;
}
char *
return ret;
}
-/*
- * This isn't used yet ...
- */
IV
PerlIOStdio_pushed(pTHX_ PerlIO *f, const char *mode, SV *arg, PerlIO_funcs *tab)
{
- if (*PerlIONext(f)) {
- PerlIOStdio *s = PerlIOSelf(f, PerlIOStdio);
- char tmode[8];
- FILE *stdio =
- PerlSIO_fdopen(PerlIO_fileno(PerlIONext(f)), mode =
- PerlIOStdio_mode(mode, tmode));
- if (stdio) {
- s->stdio = stdio;
- /* We never call down so do any pending stuff now */
- PerlIO_flush(PerlIONext(f));
- }
- else
- return -1;
+ PerlIO *n;
+ if (PerlIOValid(f) && PerlIOValid(n = PerlIONext(f))) {
+ PerlIO_funcs *toptab = PerlIOBase(n)->tab;
+ if (toptab == tab) {
+ /* Top is already stdio - pop self (duplicate) and use original */
+ PerlIO_pop(aTHX_ f);
+ return 0;
+ } else {
+ int fd = PerlIO_fileno(n);
+ char tmode[8];
+ FILE *stdio;
+ if (fd >= 0 && (stdio = PerlSIO_fdopen(fd,
+ mode = PerlIOStdio_mode(mode, tmode)))) {
+ PerlIOSelf(f, PerlIOStdio)->stdio = stdio;
+ /* We never call down so do any pending stuff now */
+ PerlIO_flush(PerlIONext(f));
+ }
+ else {
+ return -1;
+ }
+ }
}
return PerlIOBase_pushed(aTHX_ f, mode, arg, tab);
}
s->stdio = stdio;
PerlIOUnix_refcnt_inc(fileno(s->stdio));
}
+ return f;
+ }
+ else {
+ return NULL;
}
- return f;
}
}
if (fd >= 0) {
Sock_size_t optlen = sizeof(int);
#endif
FILE *stdio = PerlIOSelf(f, PerlIOStdio)->stdio;
+ if (!stdio) {
+ errno = EBADF;
+ return -1;
+ }
if (PerlIOUnix_refcnt_dec(fileno(stdio)) > 0) {
/* Do not close it but do flush any buffers */
return PerlIO_flush(f);
"stdio",
sizeof(PerlIOStdio),
PERLIO_K_BUFFERED|PERLIO_K_RAW,
- PerlIOBase_pushed,
+ PerlIOStdio_pushed,
PerlIOBase_popped,
PerlIOStdio_open,
PerlIOBase_binmode, /* binmode */
+
+
+