[perl #24940] "sub foo :unique" segfaults
[p5sagit/p5-mst-13.2.git] / ext / PerlIO / via / via.xs
index d454678..d95d631 100644 (file)
@@ -35,6 +35,7 @@ typedef struct
  CV *mERROR;
  CV *mEOF;
  CV *BINMODE;
+ CV *UTF8;
 } PerlIOVia;
 
 #define MYMethod(x) #x,&s->x
@@ -164,6 +165,15 @@ PerlIOVia_pushed(pTHX_ PerlIO * f, const char *mode, SV * arg,
                else {
                    goto push_failed;
                }
+               modesv = (*PerlIONext(f) && (PerlIOBase(PerlIONext(f))->flags & PERLIO_F_UTF8))
+                           ? &PL_sv_yes : &PL_sv_no;
+               result = PerlIOVia_method(aTHX_ f, MYMethod(UTF8), G_SCALAR, modesv, Nullsv);
+               if (result && SvTRUE(result)) {
+                   PerlIOBase(f)->flags |= ~PERLIO_F_UTF8;
+               }
+               else {
+                   PerlIOBase(f)->flags &= ~PERLIO_F_UTF8;
+               }
                if (PerlIOVia_fetchmethod(aTHX_ s, MYMethod(FILL)) ==
                    (CV *) - 1)
                    PerlIOBase(f)->flags &= ~PERLIO_F_FASTGETS;
@@ -350,12 +360,20 @@ IV
 PerlIOVia_seek(pTHX_ PerlIO * f, Off_t offset, int whence)
 {
     PerlIOVia *s = PerlIOSelf(f, PerlIOVia);
-    SV *offsv = sv_2mortal(newSViv(offset));
+    SV *offsv = sv_2mortal(sizeof(Off_t) > sizeof(IV)
+                          ? newSVnv((NV)offset) : newSViv((IV)offset));
     SV *whsv = sv_2mortal(newSViv(whence));
     SV *result =
        PerlIOVia_method(aTHX_ f, MYMethod(SEEK), G_SCALAR, offsv, whsv,
                         Nullsv);
+#if Off_t_size == 8 && defined(CONDOP_SIZE) && CONDOP_SIZE < Off_t_size
+    if (result)
+       return (Off_t) SvIV(result);
+    else
+       return (Off_t) -1;
+#else
     return (result) ? SvIV(result) : -1;
+#endif
 }
 
 Off_t
@@ -364,7 +382,9 @@ PerlIOVia_tell(pTHX_ PerlIO * f)
     PerlIOVia *s = PerlIOSelf(f, PerlIOVia);
     SV *result =
        PerlIOVia_method(aTHX_ f, MYMethod(TELL), G_SCALAR, Nullsv);
-    return (result) ? (Off_t) SvIV(result) : (Off_t) - 1;
+    return (result)
+          ? (SvNOK(result) ? (Off_t)SvNV(result) : (Off_t)SvIV(result))
+          : (Off_t) - 1;
 }
 
 SSize_t