Re: overriding builtins quirk
[p5sagit/p5-mst-13.2.git] / pp_sys.c
index 0245a35..b14dd77 100644 (file)
--- a/pp_sys.c
+++ b/pp_sys.c
@@ -457,7 +457,7 @@ PP(pp_die)
     }
     else {
        tmpsv = TOPs;
-        tmps = (SvROK(tmpsv) && PL_in_eval) ? Nullch : SvPV(tmpsv, len);
+        tmps = SvROK(tmpsv) ? Nullch : SvPV(tmpsv, len);
     }
     if (!tmps || !len) {
        SV *error = ERRSV;
@@ -608,8 +608,8 @@ PP(pp_pipe_op)
     if (PerlProc_pipe(fd) < 0)
        goto badexit;
 
-    IoIFP(rstio) = PerlIO_fdopen(fd[0], "r");
-    IoOFP(wstio) = PerlIO_fdopen(fd[1], "w");
+    IoIFP(rstio) = PerlIO_fdopen(fd[0], "r"PIPESOCK_MODE);
+    IoOFP(wstio) = PerlIO_fdopen(fd[1], "w"PIPESOCK_MODE);
     IoOFP(rstio) = IoIFP(rstio);
     IoIFP(wstio) = IoOFP(wstio);
     IoTYPE(rstio) = IoTYPE_RDONLY;
@@ -734,6 +734,7 @@ PP(pp_binmode)
     if (!(io = GvIO(gv)) || !(fp = IoIFP(io))) {
        if (ckWARN2(WARN_UNOPENED,WARN_CLOSED))
            report_evil_fh(gv, io, PL_op->op_type);
+       SETERRNO(EBADF,RMS_IFI);
         RETPUSHUNDEF;
     }
 
@@ -761,7 +762,6 @@ PP(pp_tie)
     char *methname;
     int how = PERL_MAGIC_tied;
     U32 items;
-    STRLEN n_a;
 
     varsv = *++MARK;
     switch(SvTYPE(varsv)) {
@@ -808,8 +808,8 @@ PP(pp_tie)
         */
        stash = gv_stashsv(*MARK, FALSE);
        if (!stash || !(gv = gv_fetchmethod(stash, methname))) {
-           DIE(aTHX_ "Can't locate object method \"%s\" via package \"%s\"",
-                methname, SvPV(*MARK,n_a));
+           DIE(aTHX_ "Can't locate object method \"%s\" via package \"%"SVf"\"",
+                methname, *MARK);
        }
        ENTER;
        PUSHSTACKi(PERLSI_MAGIC);
@@ -1177,6 +1177,7 @@ PP(pp_getc)
        if (ckWARN2(WARN_UNOPENED,WARN_CLOSED)
                && (!io || (!IoIFP(io) && IoTYPE(io) != IoTYPE_WRONLY)))
            report_evil_fh(gv, io, PL_op->op_type);
+       SETERRNO(EBADF,RMS_IFI);
        RETPUSHUNDEF;
     }
     TAINT;
@@ -1362,21 +1363,8 @@ PP(pp_leavewrite)
     fp = IoOFP(io);
     if (!fp) {
        if (ckWARN2(WARN_CLOSED,WARN_IO)) {
-           if (IoIFP(io)) {
-               /* integrate with report_evil_fh()? */
-               char *name = NULL;
-               if (isGV(gv)) {
-                   SV* sv = sv_newmortal();
-                   gv_efullname4(sv, gv, Nullch, FALSE);
-                   name = SvPV_nolen(sv);
-               }
-               if (name && *name)
-                   Perl_warner(aTHX_ packWARN(WARN_IO),
-                               "Filehandle %s opened only for input", name);
-               else
-                   Perl_warner(aTHX_ packWARN(WARN_IO),
-                               "Filehandle opened only for input");
-           }
+           if (IoIFP(io))
+               report_evil_fh(gv, io, OP_phoney_INPUT_ONLY);
            else if (ckWARN(WARN_CLOSED))
                report_evil_fh(gv, io, PL_op->op_type);
        }
@@ -1449,20 +1437,8 @@ PP(pp_prtf)
     }
     else if (!(fp = IoOFP(io))) {
        if (ckWARN2(WARN_CLOSED,WARN_IO))  {
-           /* integrate with report_evil_fh()? */
-           if (IoIFP(io)) {
-               char *name = NULL;
-               if (isGV(gv)) {
-                   gv_efullname4(sv, gv, Nullch, FALSE);
-                   name = SvPV_nolen(sv);
-               }
-               if (name && *name)
-                   Perl_warner(aTHX_ packWARN(WARN_IO),
-                               "Filehandle %s opened only for input", name);
-               else
-                   Perl_warner(aTHX_ packWARN(WARN_IO),
-                               "Filehandle opened only for input");
-           }
+           if (IoIFP(io))
+               report_evil_fh(gv, io, OP_phoney_INPUT_ONLY);
            else if (ckWARN(WARN_CLOSED))
                report_evil_fh(gv, io, PL_op->op_type);
        }
@@ -1571,8 +1547,12 @@ PP(pp_sysread)
     else
        offset = 0;
     io = GvIO(gv);
-    if (!io || !IoIFP(io))
+    if (!io || !IoIFP(io)) {
+       if (ckWARN2(WARN_UNOPENED,WARN_CLOSED))
+           report_evil_fh(gv, io, PL_op->op_type);
+       SETERRNO(EBADF,RMS_IFI);
        goto say_undef;
+    }
     if ((fp_utf8 = PerlIO_isutf8(IoIFP(io))) && !IN_BYTES) {
        buffer = SvPVutf8_force(bufsv, blen);
        /* UTF8 may not have been set if they are all low bytes */
@@ -1685,21 +1665,7 @@ PP(pp_sysread)
     }
     if (count < 0) {
        if ((IoTYPE(io) == IoTYPE_WRONLY) && ckWARN(WARN_IO))
-       {
-           /* integrate with report_evil_fh()? */
-           char *name = NULL;
-           if (isGV(gv)) {
-               SV* sv = sv_newmortal();
-               gv_efullname4(sv, gv, Nullch, FALSE);
-               name = SvPV_nolen(sv);
-           }
-           if (name && *name)
-               Perl_warner(aTHX_ packWARN(WARN_IO),
-                           "Filehandle %s opened only for output", name);
-           else
-               Perl_warner(aTHX_ packWARN(WARN_IO),
-                           "Filehandle opened only for output");
-       }
+               report_evil_fh(gv, io, OP_phoney_OUTPUT_ONLY);
        goto say_undef;
     }
     SvCUR_set(bufsv, count+(buffer - SvPVX(bufsv)));
@@ -1813,6 +1779,7 @@ PP(pp_send)
        retval = -1;
        if (ckWARN(WARN_CLOSED))
            report_evil_fh(gv, io, PL_op->op_type);
+       SETERRNO(EBADF,RMS_IFI);
        goto say_undef;
     }
 
@@ -2064,22 +2031,31 @@ PP(pp_truncate)
         STRLEN n_a;
        int result = 1;
        GV *tmpgv;
-       
+       IO *io;
+
        if (PL_op->op_flags & OPf_SPECIAL) {
            tmpgv = gv_fetchpv(POPpx, FALSE, SVt_PVIO);
 
-       do_ftruncate:
-           TAINT_PROPER("truncate");
-           if (!GvIO(tmpgv) || !IoIFP(GvIOp(tmpgv)))
-               result = 0;
+       do_ftruncate_gv:
+           if (!GvIO(tmpgv))
+               result = 0;
            else {
-               PerlIO_flush(IoIFP(GvIOp(tmpgv)));
+               PerlIO *fp;
+               io = GvIOp(tmpgv);
+           do_ftruncate_io:
+               TAINT_PROPER("truncate");
+               if (!(fp = IoIFP(io))) {
+                   result = 0;
+               }
+               else {
+                   PerlIO_flush(fp);
 #ifdef HAS_TRUNCATE
-               if (ftruncate(PerlIO_fileno(IoIFP(GvIOn(tmpgv))), len) < 0)
+                   if (ftruncate(PerlIO_fileno(fp), len) < 0)
 #else
-               if (my_chsize(PerlIO_fileno(IoIFP(GvIOn(tmpgv))), len) < 0)
+                   if (my_chsize(PerlIO_fileno(fp), len) < 0)
 #endif
-                   result = 0;
+                       result = 0;
+               }
            }
        }
        else {
@@ -2088,11 +2064,15 @@ PP(pp_truncate)
        
            if (SvTYPE(sv) == SVt_PVGV) {
                tmpgv = (GV*)sv;                /* *main::FRED for example */
-               goto do_ftruncate;
+               goto do_ftruncate_gv;
            }
            else if (SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PVGV) {
                tmpgv = (GV*) SvRV(sv); /* \*main::FRED for example */
-               goto do_ftruncate;
+               goto do_ftruncate_gv;
+           }
+           else if (SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PVIO) {
+               io = (IO*) SvRV(sv); /* *main::FRED{IO} for example */
+               goto do_ftruncate_io;
            }
 
            name = SvPV(sv, n_a);
@@ -2274,8 +2254,8 @@ PP(pp_socket)
     fd = PerlSock_socket(domain, type, protocol);
     if (fd < 0)
        RETPUSHUNDEF;
-    IoIFP(io) = PerlIO_fdopen(fd, "r");        /* stdio gets confused about sockets */
-    IoOFP(io) = PerlIO_fdopen(fd, "w");
+    IoIFP(io) = PerlIO_fdopen(fd, "r"PIPESOCK_MODE);   /* stdio gets confused about sockets */
+    IoOFP(io) = PerlIO_fdopen(fd, "w"PIPESOCK_MODE);
     IoTYPE(io) = IoTYPE_SOCKET;
     if (!IoIFP(io) || !IoOFP(io)) {
        if (IoIFP(io)) PerlIO_close(IoIFP(io));
@@ -2336,11 +2316,11 @@ PP(pp_sockpair)
     TAINT_PROPER("socketpair");
     if (PerlSock_socketpair(domain, type, protocol, fd) < 0)
        RETPUSHUNDEF;
-    IoIFP(io1) = PerlIO_fdopen(fd[0], "r");
-    IoOFP(io1) = PerlIO_fdopen(fd[0], "w");
+    IoIFP(io1) = PerlIO_fdopen(fd[0], "r"PIPESOCK_MODE);
+    IoOFP(io1) = PerlIO_fdopen(fd[0], "w"PIPESOCK_MODE);
     IoTYPE(io1) = IoTYPE_SOCKET;
-    IoIFP(io2) = PerlIO_fdopen(fd[1], "r");
-    IoOFP(io2) = PerlIO_fdopen(fd[1], "w");
+    IoIFP(io2) = PerlIO_fdopen(fd[1], "r"PIPESOCK_MODE);
+    IoOFP(io2) = PerlIO_fdopen(fd[1], "w"PIPESOCK_MODE);
     IoTYPE(io2) = IoTYPE_SOCKET;
     if (!IoIFP(io1) || !IoOFP(io1) || !IoIFP(io2) || !IoOFP(io2)) {
        if (IoIFP(io1)) PerlIO_close(IoIFP(io1));
@@ -2488,7 +2468,6 @@ PP(pp_accept)
     struct sockaddr saddr;     /* use a struct to avoid alignment problems */
     Sock_size_t len = sizeof saddr;
     int fd;
-    int fd2;
 
     ggv = (GV*)POPs;
     ngv = (GV*)POPs;
@@ -2508,12 +2487,8 @@ PP(pp_accept)
        goto badexit;
     if (IoIFP(nstio))
        do_close(ngv, FALSE);
-    IoIFP(nstio) = PerlIO_fdopen(fd, "r");
-    /* FIXME: we dup(fd) here so that refcounting of fd's does not inhibit
-       fclose of IoOFP's FILE * - and hence leak memory.
-       Special treatment of _this_ case of IoIFP != IoOFP seems wrong.
-     */
-    IoOFP(nstio) = PerlIO_fdopen(fd2 = PerlLIO_dup(fd), "w");
+    IoIFP(nstio) = PerlIO_fdopen(fd, "r"PIPESOCK_MODE);
+    IoOFP(nstio) = PerlIO_fdopen(fd, "w"PIPESOCK_MODE);
     IoTYPE(nstio) = IoTYPE_SOCKET;
     if (!IoIFP(nstio) || !IoOFP(nstio)) {
        if (IoIFP(nstio)) PerlIO_close(IoIFP(nstio));
@@ -2523,7 +2498,6 @@ PP(pp_accept)
     }
 #if defined(HAS_FCNTL) && defined(F_SETFD)
     fcntl(fd, F_SETFD, fd > PL_maxsysfd);      /* ensure close-on-exec */
-    fcntl(fd2, F_SETFD, fd2 > PL_maxsysfd);    /* ensure close-on-exec */
 #endif
 
 #ifdef EPOC
@@ -2831,7 +2805,7 @@ PP(pp_stat)
        PUSHs(sv_2mortal(newSVpvn("", 0)));
 #endif
 #if Off_t_size > IVSIZE
-       PUSHs(sv_2mortal(newSVnv(PL_statcache.st_size)));
+       PUSHs(sv_2mortal(newSVnv((NV)PL_statcache.st_size)));
 #else
        PUSHs(sv_2mortal(newSViv(PL_statcache.st_size)));
 #endif
@@ -3711,7 +3685,7 @@ PP(pp_mkdir)
      * -d, chdir(), chmod(), chown(), chroot(), fcntl()?,
      * (mkdir()), opendir(), rename(), rmdir(), stat(). --jhi */
     if (len > 1 && tmps[len-1] == '/') {
-       while (tmps[len] == '/' && len > 1)
+       while (tmps[len-1] == '/' && len > 1)
            len--;
        tmps = savepvn(tmps, len);
        copy = TRUE;
@@ -4945,6 +4919,9 @@ PP(pp_gservent)
        char *proto = POPpbytex;
        unsigned short port = (unsigned short)POPu;
 
+       if (proto && !*proto)
+           proto = Nullch;
+
 #ifdef HAS_HTONS
        port = PerlSock_htons(port);
 #endif