--- doio.c.orig Tue Jul 29 02:08:11 1997 +++ doio.c Sat Sep 29 13:56:55 2001 @@ -1333,9 +1333,6 @@ char *a; I32 id, n, cmd, infosize, getinfo; I32 ret = -1; -#ifdef __linux__ /* XXX Need metaconfig test */ - union semun unsemds; -#endif id = SvIVx(*++mark); n = (optype == OP_SEMCTL) ? SvIVx(*++mark) : 0; @@ -1365,21 +1362,10 @@ else if (cmd == GETALL || cmd == SETALL) { struct semid_ds semds; -#ifdef __linux__ /* XXX Need metaconfig test */ -/* linux (and Solaris2?) uses : - int semctl (int semid, int semnum, int cmd, union semun arg) - union semun { - int val; - struct semid_ds *buf; - ushort *array; - }; -*/ - union semun 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 + if (Semctl(id, 0, IPC_STAT, semun) == -1) return -1; getinfo = (cmd == GETALL); infosize = semds.sem_nsems * sizeof(short); @@ -1424,13 +1410,12 @@ break; #endif #ifdef HAS_SEM - case OP_SEMCTL: -#ifdef __linux__ /* 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 --- perl.h.orig Mon Oct 6 18:20:06 1997 +++ perl.h Sat Sep 29 14:43:21 2001 @@ -2221,5 +2221,27 @@ #define printf PerlIO_stdoutf #endif -#endif /* Include guard */ +#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 */ --- config_h.SH.orig Thu May 8 17:57:47 1997 +++ config_h.SH Sat Sep 29 14:08:09 2001 @@ -617,6 +617,30 @@ */ #$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. --- patchlevel.h.orig Wed Oct 15 10:55:19 1997 +++ patchlevel.h Sun Sep 30 19:59:22 2001 @@ -39,6 +39,7 @@ /* The following line and terminating '};' are read by perlbug.PL. Don't alter. */ static char *local_patches[] = { NULL + ,"linux union semun fixes backported from 5.004_05 (nick\\@ccl4.org)" ,NULL }; --- Configure.orig Fri Oct 3 18:57:39 1997 +++ Configure Sat Sep 29 14:14:08 2001 @@ -371,6 +371,9 @@ d_semctl='' d_semget='' d_semop='' +d_union_semun='' +d_semctl_semun='' +d_semctl_semid_ds='' d_setegid='' d_seteuid='' d_setlinebuf='' @@ -7338,6 +7341,162 @@ 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 @@ -10144,6 +10303,9 @@ 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_setlinebuf='$d_setlinebuf'