From: Jarkko Hietaniemi Date: Sun, 24 May 1998 16:13:21 +0000 (+0300) Subject: This change really is: X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=f0784f6a4c3e45e13aac90c9b07dd4163084f9a4;p=p5sagit%2Fp5-mst-13.2.git This change really is: Subject: [PATCH] 5.004_65: the infamous semctl() Date: Sun, 24 May 1998 16:13:21 +0300 (EET DST) Change 1041 claimed to be this patch but was really: Subject: [PATCH] 5.004_65: t/op/ipc*.t Date: Sat, 16 May 1998 00:52:39 +0300 (EET DST) From: Jarkko Hietaniemi p4raw-id: //depot/perl@1043 --- diff --git a/Configure b/Configure index 79b7a5d..04ab73c 100755 --- a/Configure +++ b/Configure @@ -408,6 +408,9 @@ d_sem='' d_semctl='' d_semget='' d_semop='' +d_union_semun='' +d_semctl_semun='' +d_semctl_semid_ds='' d_setegid='' d_seteuid='' d_setgrps='' @@ -7945,6 +7948,162 @@ fi set d_sem eval $setvar +: see how to do semctl IPC_STAT +case "$h_sem$d_sem$d_semctl" in +true$define$define) + : see whether sys/sem.h defines union semun + $cat > try.c <<'END' +#include +#include +#include +int main () { union semun semun; semun.buf = 0; } +END + if $cc $ccflags -o try try.c > /dev/null 2>&1; then + echo "You have union semun in ." >&4 + val="$define" + else + echo "You do not have union semun in ." >&4 + val="$undef" + fi + $rm -f try try.c + set d_union_semun + eval $setvar + + : see whether semctl IPC_STAT can use union semun + $cat > try.c < +#include +#include +#include +#include +#include +#ifndef errno +extern int errno; +#endif +#$d_union_semun HAS_UNION_SEMUN +int main() { + union semun +#ifndef HAS_UNION_SEMUN + { + int val; + struct semid_ds *buf; + unsigned short *array; + } +#endif + arg; + int sem, st; + +#if defined(IPC_PRIVATE) && defined(S_IRWXU) && defined(S_IRWXG) && \ + defined(S_IRWXO) && defined(IPC_CREAT) + sem = semget(IPC_PRIVATE, 1, S_IRWXU|S_IRWXG|S_IRWXO|IPC_CREAT); + if (sem > -1) { + struct semid_ds argbuf; + arg.buf = &argbuf; +# ifdef IPC_STAT + st = semctl(sem, 0, IPC_STAT, arg); + if (st == 0) + printf("semun\n"); + else +# endif /* IPC_STAT */ + printf("semctl IPC_STAT failed: errno = %d\n", errno); +# ifdef IPC_RMID + if (semctl(sem, 0, IPC_RMID, arg) != 0) +# endif /* IPC_RMID */ + printf("semctl IPC_RMID failed: errno = %d\n", errno); + } else +#endif /* IPC_PRIVATE && ... */ + printf("semget failed: errno = %d\n", errno); + + return 0; +} +END + val="$undef" + if $cc $ccflags -o try try.c > /dev/null 2>&1; then + d_semctl_semun=`./try` + case "$d_semctl_semun" in + semun) val="$define" ;; + esac + fi + $rm -f try try.c + set d_semctl_semun + eval $setvar + case "$d_semctl_semun" in + $define|true) + echo "You can use union semun for semctl IPC_STAT." >&4 + ;; + *) echo "You cannot use union semun for semctl IPC_STAT." >&4 + ;; + esac + + : see whether semctl IPC_STAT can use struct semid_ds pointer + + $cat > try.c <<'END' +#include +#include +#include +#include +#include +#include +#ifndef errno +extern int errno; +#endif +int main() { + struct semid_ds arg; + int sem, st; + +#if defined(IPC_PRIVATE) && defined(S_IRWXU) && defined(S_IRWXG) && \ + defined(S_IRWXO) && defined(IPC_CREAT) + sem = semget(IPC_PRIVATE, 1, S_IRWXU|S_IRWXG|S_IRWXO|IPC_CREAT); + if (sem > -1) { +# ifdef IPC_STAT + st = semctl(sem, 0, IPC_STAT, &arg); + if (st == 0) + printf("semid_ds\n"); + else +# endif /* IPC_STAT */ + printf("semctl IPC_STAT failed: errno = %d\n", errno); +# ifdef IPC_RMID + if (semctl(sem, 0, IPC_RMID, &arg) != 0) +# endif /* IPC_RMID */ + printf("semctl IPC_RMID failed: errno = %d\n", errno); + } else +#endif /* IPC_PRIVATE && ... */ + printf("semget failed: errno = %d\n", errno); + + return 0; +} +END + val="$undef" + if $cc $ccflags -o try try.c > /dev/null 2>&1; then + d_semctl_semid_ds=`./try` + case "$d_semctl_semid_ds" in + semid_ds) val="$define" ;; + esac + fi + $rm -f try try.c + set d_semctl_semid_ds + eval $setvar + case "$d_semctl_semid_ds" in + $define|true) + echo "You can use struct semid_ds * for semctl IPC_STAT." >&4 + ;; + *) echo "You cannot use struct semid_ds * for semctl IPC_STAT." >&4 + ;; + esac + ;; +*) val="$undef" + + set d_union_semun + eval $setvar + + set d_semctl_semun + eval $setvar + + set d_semctl_semid_ds + eval $setvar + ;; +esac + : see if setegid exists set setegid d_setegid eval $inlibc @@ -11134,6 +11293,9 @@ d_sem='$d_sem' d_semctl='$d_semctl' d_semget='$d_semget' d_semop='$d_semop' +d_union_semun='$d_union_semun' +d_semctl_semun='$d_semctl_semun' +d_semctl_semid_ds='$d_semctl_semid_ds' d_setegid='$d_setegid' d_seteuid='$d_seteuid' d_setgrps='$d_setgrps' diff --git a/config_h.SH b/config_h.SH index 78486ba..ab532e5 100644 --- a/config_h.SH +++ b/config_h.SH @@ -536,6 +536,30 @@ sed <config.h -e 's!^#undef\(.*/\)\*!/\*#define\1 \*!' -e 's!^#un- */ #$d_sem HAS_SEM /**/ +/* HAS_UNION_SEMUN: + * This symbol, if defined, indicates that the union semun + * is defined in . If not, the user code probably + * needs to define it as: + * union semun { + * int val; + * struct semid_ds *buf; + * unsigned short *array; + * } + */ +#$d_union_semun HAS_UNION_SEMUN /**/ + +/* USE_SEMCTL_SEMUN: + * This symbol, if defined, indicates that union semun is + * used for semctl IPC_STAT. + */ +#$d_semctl_semun USE_SEMCTL_SEMUN /**/ + +/* USE_SEMCTL_SEMID_DS: + * This symbol, if defined, indicates that struct semid_ds * is + * used for semctl IPC_STAT. + */ +#$d_semctl_semid_ds USE_SEMCTL_SEMID_DS /**/ + /* HAS_SETEGID: * This symbol, if defined, indicates that the setegid routine is available * to change the effective gid of the current program. diff --git a/doio.c b/doio.c index bbf3837..37d6167 100644 --- a/doio.c +++ b/doio.c @@ -1389,21 +1389,6 @@ do_ipcget(I32 optype, SV **mark, SV **sp) return -1; /* should never happen */ } -#if defined(__sun) && defined(__svr4__) /* XXX Need metaconfig test */ -/* Solaris manpage says that it uses (like linux) - int semctl (int semid, int semnum, int cmd, union semun arg) - but the system include files do not define union semun !!!! - Note: Linux/glibc *does* declare union semun in - but, unlike the older Linux libc and Solaris, it has an extra - struct seminfo * on the end. -*/ -union semun { - int val; - struct semid_ds *buf; - ushort *array; -}; -#endif - I32 do_ipcctl(I32 optype, SV **mark, SV **sp) { @@ -1412,26 +1397,6 @@ do_ipcctl(I32 optype, SV **mark, SV **sp) char *a; I32 id, n, cmd, infosize, getinfo; I32 ret = -1; -/* XXX REALLY need metaconfig test */ -/* linux and Solaris2 use: - int semctl (int semid, int semnum, int cmd, union semun arg) - instead of: - int semctl (int semid, int semnum, int cmd, struct semid_ds *arg); - Solaris and Linux (pre-glibc) use - union semun { - int val; - struct semid_ds *buf; - ushort *array; - }; - but Solaris doesn't declare it in a header file (we declared it - explicitly earlier). Linux/glibc declares a *different* union semun - so we just refer to "union semun" here. - -*/ -#if defined(__linux__) || (defined(__sun__) && defined(__svr4__)) -# define SEMCTL_SEMUN - union semun unsemds, semun; -#endif id = SvIVx(*++mark); n = (optype == OP_SEMCTL) ? SvIVx(*++mark) : 0; @@ -1461,13 +1426,9 @@ do_ipcctl(I32 optype, SV **mark, SV **sp) else if (cmd == GETALL || cmd == SETALL) { struct semid_ds semds; -#ifdef SEMCTL_SEMUN + union semun semun; + semun.buf = &semds; - if (semctl(id, 0, IPC_STAT, semun) == -1) -#else - if (semctl(id, 0, IPC_STAT, &semds) == -1) -#endif - return -1; getinfo = (cmd == GETALL); infosize = semds.sem_nsems * sizeof(short); /* "short" is technically wrong but much more portable @@ -1511,14 +1472,12 @@ do_ipcctl(I32 optype, SV **mark, SV **sp) break; #endif #ifdef HAS_SEM - case OP_SEMCTL: -#ifdef SEMCTL_SEMUN - /* XXX Need metaconfig test */ - unsemds.buf = (struct semid_ds *)a; - ret = semctl(id, n, cmd, unsemds); -#else - ret = semctl(id, n, cmd, (struct semid_ds *)a); -#endif + case OP_SEMCTL: { + union semun unsemds; + + unsemds.buf = (struct semid_ds *)a; + ret = Semctl(id, n, cmd, unsemds); + } break; #endif #ifdef HAS_SHM diff --git a/perl.h b/perl.h index fc96064..8645c39 100644 --- a/perl.h +++ b/perl.h @@ -2090,6 +2090,26 @@ enum { UNLOCK_SV_MUTEX; \ } while (0) +#ifdef HAS_SEM +# include +# include +# ifndef HAS_UNION_SEMUN /* Provide the union semun. */ + union semun { + int val; + struct semid_ds *buf; + unsigned short *array; + }; +# endif +# ifdef USE_SEMCTL_SEMUN +# define Semctl(id, num, cmd, semun) semctl(id, num, cmd, semun) +# else +# ifdef USE_SEMCTL_SEMID_DS +# define Semctl(id, num, cmd, semun) semctl(id, num, cmd, semun.buf) +# endif +# endif +# ifndef Semctl /* Place our bets on the semun horse. */ +# define Semctl(id, num, cmd, semun) semctl(id, num, cmd, semun) +# endif +#endif #endif /* Include guard */ -