perlio tweaks (reported by Nicholas Clark)
[p5sagit/p5-mst-13.2.git] / perlio.c
index 9f12be6..132fe47 100644 (file)
--- a/perlio.c
+++ b/perlio.c
@@ -1825,12 +1825,12 @@ IV
 PerlIOStdio_close(PerlIO *f)
 {
  dTHX;
-#ifdef HAS_SOCKET
+#ifdef HAS_SOCKS5_INIT
  int optval, optlen = sizeof(int);
 #endif
  FILE *stdio = PerlIOSelf(f,PerlIOStdio)->stdio;
  return(
-#ifdef HAS_SOCKET
+#ifdef HAS_SOCKS5_INIT
    (getsockopt(PerlIO_fileno(f), SOL_SOCKET, SO_TYPE, (char *)&optval, &optlen) < 0) ?
        PerlSIO_fclose(stdio) :
        close(PerlIO_fileno(f))
@@ -2079,7 +2079,17 @@ IV
 PerlIOBuf_pushed(PerlIO *f, const char *mode, const char *arg, STRLEN len)
 {
  PerlIOBuf *b = PerlIOSelf(f,PerlIOBuf);
- b->posn = PerlIO_tell(PerlIONext(f));
+ int fd  = PerlIO_fileno(f);
+ Off_t posn;
+ if (fd >= 0 && PerlLIO_isatty(fd))
+  {
+   PerlIOBase(f)->flags |= PERLIO_F_LINEBUF;
+  }
+ posn = PerlIO_tell(PerlIONext(f));
+ if (posn != (Off_t) -1)
+  {
+   b->posn = posn;
+  }
  return PerlIOBase_pushed(f,mode,arg,len);
 }
 
@@ -2610,8 +2620,12 @@ PerlIOPending_read(PerlIO *f, void *vbuf, Size_t count)
   avail = count;
  if (avail > 0)
   got = PerlIOBuf_read(f,vbuf,avail);
- if (got < count)
-  got += PerlIO_read(f,((STDCHAR *) vbuf)+got,count-got);
+ if (got >= 0 && got < count)
+  {
+   SSize_t more = PerlIO_read(f,((STDCHAR *) vbuf)+got,count-got);
+   if (more >= 0 || got == 0)
+    got += more;
+  }
  return got;
 }
 
@@ -3375,6 +3389,7 @@ PerlIO_vprintf(PerlIO *f, const char *fmt, va_list ap)
  SV *sv = newSVpvn("",0);
  char *s;
  STRLEN len;
+ SSize_t wrote;
 #ifdef NEED_VA_COPY
  va_list apc;
  Perl_va_copy(ap, apc);
@@ -3383,7 +3398,9 @@ PerlIO_vprintf(PerlIO *f, const char *fmt, va_list ap)
  sv_vcatpvf(sv, fmt, &ap);
 #endif
  s = SvPV(sv,len);
- return PerlIO_write(f,s,len);
+ wrote = PerlIO_write(f,s,len);
+ SvREFCNT_dec(sv);
+ return wrote;
 }
 
 #undef PerlIO_printf