diff options
-rwxr-xr-x | Configure | 162 | ||||
-rw-r--r-- | config_h.SH | 24 | ||||
-rw-r--r-- | doio.c | 57 | ||||
-rw-r--r-- | perl.h | 22 |
4 files changed, 215 insertions, 50 deletions
@@ -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 <sys/types.h> +#include <sys/ipc.h> +#include <sys/sem.h> +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 <sys/sem.h>." >&4 + val="$define" + else + echo "You do not have union semun in <sys/sem.h>." >&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 <<END +#include <sys/types.h> +#include <sys/ipc.h> +#include <sys/sem.h> +#include <sys/stat.h> +#include <stdio.h> +#include <errno.h> +#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 <sys/types.h> +#include <sys/ipc.h> +#include <sys/sem.h> +#include <sys/stat.h> +#include <stdio.h> +#include <errno.h> +#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 78486bacae..ab532e54b2 100644 --- a/config_h.SH +++ b/config_h.SH @@ -536,6 +536,30 @@ sed <<!GROK!THIS! >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 <sys/sem.h>. 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. @@ -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 <sys/sem_buf.h> - 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 @@ -2090,6 +2090,26 @@ enum { UNLOCK_SV_MUTEX; \ } while (0) +#ifdef HAS_SEM +# include <sys/ipc.h> +# include <sys/sem.h> +# 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 */ - |