This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Re: And now the Cwd problem (was Re: chdir.t problem...)
[perl5.git] / doio.c
diff --git a/doio.c b/doio.c
index dfd8710..0309e2a 100644 (file)
--- a/doio.c
+++ b/doio.c
@@ -174,7 +174,7 @@ Perl_do_openn(pTHX_ GV *gv, register char *name, I32 len, int as_raw,
             IoTYPE(io) = IoTYPE_RDWR;
             break;
        }
-       writing = (result > 0);
+       writing = (result != O_RDONLY);
 
        if (result == O_RDONLY) {
            mode[ix++] = 'r';
@@ -235,6 +235,7 @@ Perl_do_openn(pTHX_ GV *gv, register char *name, I32 len, int as_raw,
        if ((*type == IoTYPE_RDWR) && /* scary */
            (*(type+1) == IoTYPE_RDONLY || *(type+1) == IoTYPE_WRONLY) &&
            ((!num_svs || (tend > type+1 && tend[-1] != IoTYPE_PIPE)))) {
+        TAINT_PROPER("open");
            mode[1] = *type++;
            writing = 1;
        }
@@ -1221,7 +1222,9 @@ Perl_do_print(pTHX_ register SV *sv, PerlIO *fp)
                sv_utf8_upgrade(sv = sv_mortalcopy(sv));
        }
        else if (DO_UTF8(sv)) {
-           if (!sv_utf8_downgrade((sv = sv_mortalcopy(sv)), TRUE)) {
+           if (!sv_utf8_downgrade((sv = sv_mortalcopy(sv)), TRUE)
+               && ckWARN(WARN_UTF8))
+           {
                Perl_warner(aTHX_ WARN_UTF8, "Wide character in print");
            }
        }
@@ -2029,13 +2032,42 @@ Perl_do_semop(pTHX_ SV **mark, SV **sp)
     id = SvIVx(*++mark);
     opstr = *++mark;
     opbuf = SvPV(opstr, opsize);
-    if (opsize < sizeof(struct sembuf)
-       || (opsize % sizeof(struct sembuf)) != 0) {
+    if (opsize < 3 * SHORTSIZE
+       || (opsize % (3 * SHORTSIZE))) {
        SETERRNO(EINVAL,LIB$_INVARG);
        return -1;
     }
     SETERRNO(0,0);
-    return semop(id, (struct sembuf *)opbuf, opsize/sizeof(struct sembuf));
+    /* We can't assume that sizeof(struct sembuf) == 3 * sizeof(short). */
+    {
+        int nsops  = opsize / (3 * sizeof (short));
+        int i      = nsops;
+        short *ops = (short *) opbuf;
+        short *o   = ops;
+        struct sembuf *temps, *t;
+        I32 result;
+
+        New (0, temps, nsops, struct sembuf);
+        t = temps;
+        while (i--) {
+            t->sem_num = *o++;
+            t->sem_op  = *o++;
+            t->sem_flg = *o++;
+            t++;
+        }
+        result = semop(id, temps, nsops);
+        t = temps;
+        o = ops;
+        i = nsops;
+        while (i--) {
+            *o++ = t->sem_num;
+            *o++ = t->sem_op;
+            *o++ = t->sem_flg;
+            t++;
+        }
+        Safefree(temps);
+        return result;
+    }
 #else
     Perl_croak(aTHX_ "semop not implemented");
 #endif