spaceship and refs
[p5sagit/p5-mst-13.2.git] / pp_sys.c
index b241a0e..bf2b352 100644 (file)
--- a/pp_sys.c
+++ b/pp_sys.c
@@ -433,6 +433,9 @@ PP(pp_die)
     SV *tmpsv;
     STRLEN len;
     bool multiarg = 0;
+#ifdef VMS
+    VMSISH_HUSHED  = VMSISH_HUSHED || (PL_op->op_private & OPpHUSH_VMSISH);
+#endif
     if (SP - MARK != 1) {
        dTARGET;
        do_join(TARG, &PL_sv_no, MARK, SP);
@@ -1422,7 +1425,7 @@ PP(pp_prtf)
     if (!(io = GvIO(gv))) {
        if (ckWARN2(WARN_UNOPENED,WARN_CLOSED))
            report_evil_fh(gv, io, PL_op->op_type);
-       SETERRNO(EBADF,VMS_RMS_IFI);
+       SETERRNO(EBADF,RMS$_IFI);
        goto just_say_no;
     }
     else if (!(fp = IoOFP(io))) {
@@ -1444,7 +1447,7 @@ PP(pp_prtf)
            else if (ckWARN(WARN_CLOSED))
                report_evil_fh(gv, io, PL_op->op_type);
        }
-       SETERRNO(EBADF,IoIFP(io)?VMS_RMS_FAC:VMS_RMS_IFI);
+       SETERRNO(EBADF,IoIFP(io)?RMS$_FAC:RMS$_IFI);
        goto just_say_no;
     }
     else {
@@ -1514,6 +1517,9 @@ PP(pp_sysread)
     int fp_utf8;
     Size_t got = 0;
     Size_t wanted;
+    bool charstart = FALSE;
+    STRLEN charskip = 0;
+    STRLEN skip = 0;
 
     gv = (GV*)*++MARK;
     if ((PL_op->op_type == OP_READ || PL_op->op_type == OP_SYSREAD)
@@ -1560,6 +1566,10 @@ PP(pp_sysread)
        DIE(aTHX_ "Negative length");
     wanted = length;
 
+    charstart = TRUE;
+    charskip  = 0;
+    skip = 0;
+
 #ifdef HAS_SOCKET
     if (PL_op->op_type == OP_RECV) {
        char namebuf[MAXPATHLEN];
@@ -1680,23 +1690,30 @@ PP(pp_sysread)
        /* Look at utf8 we got back and count the characters */
        char *bend = buffer + count;
        while (buffer < bend) {
-           STRLEN skip = UTF8SKIP(buffer);
-           if (buffer+skip > bend) {
+           if (charstart) {
+               skip = UTF8SKIP(buffer);
+               charskip = 0;
+           }
+           if (buffer - charskip + skip > bend) {
                /* partial character - try for rest of it */
                length = skip - (bend-buffer);
                offset = bend - SvPVX(bufsv);
+               charstart = FALSE;
+               charskip += count;
                goto more_bytes;
            }
            else {
                got++;
                buffer += skip;
+               charstart = TRUE;
+               charskip  = 0;
            }
         }
        /* If we have not 'got' the number of _characters_ we 'wanted' get some more
           provided amount read (count) was what was requested (length)
         */
        if (got < wanted && count == length) {
-           length = (wanted-got);
+           length = wanted - got;
            offset = bend - SvPVX(bufsv);
            goto more_bytes;
        }
@@ -1846,6 +1863,8 @@ PP(pp_send)
     if (retval < 0)
        goto say_undef;
     SP = ORIGMARK;
+    if (DO_UTF8(bufsv))
+        retval = utf8_length((U8*)buffer, (U8*)buffer + retval);
 #if Size_t_size > IVSIZE
     PUSHn(retval);
 #else
@@ -2080,7 +2099,7 @@ PP(pp_truncate)
        if (result)
            RETPUSHYES;
        if (!errno)
-           SETERRNO(EBADF,VMS_RMS_IFI);
+           SETERRNO(EBADF,RMS$_IFI);
        RETPUSHUNDEF;
     }
 #else
@@ -2107,7 +2126,7 @@ PP(pp_ioctl)
     if (!io || !argsv || !IoIFP(io)) {
        if (ckWARN2(WARN_UNOPENED,WARN_CLOSED))
            report_evil_fh(gv, io, PL_op->op_type);
-       SETERRNO(EBADF,VMS_RMS_IFI);    /* well, sort of... */
+       SETERRNO(EBADF,RMS$_IFI);       /* well, sort of... */
        RETPUSHUNDEF;
     }
 
@@ -2195,7 +2214,7 @@ PP(pp_flock)
        if (ckWARN2(WARN_UNOPENED,WARN_CLOSED))
            report_evil_fh(gv, io, PL_op->op_type);
        value = 0;
-       SETERRNO(EBADF,VMS_RMS_IFI);
+       SETERRNO(EBADF,RMS$_IFI);
     }
     PUSHi(value);
     RETURN;
@@ -2225,7 +2244,7 @@ PP(pp_socket)
            report_evil_fh(gv, io, PL_op->op_type);
        if (IoIFP(io))
            do_close(gv, FALSE);
-       SETERRNO(EBADF,VMS_LIB_INVARG);
+       SETERRNO(EBADF,LIB$_INVARG);
        RETPUSHUNDEF;
     }
 
@@ -2376,7 +2395,7 @@ PP(pp_bind)
 nuts:
     if (ckWARN(WARN_CLOSED))
        report_evil_fh(gv, io, PL_op->op_type);
-    SETERRNO(EBADF,VMS_SS_IVCHAN);
+    SETERRNO(EBADF,SS$_IVCHAN);
     RETPUSHUNDEF;
 #else
     DIE(aTHX_ PL_no_sock_func, "bind");
@@ -2406,7 +2425,7 @@ PP(pp_connect)
 nuts:
     if (ckWARN(WARN_CLOSED))
        report_evil_fh(gv, io, PL_op->op_type);
-    SETERRNO(EBADF,VMS_SS_IVCHAN);
+    SETERRNO(EBADF,SS$_IVCHAN);
     RETPUSHUNDEF;
 #else
     DIE(aTHX_ PL_no_sock_func, "connect");
@@ -2432,7 +2451,7 @@ PP(pp_listen)
 nuts:
     if (ckWARN(WARN_CLOSED))
        report_evil_fh(gv, io, PL_op->op_type);
-    SETERRNO(EBADF,VMS_SS_IVCHAN);
+    SETERRNO(EBADF,SS$_IVCHAN);
     RETPUSHUNDEF;
 #else
     DIE(aTHX_ PL_no_sock_func, "listen");
@@ -2464,12 +2483,11 @@ PP(pp_accept)
        goto nuts;
 
     nstio = GvIOn(ngv);
-    if (IoIFP(nstio))
-       do_close(ngv, FALSE);
-
     fd = PerlSock_accept(PerlIO_fileno(IoIFP(gstio)), (struct sockaddr *)&saddr, &len);
     if (fd < 0)
        goto badexit;
+    if (IoIFP(nstio))
+       do_close(ngv, FALSE);
     IoIFP(nstio) = PerlIO_fdopen(fd, "r");
     IoOFP(nstio) = PerlIO_fdopen(fd, "w");
     IoTYPE(nstio) = IoTYPE_SOCKET;
@@ -2494,7 +2512,7 @@ PP(pp_accept)
 nuts:
     if (ckWARN(WARN_CLOSED))
        report_evil_fh(ggv, ggv ? GvIO(ggv) : 0, PL_op->op_type);
-    SETERRNO(EBADF,VMS_SS_IVCHAN);
+    SETERRNO(EBADF,SS$_IVCHAN);
 
 badexit:
     RETPUSHUNDEF;
@@ -2521,7 +2539,7 @@ PP(pp_shutdown)
 nuts:
     if (ckWARN(WARN_CLOSED))
        report_evil_fh(gv, io, PL_op->op_type);
-    SETERRNO(EBADF,VMS_SS_IVCHAN);
+    SETERRNO(EBADF,SS$_IVCHAN);
     RETPUSHUNDEF;
 #else
     DIE(aTHX_ PL_no_sock_func, "shutdown");
@@ -2600,7 +2618,7 @@ PP(pp_ssockopt)
 nuts:
     if (ckWARN(WARN_CLOSED))
        report_evil_fh(gv, io, optype);
-    SETERRNO(EBADF,VMS_SS_IVCHAN);
+    SETERRNO(EBADF,SS$_IVCHAN);
 nuts2:
     RETPUSHUNDEF;
 
@@ -2673,7 +2691,7 @@ PP(pp_getpeername)
 nuts:
     if (ckWARN(WARN_CLOSED))
        report_evil_fh(gv, io, optype);
-    SETERRNO(EBADF,VMS_SS_IVCHAN);
+    SETERRNO(EBADF,SS$_IVCHAN);
 nuts2:
     RETPUSHUNDEF;
 
@@ -3276,7 +3294,7 @@ PP(pp_fttext)
                gv = cGVOP_gv;
                report_evil_fh(gv, GvIO(gv), PL_op->op_type);
            }
-           SETERRNO(EBADF,VMS_RMS_IFI);
+           SETERRNO(EBADF,RMS$_IFI);
            RETPUSHUNDEF;
        }
     }
@@ -3882,7 +3900,7 @@ PP(pp_closedir)
     RETPUSHYES;
 nope:
     if (!errno)
-       SETERRNO(EBADF,VMS_RMS_IFI);
+       SETERRNO(EBADF,RMS$_IFI);
     RETPUSHUNDEF;
 #else
     DIE(aTHX_ PL_no_dir_func, "closedir");