d_semctl=''
d_semget=''
d_semop=''
+d_union_semun=''
+d_semctl_semun=''
+d_semctl_semid_ds=''
d_setegid=''
d_seteuid=''
d_setgrps=''
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
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'
*/
#$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.
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)
{
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;
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
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
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 */
-