diff options
author | Nicholas Clark <nick@ccl4.org> | 2001-07-01 23:26:48 +0100 |
---|---|---|
committer | Jarkko Hietaniemi <jhi@iki.fi> | 2001-07-02 17:37:44 +0000 |
commit | 248ff010a9f14ea43c69a11c0242d8e9e015163d (patch) | |
tree | 5faffa40ce293bf6cc686e41f8f2029513f4d2c3 /doio.c | |
parent | 33f2f539b5ffc4650c1fcafdf5cfcabd7b1953ec (diff) | |
download | perl-248ff010a9f14ea43c69a11c0242d8e9e015163d.tar.gz |
Based on
Subject: Re: sizeof(struct sembuf)
Message-ID: <20010701222648.W59620@plum.flirble.org>
but do semop() always the slow way.
p4raw-id: //depot/perl@11098
Diffstat (limited to 'doio.c')
-rw-r--r-- | doio.c | 35 |
1 files changed, 32 insertions, 3 deletions
@@ -2029,13 +2029,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 |