includes a modified version.
p4raw-id: //depot/perl@1046
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;
- union semun semun;
-
+#ifdef SEMCTL_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: {
- union semun unsemds;
-
- unsemds.buf = (struct semid_ds *)a;
- ret = Semctl(id, n, cmd, unsemds);
- }
+ 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
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 */
+