OS/2 build
[p5sagit/p5-mst-13.2.git] / pp_sys.c
index ea35136..9fee8c9 100644 (file)
--- a/pp_sys.c
+++ b/pp_sys.c
@@ -1517,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)
@@ -1563,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];
@@ -1683,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;
        }
@@ -1849,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
@@ -3396,6 +3412,7 @@ PP(pp_chdir)
         }
         else {            
             PUSHi(0);
+            TAINT_PROPER("chdir");
             RETURN;
         }
     }
@@ -3497,9 +3514,8 @@ PP(pp_rename)
 
 PP(pp_link)
 {
-    dSP;
 #ifdef HAS_LINK
-    dTARGET;
+    dSP; dTARGET;
     STRLEN n_a;
     char *tmps2 = POPpx;
     char *tmps = SvPV(TOPs, n_a);
@@ -3907,8 +3923,11 @@ PP(pp_fork)
        RETSETUNDEF;
     if (!childpid) {
        /*SUPPRESS 560*/
-       if ((tmpgv = gv_fetchpv("$", TRUE, SVt_PV)))
+       if ((tmpgv = gv_fetchpv("$", TRUE, SVt_PV))) {
+            SvREADONLY_off(GvSV(tmpgv));
            sv_setiv(GvSV(tmpgv), (IV)PerlProc_getpid());
+            SvREADONLY_on(GvSV(tmpgv));
+        }
        hv_clear(PL_pidstatus); /* no kids, so don't wait for 'em */
     }
     PUSHi(childpid);
@@ -4011,6 +4030,16 @@ PP(pp_system)
         int status;
         Sigsave_t ihand,qhand;     /* place to save signals during system() */
         
+        if (PL_tainting) {
+            SV *cmd = NULL;
+            if (PL_op->op_flags & OPf_STACKED)
+               cmd = *(MARK + 1);
+            else if (SP - MARK != 1)
+               cmd = *SP;
+            if (cmd && *(SvPV_nolen(cmd)) != '/')
+               TAINT_ENV();
+        }
+
         if (PerlProc_pipe(pp) >= 0)
              did_pipes = 1;
         while ((childpid = PerlProc_fork()) == -1) {