summaryrefslogtreecommitdiff
path: root/sys/compat/linux
diff options
context:
space:
mode:
authorfvdl <fvdl@NetBSD.org>1995-08-15 21:14:32 +0000
committerfvdl <fvdl@NetBSD.org>1995-08-15 21:14:32 +0000
commit02b3c95be6462df2ce3b205fbedf4d02bd33060c (patch)
treeabcfa120cc6df2d31eff6974b22c59cb997cbde7 /sys/compat/linux
parent238eb3d35a6f9f8e08556cde7bca007afd79f8e9 (diff)
Implement the rest of the sysv ipc calls ({sem,msg}*())
Diffstat (limited to 'sys/compat/linux')
-rw-r--r--sys/compat/linux/common/linux_ipc.c273
-rw-r--r--sys/compat/linux/common/linux_ipccall.c273
-rw-r--r--sys/compat/linux/common/linux_ipccall.h11
-rw-r--r--sys/compat/linux/common/linux_msg.h14
-rw-r--r--sys/compat/linux/common/linux_sem.h72
-rw-r--r--sys/compat/linux/include/linux_ipccall.h11
-rw-r--r--sys/compat/linux/include/linux_msg.h14
-rw-r--r--sys/compat/linux/include/linux_sem.h72
-rw-r--r--sys/compat/linux/linux_ipc.c273
-rw-r--r--sys/compat/linux/linux_ipccall.h11
-rw-r--r--sys/compat/linux/linux_msg.h14
-rw-r--r--sys/compat/linux/linux_sem.h72
-rw-r--r--sys/compat/linux/multiarch/linux_ipccall.c273
-rw-r--r--sys/compat/linux/multiarch/linux_ipccall.h11
14 files changed, 1201 insertions, 193 deletions
diff --git a/sys/compat/linux/common/linux_ipc.c b/sys/compat/linux/common/linux_ipc.c
index 984a07f155c..dbef9670c57 100644
--- a/sys/compat/linux/common/linux_ipc.c
+++ b/sys/compat/linux/common/linux_ipc.c
@@ -1,4 +1,4 @@
-/* $NetBSD: linux_ipc.c,v 1.5 1995/08/14 01:27:52 mycroft Exp $ */
+/* $NetBSD: linux_ipc.c,v 1.6 1995/08/15 21:14:32 fvdl Exp $ */
/*
* Copyright (c) 1995 Frank van der Linden
@@ -35,6 +35,7 @@
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/shm.h>
+#include <sys/sem.h>
#include <sys/msg.h>
#include <sys/proc.h>
#include <sys/uio.h>
@@ -54,6 +55,7 @@
#include <compat/linux/linux_ipc.h>
#include <compat/linux/linux_msg.h>
#include <compat/linux/linux_shm.h>
+#include <compat/linux/linux_sem.h>
#include <compat/linux/linux_ipccall.h>
/*
@@ -114,35 +116,35 @@ linux_ipc(p, uap, retval)
switch (SCARG(uap, what)) {
#ifdef SYSVSEM
- case LINUX_SYS_semop:
- return linux_semop(p, uap, retval);
- case LINUX_SYS_semget:
- return linux_semget(p, uap, retval);
- case LINUX_SYS_semctl:
- return linux_semctl(p, uap, retval);
+ case LINUX_SYS_semop:
+ return linux_semop(p, uap, retval);
+ case LINUX_SYS_semget:
+ return linux_semget(p, uap, retval);
+ case LINUX_SYS_semctl:
+ return linux_semctl(p, uap, retval);
#endif
#ifdef SYSVMSG
- case LINUX_SYS_msgsnd:
- return linux_msgsnd(p, uap, retval);
- case LINUX_SYS_msgrcv:
- return linux_msgrcv(p, uap, retval);
- case LINUX_SYS_msgget:
- return linux_msgget(p, uap, retval);
- case LINUX_SYS_msgctl:
- return linux_msgctl(p, uap, retval);
+ case LINUX_SYS_msgsnd:
+ return linux_msgsnd(p, uap, retval);
+ case LINUX_SYS_msgrcv:
+ return linux_msgrcv(p, uap, retval);
+ case LINUX_SYS_msgget:
+ return linux_msgget(p, uap, retval);
+ case LINUX_SYS_msgctl:
+ return linux_msgctl(p, uap, retval);
#endif
#ifdef SYSVSHM
- case LINUX_SYS_shmat:
- return linux_shmat(p, uap, retval);
- case LINUX_SYS_shmdt:
- return linux_shmdt(p, uap, retval);
- case LINUX_SYS_shmget:
- return linux_shmget(p, uap, retval);
- case LINUX_SYS_shmctl:
- return linux_shmctl(p, uap, retval);
+ case LINUX_SYS_shmat:
+ return linux_shmat(p, uap, retval);
+ case LINUX_SYS_shmdt:
+ return linux_shmdt(p, uap, retval);
+ case LINUX_SYS_shmget:
+ return linux_shmget(p, uap, retval);
+ case LINUX_SYS_shmctl:
+ return linux_shmctl(p, uap, retval);
#endif
- default:
- return ENOSYS;
+ default:
+ return ENOSYS;
}
}
@@ -181,8 +183,37 @@ bsd_to_linux_ipc_perm(bpp, lpp)
#ifdef SYSVSEM
/*
- * Semaphore operations: not implemented yet.
+ * Semaphore operations. Most constants and structures are the same on
+ * both systems. Only semctl() needs some extra work.
*/
+
+/*
+ * Convert between Linux and NetBSD semid_ds structures.
+ */
+static void
+bsd_to_linux_semid_ds(bs, ls)
+ struct semid_ds *bs;
+ struct linux_semid_ds *ls;
+{
+ bsd_to_linux_ipc_perm(&bs->sem_perm, &ls->l_sem_perm);
+ ls->l_sem_otime = bs->sem_otime;
+ ls->l_sem_ctime = bs->sem_ctime;
+ ls->l_sem_nsems = bs->sem_nsems;
+ ls->l_sem_base = bs->sem_base;
+}
+
+static void
+linux_to_bsd_semid_ds(ls, bs)
+ struct linux_semid_ds *ls;
+ struct semid_ds *bs;
+{
+ linux_to_bsd_ipc_perm(&ls->l_sem_perm, &bs->sem_perm);
+ bs->sem_otime = ls->l_sem_otime;
+ bs->sem_ctime = ls->l_sem_ctime;
+ bs->sem_nsems = ls->l_sem_nsems;
+ bs->sem_base = ls->l_sem_base;
+}
+
int
linux_semop(p, uap, retval)
struct proc *p;
@@ -195,7 +226,13 @@ linux_semop(p, uap, retval)
} */ *uap;
register_t *retval;
{
- return ENOSYS;
+ struct semop_args bsa;
+
+ SCARG(&bsa, semid) = SCARG(uap, a1);
+ SCARG(&bsa, sops) = (struct sembuf *)SCARG(uap, ptr);
+ SCARG(&bsa, nsops) = SCARG(uap, a2);
+
+ return semop(p, &bsa, retval);
}
int
@@ -210,9 +247,21 @@ linux_semget(p, uap, retval)
} */ *uap;
register_t *retval;
{
- return ENOSYS;
+ struct semget_args bsa;
+
+ SCARG(&bsa, key) = (key_t)SCARG(uap, a1);
+ SCARG(&bsa, nsems) = SCARG(uap, a2);
+ SCARG(&bsa, semflg) = SCARG(uap, a3);
+
+ return semget(p, &bsa, retval);
}
+/*
+ * Most of this can be handled by directly passing the arguments on,
+ * buf IPC_* require a lot of copy{in,out} because of the extra indirection
+ * (we are passed a pointer to a union cointaining a pointer to a semid_ds
+ * structure.
+ */
int
linux_semctl(p, uap, retval)
struct proc *p;
@@ -225,14 +274,111 @@ linux_semctl(p, uap, retval)
} */ *uap;
register_t *retval;
{
- return ENOSYS;
+ caddr_t sg, unptr, dsp, ldsp;
+ int error, cmd;
+ struct __semctl_args bsa;
+ struct linux_semid_ds lm;
+ struct semid_ds bm;
+
+ SCARG(&bsa, semid) = SCARG(uap, a1);
+ SCARG(&bsa, semnum) = SCARG(uap, a2);
+ SCARG(&bsa, cmd) = SCARG(uap, a3);
+ SCARG(&bsa, arg) = (union semun *)SCARG(uap, ptr);
+ switch(SCARG(uap, a3)) {
+ case LINUX_GETVAL:
+ cmd = GETVAL;
+ break;
+ case LINUX_GETPID:
+ cmd = GETPID;
+ break;
+ case LINUX_GETNCNT:
+ cmd = GETNCNT;
+ break;
+ case LINUX_GETZCNT:
+ cmd = GETZCNT;
+ break;
+ case LINUX_SETVAL:
+ cmd = SETVAL;
+ break;
+ case LINUX_IPC_RMID:
+ cmd = IPC_RMID;
+ break;
+ case LINUX_IPC_SET:
+ if ((error = copyin(SCARG(uap, ptr), &ldsp, sizeof ldsp)))
+ return error;
+ if ((error = copyin(ldsp, (caddr_t)&lm, sizeof lm)))
+ return error;
+ linux_to_bsd_semid_ds(&lm, &bm);
+ sg = stackgap_init(p->p_emul);
+ unptr = stackgap_alloc(&sg, sizeof (union semun));
+ dsp = stackgap_alloc(&sg, sizeof (struct semid_ds));
+ if ((error = copyout((caddr_t)&bm, dsp, sizeof bm)))
+ return error;
+ if ((error = copyout((caddr_t)&dsp, unptr, sizeof dsp)))
+ return error;
+ SCARG(&bsa, arg) = (union semun *)unptr;
+ return __semctl(p, &bsa, retval);
+ case LINUX_IPC_STAT:
+ sg = stackgap_init(p->p_emul);
+ unptr = stackgap_alloc(&sg, sizeof (union semun *));
+ dsp = stackgap_alloc(&sg, sizeof (struct semid_ds));
+ if ((error = copyout((caddr_t)&dsp, unptr, sizeof dsp)))
+ return error;
+ SCARG(&bsa, arg) = (union semun *)unptr;
+ if ((error = __semctl(p, &bsa, retval)))
+ return error;
+ if ((error = copyin(dsp, (caddr_t)&bm, sizeof bm)))
+ return error;
+ bsd_to_linux_semid_ds(&bm, &lm);
+ if ((error = copyin(SCARG(uap, ptr), &ldsp, sizeof ldsp)))
+ return error;
+ return copyout((caddr_t)&lm, ldsp, sizeof lm);
+ default:
+ return EINVAL;
+ }
+ SCARG(&bsa, cmd) = cmd;
+ return __semctl(p, &bsa, retval);
}
#endif /* SYSVSEM */
#ifdef SYSVMSG
-/*
- * Msg functions: not implemented yet.
- */
+
+static void
+linux_to_bsd_msqid_ds(lmp, bmp)
+ struct linux_msqid_ds *lmp;
+ struct msqid_ds *bmp;
+{
+ linux_to_bsd_ipc_perm(&lmp->l_msg_perm, &bmp->msg_perm);
+ bmp->msg_first = lmp->l_msg_first;
+ bmp->msg_last = lmp->l_msg_last;
+ bmp->msg_cbytes = lmp->l_msg_cbytes;
+ bmp->msg_qnum = lmp->l_msg_qnum;
+ bmp->msg_qbytes = lmp->l_msg_qbytes;
+ bmp->msg_lspid = lmp->l_msg_lspid;
+ bmp->msg_lrpid = lmp->l_msg_lrpid;
+ bmp->msg_stime = lmp->l_msg_stime;
+ bmp->msg_rtime = lmp->l_msg_rtime;
+ bmp->msg_ctime = lmp->l_msg_ctime;
+}
+
+static void
+bsd_to_linux_msqid_ds(bmp, lmp)
+ struct msqid_ds *bmp;
+ struct linux_msqid_ds *lmp;
+{
+ bsd_to_linux_ipc_perm(&bmp->msg_perm, &lmp->l_msg_perm);
+ lmp->l_msg_first = bmp->msg_first;
+ lmp->l_msg_last = bmp->msg_last;
+ lmp->l_msg_cbytes = bmp->msg_cbytes;
+ lmp->l_msg_qnum = bmp->msg_qnum;
+ lmp->l_msg_qbytes = bmp->msg_qbytes;
+ lmp->l_msg_lspid = bmp->msg_lspid;
+ lmp->l_msg_lrpid = bmp->msg_lrpid;
+ lmp->l_msg_stime = bmp->msg_stime;
+ lmp->l_msg_rtime = bmp->msg_rtime;
+ lmp->l_msg_ctime = bmp->msg_ctime;
+}
+
int
linux_msgsnd(p, uap, retval)
struct proc *p;
@@ -245,7 +391,14 @@ linux_msgsnd(p, uap, retval)
} */ *uap;
register_t *retval;
{
- return ENOSYS;
+ struct msgsnd_args bma;
+
+ SCARG(&bma, msqid) = SCARG(uap, a1);
+ SCARG(&bma, msgp) = SCARG(uap, ptr);
+ SCARG(&bma, msgsz) = SCARG(uap, a2);
+ SCARG(&bma, msgflg) = SCARG(uap, a3);
+
+ return msgsnd(p, &bma, retval);
}
int
@@ -260,7 +413,19 @@ linux_msgrcv(p, uap, retval)
} */ *uap;
register_t *retval;
{
- return ENOSYS;
+ struct msgrcv_args bma;
+ struct linux_msgrcv_msgarg kluge;
+ int error;
+
+ if ((error = copyin(SCARG(uap, ptr), &kluge, sizeof kluge)))
+ return error;
+
+ SCARG(&bma, msqid) = SCARG(uap, a1);
+ SCARG(&bma, msgp) = kluge.msg;
+ SCARG(&bma, msgsz) = SCARG(uap, a2);
+ SCARG(&bma, msgtyp) = kluge.type;
+ SCARG(&bma, msgflg) = SCARG(uap, a3);
+ return msgrcv(p, &bma, retval);
}
int
@@ -275,7 +440,11 @@ linux_msgget(p, uap, retval)
} */ *uap;
register_t *retval;
{
- return ENOSYS;
+ struct msgget_args bma;
+
+ SCARG(&bma, key) = (key_t)SCARG(uap, a1);
+ SCARG(&bma, msgflg) = SCARG(uap, a2);
+ return msgget(p, &bma, retval);
}
int
@@ -290,7 +459,39 @@ linux_msgctl(p, uap, retval)
} */ *uap;
register_t *retval;
{
- return ENOSYS;
+ struct msgctl_args bma;
+ caddr_t umsgptr, sg;
+ struct linux_msqid_ds lm;
+ struct msqid_ds bm;
+ int error;
+
+ SCARG(&bma, msqid) = SCARG(uap, a1);
+ SCARG(&bma, cmd) = SCARG(uap, a2);
+ switch (SCARG(uap, a2)) {
+ case LINUX_IPC_RMID:
+ return msgctl(p, &bma, retval);
+ case LINUX_IPC_SET:
+ if ((error = copyin(SCARG(uap, ptr), (caddr_t)&lm, sizeof lm)))
+ return error;
+ linux_to_bsd_msqid_ds(&lm, &bm);
+ sg = stackgap_init(p->p_emul);
+ umsgptr = stackgap_alloc(&sg, sizeof bm);
+ if ((error = copyout((caddr_t)&bm, umsgptr, sizeof bm)))
+ return error;
+ SCARG(&bma, buf) = (struct msqid_ds *)umsgptr;
+ return msgctl(p, &bma, retval);
+ case LINUX_IPC_STAT:
+ sg = stackgap_init(p->p_emul);
+ umsgptr = stackgap_alloc(&sg, sizeof (struct msqid_ds));
+ SCARG(&bma, buf) = (struct msqid_ds *)umsgptr;
+ if ((error = msgctl(p, &bma, retval)))
+ return error;
+ if ((error = copyin(umsgptr, (caddr_t)&bm, sizeof bm)))
+ return error;
+ bsd_to_linux_msqid_ds(&bm, &lm);
+ return copyout((caddr_t)&lm, SCARG(uap, ptr), sizeof lm);
+ }
+ return EINVAL;
}
#endif /* SYSVMSG */
diff --git a/sys/compat/linux/common/linux_ipccall.c b/sys/compat/linux/common/linux_ipccall.c
index 6f6dc728228..a1aceff5ba5 100644
--- a/sys/compat/linux/common/linux_ipccall.c
+++ b/sys/compat/linux/common/linux_ipccall.c
@@ -1,4 +1,4 @@
-/* $NetBSD: linux_ipccall.c,v 1.5 1995/08/14 01:27:52 mycroft Exp $ */
+/* $NetBSD: linux_ipccall.c,v 1.6 1995/08/15 21:14:32 fvdl Exp $ */
/*
* Copyright (c) 1995 Frank van der Linden
@@ -35,6 +35,7 @@
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/shm.h>
+#include <sys/sem.h>
#include <sys/msg.h>
#include <sys/proc.h>
#include <sys/uio.h>
@@ -54,6 +55,7 @@
#include <compat/linux/linux_ipc.h>
#include <compat/linux/linux_msg.h>
#include <compat/linux/linux_shm.h>
+#include <compat/linux/linux_sem.h>
#include <compat/linux/linux_ipccall.h>
/*
@@ -114,35 +116,35 @@ linux_ipc(p, uap, retval)
switch (SCARG(uap, what)) {
#ifdef SYSVSEM
- case LINUX_SYS_semop:
- return linux_semop(p, uap, retval);
- case LINUX_SYS_semget:
- return linux_semget(p, uap, retval);
- case LINUX_SYS_semctl:
- return linux_semctl(p, uap, retval);
+ case LINUX_SYS_semop:
+ return linux_semop(p, uap, retval);
+ case LINUX_SYS_semget:
+ return linux_semget(p, uap, retval);
+ case LINUX_SYS_semctl:
+ return linux_semctl(p, uap, retval);
#endif
#ifdef SYSVMSG
- case LINUX_SYS_msgsnd:
- return linux_msgsnd(p, uap, retval);
- case LINUX_SYS_msgrcv:
- return linux_msgrcv(p, uap, retval);
- case LINUX_SYS_msgget:
- return linux_msgget(p, uap, retval);
- case LINUX_SYS_msgctl:
- return linux_msgctl(p, uap, retval);
+ case LINUX_SYS_msgsnd:
+ return linux_msgsnd(p, uap, retval);
+ case LINUX_SYS_msgrcv:
+ return linux_msgrcv(p, uap, retval);
+ case LINUX_SYS_msgget:
+ return linux_msgget(p, uap, retval);
+ case LINUX_SYS_msgctl:
+ return linux_msgctl(p, uap, retval);
#endif
#ifdef SYSVSHM
- case LINUX_SYS_shmat:
- return linux_shmat(p, uap, retval);
- case LINUX_SYS_shmdt:
- return linux_shmdt(p, uap, retval);
- case LINUX_SYS_shmget:
- return linux_shmget(p, uap, retval);
- case LINUX_SYS_shmctl:
- return linux_shmctl(p, uap, retval);
+ case LINUX_SYS_shmat:
+ return linux_shmat(p, uap, retval);
+ case LINUX_SYS_shmdt:
+ return linux_shmdt(p, uap, retval);
+ case LINUX_SYS_shmget:
+ return linux_shmget(p, uap, retval);
+ case LINUX_SYS_shmctl:
+ return linux_shmctl(p, uap, retval);
#endif
- default:
- return ENOSYS;
+ default:
+ return ENOSYS;
}
}
@@ -181,8 +183,37 @@ bsd_to_linux_ipc_perm(bpp, lpp)
#ifdef SYSVSEM
/*
- * Semaphore operations: not implemented yet.
+ * Semaphore operations. Most constants and structures are the same on
+ * both systems. Only semctl() needs some extra work.
*/
+
+/*
+ * Convert between Linux and NetBSD semid_ds structures.
+ */
+static void
+bsd_to_linux_semid_ds(bs, ls)
+ struct semid_ds *bs;
+ struct linux_semid_ds *ls;
+{
+ bsd_to_linux_ipc_perm(&bs->sem_perm, &ls->l_sem_perm);
+ ls->l_sem_otime = bs->sem_otime;
+ ls->l_sem_ctime = bs->sem_ctime;
+ ls->l_sem_nsems = bs->sem_nsems;
+ ls->l_sem_base = bs->sem_base;
+}
+
+static void
+linux_to_bsd_semid_ds(ls, bs)
+ struct linux_semid_ds *ls;
+ struct semid_ds *bs;
+{
+ linux_to_bsd_ipc_perm(&ls->l_sem_perm, &bs->sem_perm);
+ bs->sem_otime = ls->l_sem_otime;
+ bs->sem_ctime = ls->l_sem_ctime;
+ bs->sem_nsems = ls->l_sem_nsems;
+ bs->sem_base = ls->l_sem_base;
+}
+
int
linux_semop(p, uap, retval)
struct proc *p;
@@ -195,7 +226,13 @@ linux_semop(p, uap, retval)
} */ *uap;
register_t *retval;
{
- return ENOSYS;
+ struct semop_args bsa;
+
+ SCARG(&bsa, semid) = SCARG(uap, a1);
+ SCARG(&bsa, sops) = (struct sembuf *)SCARG(uap, ptr);
+ SCARG(&bsa, nsops) = SCARG(uap, a2);
+
+ return semop(p, &bsa, retval);
}
int
@@ -210,9 +247,21 @@ linux_semget(p, uap, retval)
} */ *uap;
register_t *retval;
{
- return ENOSYS;
+ struct semget_args bsa;
+
+ SCARG(&bsa, key) = (key_t)SCARG(uap, a1);
+ SCARG(&bsa, nsems) = SCARG(uap, a2);
+ SCARG(&bsa, semflg) = SCARG(uap, a3);
+
+ return semget(p, &bsa, retval);
}
+/*
+ * Most of this can be handled by directly passing the arguments on,
+ * buf IPC_* require a lot of copy{in,out} because of the extra indirection
+ * (we are passed a pointer to a union cointaining a pointer to a semid_ds
+ * structure.
+ */
int
linux_semctl(p, uap, retval)
struct proc *p;
@@ -225,14 +274,111 @@ linux_semctl(p, uap, retval)
} */ *uap;
register_t *retval;
{
- return ENOSYS;
+ caddr_t sg, unptr, dsp, ldsp;
+ int error, cmd;
+ struct __semctl_args bsa;
+ struct linux_semid_ds lm;
+ struct semid_ds bm;
+
+ SCARG(&bsa, semid) = SCARG(uap, a1);
+ SCARG(&bsa, semnum) = SCARG(uap, a2);
+ SCARG(&bsa, cmd) = SCARG(uap, a3);
+ SCARG(&bsa, arg) = (union semun *)SCARG(uap, ptr);
+ switch(SCARG(uap, a3)) {
+ case LINUX_GETVAL:
+ cmd = GETVAL;
+ break;
+ case LINUX_GETPID:
+ cmd = GETPID;
+ break;
+ case LINUX_GETNCNT:
+ cmd = GETNCNT;
+ break;
+ case LINUX_GETZCNT:
+ cmd = GETZCNT;
+ break;
+ case LINUX_SETVAL:
+ cmd = SETVAL;
+ break;
+ case LINUX_IPC_RMID:
+ cmd = IPC_RMID;
+ break;
+ case LINUX_IPC_SET:
+ if ((error = copyin(SCARG(uap, ptr), &ldsp, sizeof ldsp)))
+ return error;
+ if ((error = copyin(ldsp, (caddr_t)&lm, sizeof lm)))
+ return error;
+ linux_to_bsd_semid_ds(&lm, &bm);
+ sg = stackgap_init(p->p_emul);
+ unptr = stackgap_alloc(&sg, sizeof (union semun));
+ dsp = stackgap_alloc(&sg, sizeof (struct semid_ds));
+ if ((error = copyout((caddr_t)&bm, dsp, sizeof bm)))
+ return error;
+ if ((error = copyout((caddr_t)&dsp, unptr, sizeof dsp)))
+ return error;
+ SCARG(&bsa, arg) = (union semun *)unptr;
+ return __semctl(p, &bsa, retval);
+ case LINUX_IPC_STAT:
+ sg = stackgap_init(p->p_emul);
+ unptr = stackgap_alloc(&sg, sizeof (union semun *));
+ dsp = stackgap_alloc(&sg, sizeof (struct semid_ds));
+ if ((error = copyout((caddr_t)&dsp, unptr, sizeof dsp)))
+ return error;
+ SCARG(&bsa, arg) = (union semun *)unptr;
+ if ((error = __semctl(p, &bsa, retval)))
+ return error;
+ if ((error = copyin(dsp, (caddr_t)&bm, sizeof bm)))
+ return error;
+ bsd_to_linux_semid_ds(&bm, &lm);
+ if ((error = copyin(SCARG(uap, ptr), &ldsp, sizeof ldsp)))
+ return error;
+ return copyout((caddr_t)&lm, ldsp, sizeof lm);
+ default:
+ return EINVAL;
+ }
+ SCARG(&bsa, cmd) = cmd;
+ return __semctl(p, &bsa, retval);
}
#endif /* SYSVSEM */
#ifdef SYSVMSG
-/*
- * Msg functions: not implemented yet.
- */
+
+static void
+linux_to_bsd_msqid_ds(lmp, bmp)
+ struct linux_msqid_ds *lmp;
+ struct msqid_ds *bmp;
+{
+ linux_to_bsd_ipc_perm(&lmp->l_msg_perm, &bmp->msg_perm);
+ bmp->msg_first = lmp->l_msg_first;
+ bmp->msg_last = lmp->l_msg_last;
+ bmp->msg_cbytes = lmp->l_msg_cbytes;
+ bmp->msg_qnum = lmp->l_msg_qnum;
+ bmp->msg_qbytes = lmp->l_msg_qbytes;
+ bmp->msg_lspid = lmp->l_msg_lspid;
+ bmp->msg_lrpid = lmp->l_msg_lrpid;
+ bmp->msg_stime = lmp->l_msg_stime;
+ bmp->msg_rtime = lmp->l_msg_rtime;
+ bmp->msg_ctime = lmp->l_msg_ctime;
+}
+
+static void
+bsd_to_linux_msqid_ds(bmp, lmp)
+ struct msqid_ds *bmp;
+ struct linux_msqid_ds *lmp;
+{
+ bsd_to_linux_ipc_perm(&bmp->msg_perm, &lmp->l_msg_perm);
+ lmp->l_msg_first = bmp->msg_first;
+ lmp->l_msg_last = bmp->msg_last;
+ lmp->l_msg_cbytes = bmp->msg_cbytes;
+ lmp->l_msg_qnum = bmp->msg_qnum;
+ lmp->l_msg_qbytes = bmp->msg_qbytes;
+ lmp->l_msg_lspid = bmp->msg_lspid;
+ lmp->l_msg_lrpid = bmp->msg_lrpid;
+ lmp->l_msg_stime = bmp->msg_stime;
+ lmp->l_msg_rtime = bmp->msg_rtime;
+ lmp->l_msg_ctime = bmp->msg_ctime;
+}
+
int
linux_msgsnd(p, uap, retval)
struct proc *p;
@@ -245,7 +391,14 @@ linux_msgsnd(p, uap, retval)
} */ *uap;
register_t *retval;
{
- return ENOSYS;
+ struct msgsnd_args bma;
+
+ SCARG(&bma, msqid) = SCARG(uap, a1);
+ SCARG(&bma, msgp) = SCARG(uap, ptr);
+ SCARG(&bma, msgsz) = SCARG(uap, a2);
+ SCARG(&bma, msgflg) = SCARG(uap, a3);
+
+ return msgsnd(p, &bma, retval);
}
int
@@ -260,7 +413,19 @@ linux_msgrcv(p, uap, retval)
} */ *uap;
register_t *retval;
{
- return ENOSYS;
+ struct msgrcv_args bma;
+ struct linux_msgrcv_msgarg kluge;
+ int error;
+
+ if ((error = copyin(SCARG(uap, ptr), &kluge, sizeof kluge)))
+ return error;
+
+ SCARG(&bma, msqid) = SCARG(uap, a1);
+ SCARG(&bma, msgp) = kluge.msg;
+ SCARG(&bma, msgsz) = SCARG(uap, a2);
+ SCARG(&bma, msgtyp) = kluge.type;
+ SCARG(&bma, msgflg) = SCARG(uap, a3);
+ return msgrcv(p, &bma, retval);
}
int
@@ -275,7 +440,11 @@ linux_msgget(p, uap, retval)
} */ *uap;
register_t *retval;
{
- return ENOSYS;
+ struct msgget_args bma;
+
+ SCARG(&bma, key) = (key_t)SCARG(uap, a1);
+ SCARG(&bma, msgflg) = SCARG(uap, a2);
+ return msgget(p, &bma, retval);
}
int
@@ -290,7 +459,39 @@ linux_msgctl(p, uap, retval)
} */ *uap;
register_t *retval;
{
- return ENOSYS;
+ struct msgctl_args bma;
+ caddr_t umsgptr, sg;
+ struct linux_msqid_ds lm;
+ struct msqid_ds bm;
+ int error;
+
+ SCARG(&bma, msqid) = SCARG(uap, a1);
+ SCARG(&bma, cmd) = SCARG(uap, a2);
+ switch (SCARG(uap, a2)) {
+ case LINUX_IPC_RMID:
+ return msgctl(p, &bma, retval);
+ case LINUX_IPC_SET:
+ if ((error = copyin(SCARG(uap, ptr), (caddr_t)&lm, sizeof lm)))
+ return error;
+ linux_to_bsd_msqid_ds(&lm, &bm);
+ sg = stackgap_init(p->p_emul);
+ umsgptr = stackgap_alloc(&sg, sizeof bm);
+ if ((error = copyout((caddr_t)&bm, umsgptr, sizeof bm)))
+ return error;
+ SCARG(&bma, buf) = (struct msqid_ds *)umsgptr;
+ return msgctl(p, &bma, retval);
+ case LINUX_IPC_STAT:
+ sg = stackgap_init(p->p_emul);
+ umsgptr = stackgap_alloc(&sg, sizeof (struct msqid_ds));
+ SCARG(&bma, buf) = (struct msqid_ds *)umsgptr;
+ if ((error = msgctl(p, &bma, retval)))
+ return error;
+ if ((error = copyin(umsgptr, (caddr_t)&bm, sizeof bm)))
+ return error;
+ bsd_to_linux_msqid_ds(&bm, &lm);
+ return copyout((caddr_t)&lm, SCARG(uap, ptr), sizeof lm);
+ }
+ return EINVAL;
}
#endif /* SYSVMSG */
diff --git a/sys/compat/linux/common/linux_ipccall.h b/sys/compat/linux/common/linux_ipccall.h
index 42f166b5402..854b641dac2 100644
--- a/sys/compat/linux/common/linux_ipccall.h
+++ b/sys/compat/linux/common/linux_ipccall.h
@@ -1,4 +1,4 @@
-/* $NetBSD: linux_ipccall.h,v 1.1 1995/02/28 23:25:50 fvdl Exp $ */
+/* $NetBSD: linux_ipccall.h,v 1.2 1995/08/15 21:14:33 fvdl Exp $ */
/*
* Copyright (c) 1995 Frank van der Linden
@@ -51,13 +51,4 @@
#define LINUX_SYS_shmget 23
#define LINUX_SYS_shmctl 24
-/*
- * This kludge is used for the 6th argument to the msgrcv system
- * call, to get around the maximum of 5 arguments to a syscall in Linux.
- */
-struct linux_ipc_kludge {
- struct linux_msgbuf *msg;
- int type;
-};
-
#endif /* _LINUX_IPC_CALL_H */
diff --git a/sys/compat/linux/common/linux_msg.h b/sys/compat/linux/common/linux_msg.h
index 9abd614f8b5..b7858236dbb 100644
--- a/sys/compat/linux/common/linux_msg.h
+++ b/sys/compat/linux/common/linux_msg.h
@@ -1,4 +1,4 @@
-/* $NetBSD: linux_msg.h,v 1.1 1995/02/28 23:25:54 fvdl Exp $ */
+/* $NetBSD: linux_msg.h,v 1.2 1995/08/15 21:14:34 fvdl Exp $ */
/*
* Copyright (c) 1995 Frank van der Linden
@@ -40,8 +40,8 @@
*/
struct linux_msqid_ds {
struct linux_ipc_perm l_msg_perm;
- struct linux_msg *l_msg_first;
- struct linux_msg *l_msg_last;
+ void *l_msg_first;
+ void *l_msg_last;
linux_time_t l_msg_stime;
linux_time_t l_msg_rtime;
linux_time_t l_msg_ctime;
@@ -66,6 +66,14 @@ struct linux_mymsg {
};
/*
+ * This kludge is used for the 6th argument to the msgrcv system
+ * call, to get around the maximum of 5 arguments to a syscall in Linux.
+ */
+struct linux_msgrcv_msgarg {
+ struct linux_mymsg *msg;
+ int type;
+};
+/*
* For msgctl calls.
*/
struct linux_msginfo {
diff --git a/sys/compat/linux/common/linux_sem.h b/sys/compat/linux/common/linux_sem.h
new file mode 100644
index 00000000000..8cfbdab7f9a
--- /dev/null
+++ b/sys/compat/linux/common/linux_sem.h
@@ -0,0 +1,72 @@
+/* $NetBSD: linux_sem.h,v 1.1 1995/08/15 21:14:35 fvdl Exp $ */
+
+/*
+ * Copyright (c) 1995 Frank van der Linden
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed for the NetBSD Project
+ * by Frank van der Linden
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _LINUX_SEM_H
+#define _LINUX_SEM_H
+
+/*
+ * Operations for semctl(2), in addition to IPC_STAT and IPC_SET
+ */
+#define LINUX_GETPID 11
+#define LINUX_GETVAL 12
+#define LINUX_GETALL 13
+#define LINUX_GETNCNT 14
+#define LINUX_GETZCNT 15
+#define LINUX_SETVAL 16
+#define LINUX_SETALL 17
+
+/*
+ * Linux semid_ds structure. Internally used pointer fields are not
+ * important to us and have been changed to void *
+ */
+
+struct linux_semid_ds {
+ struct linux_ipc_perm l_sem_perm;
+ linux_time_t l_sem_otime;
+ linux_time_t l_sem_ctime;
+ void *l_sem_base;
+ void *l_eventn;
+ void *l_eventz;
+ void *l_undo;
+ ushort l_sem_nsems;
+};
+
+union linux_semun {
+ int l_val;
+ struct linux_semid_ds *l_buf;
+ ushort *l_array;
+ void *l___buf; /* For unsupported IPC_INFO */
+ void *l___pad;
+};
+
+#endif /* _LINUX_SEM_H */
diff --git a/sys/compat/linux/include/linux_ipccall.h b/sys/compat/linux/include/linux_ipccall.h
index 42f166b5402..854b641dac2 100644
--- a/sys/compat/linux/include/linux_ipccall.h
+++ b/sys/compat/linux/include/linux_ipccall.h
@@ -1,4 +1,4 @@
-/* $NetBSD: linux_ipccall.h,v 1.1 1995/02/28 23:25:50 fvdl Exp $ */
+/* $NetBSD: linux_ipccall.h,v 1.2 1995/08/15 21:14:33 fvdl Exp $ */
/*
* Copyright (c) 1995 Frank van der Linden
@@ -51,13 +51,4 @@
#define LINUX_SYS_shmget 23
#define LINUX_SYS_shmctl 24
-/*
- * This kludge is used for the 6th argument to the msgrcv system
- * call, to get around the maximum of 5 arguments to a syscall in Linux.
- */
-struct linux_ipc_kludge {
- struct linux_msgbuf *msg;
- int type;
-};
-
#endif /* _LINUX_IPC_CALL_H */
diff --git a/sys/compat/linux/include/linux_msg.h b/sys/compat/linux/include/linux_msg.h
index 9abd614f8b5..b7858236dbb 100644
--- a/sys/compat/linux/include/linux_msg.h
+++ b/sys/compat/linux/include/linux_msg.h
@@ -1,4 +1,4 @@
-/* $NetBSD: linux_msg.h,v 1.1 1995/02/28 23:25:54 fvdl Exp $ */
+/* $NetBSD: linux_msg.h,v 1.2 1995/08/15 21:14:34 fvdl Exp $ */
/*
* Copyright (c) 1995 Frank van der Linden
@@ -40,8 +40,8 @@
*/
struct linux_msqid_ds {
struct linux_ipc_perm l_msg_perm;
- struct linux_msg *l_msg_first;
- struct linux_msg *l_msg_last;
+ void *l_msg_first;
+ void *l_msg_last;
linux_time_t l_msg_stime;
linux_time_t l_msg_rtime;
linux_time_t l_msg_ctime;
@@ -66,6 +66,14 @@ struct linux_mymsg {
};
/*
+ * This kludge is used for the 6th argument to the msgrcv system
+ * call, to get around the maximum of 5 arguments to a syscall in Linux.
+ */
+struct linux_msgrcv_msgarg {
+ struct linux_mymsg *msg;
+ int type;
+};
+/*
* For msgctl calls.
*/
struct linux_msginfo {
diff --git a/sys/compat/linux/include/linux_sem.h b/sys/compat/linux/include/linux_sem.h
new file mode 100644
index 00000000000..8cfbdab7f9a
--- /dev/null
+++ b/sys/compat/linux/include/linux_sem.h
@@ -0,0 +1,72 @@
+/* $NetBSD: linux_sem.h,v 1.1 1995/08/15 21:14:35 fvdl Exp $ */
+
+/*
+ * Copyright (c) 1995 Frank van der Linden
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed for the NetBSD Project
+ * by Frank van der Linden
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _LINUX_SEM_H
+#define _LINUX_SEM_H
+
+/*
+ * Operations for semctl(2), in addition to IPC_STAT and IPC_SET
+ */
+#define LINUX_GETPID 11
+#define LINUX_GETVAL 12
+#define LINUX_GETALL 13
+#define LINUX_GETNCNT 14
+#define LINUX_GETZCNT 15
+#define LINUX_SETVAL 16
+#define LINUX_SETALL 17
+
+/*
+ * Linux semid_ds structure. Internally used pointer fields are not
+ * important to us and have been changed to void *
+ */
+
+struct linux_semid_ds {
+ struct linux_ipc_perm l_sem_perm;
+ linux_time_t l_sem_otime;
+ linux_time_t l_sem_ctime;
+ void *l_sem_base;
+ void *l_eventn;
+ void *l_eventz;
+ void *l_undo;
+ ushort l_sem_nsems;
+};
+
+union linux_semun {
+ int l_val;
+ struct linux_semid_ds *l_buf;
+ ushort *l_array;
+ void *l___buf; /* For unsupported IPC_INFO */
+ void *l___pad;
+};
+
+#endif /* _LINUX_SEM_H */
diff --git a/sys/compat/linux/linux_ipc.c b/sys/compat/linux/linux_ipc.c
index 984a07f155c..dbef9670c57 100644
--- a/sys/compat/linux/linux_ipc.c
+++ b/sys/compat/linux/linux_ipc.c
@@ -1,4 +1,4 @@
-/* $NetBSD: linux_ipc.c,v 1.5 1995/08/14 01:27:52 mycroft Exp $ */
+/* $NetBSD: linux_ipc.c,v 1.6 1995/08/15 21:14:32 fvdl Exp $ */
/*
* Copyright (c) 1995 Frank van der Linden
@@ -35,6 +35,7 @@
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/shm.h>
+#include <sys/sem.h>
#include <sys/msg.h>
#include <sys/proc.h>
#include <sys/uio.h>
@@ -54,6 +55,7 @@
#include <compat/linux/linux_ipc.h>
#include <compat/linux/linux_msg.h>
#include <compat/linux/linux_shm.h>
+#include <compat/linux/linux_sem.h>
#include <compat/linux/linux_ipccall.h>
/*
@@ -114,35 +116,35 @@ linux_ipc(p, uap, retval)
switch (SCARG(uap, what)) {
#ifdef SYSVSEM
- case LINUX_SYS_semop:
- return linux_semop(p, uap, retval);
- case LINUX_SYS_semget:
- return linux_semget(p, uap, retval);
- case LINUX_SYS_semctl:
- return linux_semctl(p, uap, retval);
+ case LINUX_SYS_semop:
+ return linux_semop(p, uap, retval);
+ case LINUX_SYS_semget:
+ return linux_semget(p, uap, retval);
+ case LINUX_SYS_semctl:
+ return linux_semctl(p, uap, retval);
#endif
#ifdef SYSVMSG
- case LINUX_SYS_msgsnd:
- return linux_msgsnd(p, uap, retval);
- case LINUX_SYS_msgrcv:
- return linux_msgrcv(p, uap, retval);
- case LINUX_SYS_msgget:
- return linux_msgget(p, uap, retval);
- case LINUX_SYS_msgctl:
- return linux_msgctl(p, uap, retval);
+ case LINUX_SYS_msgsnd:
+ return linux_msgsnd(p, uap, retval);
+ case LINUX_SYS_msgrcv:
+ return linux_msgrcv(p, uap, retval);
+ case LINUX_SYS_msgget:
+ return linux_msgget(p, uap, retval);
+ case LINUX_SYS_msgctl:
+ return linux_msgctl(p, uap, retval);
#endif
#ifdef SYSVSHM
- case LINUX_SYS_shmat:
- return linux_shmat(p, uap, retval);
- case LINUX_SYS_shmdt:
- return linux_shmdt(p, uap, retval);
- case LINUX_SYS_shmget:
- return linux_shmget(p, uap, retval);
- case LINUX_SYS_shmctl:
- return linux_shmctl(p, uap, retval);
+ case LINUX_SYS_shmat:
+ return linux_shmat(p, uap, retval);
+ case LINUX_SYS_shmdt:
+ return linux_shmdt(p, uap, retval);
+ case LINUX_SYS_shmget:
+ return linux_shmget(p, uap, retval);
+ case LINUX_SYS_shmctl:
+ return linux_shmctl(p, uap, retval);
#endif
- default:
- return ENOSYS;
+ default:
+ return ENOSYS;
}
}
@@ -181,8 +183,37 @@ bsd_to_linux_ipc_perm(bpp, lpp)
#ifdef SYSVSEM
/*
- * Semaphore operations: not implemented yet.
+ * Semaphore operations. Most constants and structures are the same on
+ * both systems. Only semctl() needs some extra work.
*/
+
+/*
+ * Convert between Linux and NetBSD semid_ds structures.
+ */
+static void
+bsd_to_linux_semid_ds(bs, ls)
+ struct semid_ds *bs;
+ struct linux_semid_ds *ls;
+{
+ bsd_to_linux_ipc_perm(&bs->sem_perm, &ls->l_sem_perm);
+ ls->l_sem_otime = bs->sem_otime;
+ ls->l_sem_ctime = bs->sem_ctime;
+ ls->l_sem_nsems = bs->sem_nsems;
+ ls->l_sem_base = bs->sem_base;
+}
+
+static void
+linux_to_bsd_semid_ds(ls, bs)
+ struct linux_semid_ds *ls;
+ struct semid_ds *bs;
+{
+ linux_to_bsd_ipc_perm(&ls->l_sem_perm, &bs->sem_perm);
+ bs->sem_otime = ls->l_sem_otime;
+ bs->sem_ctime = ls->l_sem_ctime;
+ bs->sem_nsems = ls->l_sem_nsems;
+ bs->sem_base = ls->l_sem_base;
+}
+
int
linux_semop(p, uap, retval)
struct proc *p;
@@ -195,7 +226,13 @@ linux_semop(p, uap, retval)
} */ *uap;
register_t *retval;
{
- return ENOSYS;
+ struct semop_args bsa;
+
+ SCARG(&bsa, semid) = SCARG(uap, a1);
+ SCARG(&bsa, sops) = (struct sembuf *)SCARG(uap, ptr);
+ SCARG(&bsa, nsops) = SCARG(uap, a2);
+
+ return semop(p, &bsa, retval);
}
int
@@ -210,9 +247,21 @@ linux_semget(p, uap, retval)
} */ *uap;
register_t *retval;
{
- return ENOSYS;
+ struct semget_args bsa;
+
+ SCARG(&bsa, key) = (key_t)SCARG(uap, a1);
+ SCARG(&bsa, nsems) = SCARG(uap, a2);
+ SCARG(&bsa, semflg) = SCARG(uap, a3);
+
+ return semget(p, &bsa, retval);
}
+/*
+ * Most of this can be handled by directly passing the arguments on,
+ * buf IPC_* require a lot of copy{in,out} because of the extra indirection
+ * (we are passed a pointer to a union cointaining a pointer to a semid_ds
+ * structure.
+ */
int
linux_semctl(p, uap, retval)
struct proc *p;
@@ -225,14 +274,111 @@ linux_semctl(p, uap, retval)
} */ *uap;
register_t *retval;
{
- return ENOSYS;
+ caddr_t sg, unptr, dsp, ldsp;
+ int error, cmd;
+ struct __semctl_args bsa;
+ struct linux_semid_ds lm;
+ struct semid_ds bm;
+
+ SCARG(&bsa, semid) = SCARG(uap, a1);
+ SCARG(&bsa, semnum) = SCARG(uap, a2);
+ SCARG(&bsa, cmd) = SCARG(uap, a3);
+ SCARG(&bsa, arg) = (union semun *)SCARG(uap, ptr);
+ switch(SCARG(uap, a3)) {
+ case LINUX_GETVAL:
+ cmd = GETVAL;
+ break;
+ case LINUX_GETPID:
+ cmd = GETPID;
+ break;
+ case LINUX_GETNCNT:
+ cmd = GETNCNT;
+ break;
+ case LINUX_GETZCNT:
+ cmd = GETZCNT;
+ break;
+ case LINUX_SETVAL:
+ cmd = SETVAL;
+ break;
+ case LINUX_IPC_RMID:
+ cmd = IPC_RMID;
+ break;
+ case LINUX_IPC_SET:
+ if ((error = copyin(SCARG(uap, ptr), &ldsp, sizeof ldsp)))
+ return error;
+ if ((error = copyin(ldsp, (caddr_t)&lm, sizeof lm)))
+ return error;
+ linux_to_bsd_semid_ds(&lm, &bm);
+ sg = stackgap_init(p->p_emul);
+ unptr = stackgap_alloc(&sg, sizeof (union semun));
+ dsp = stackgap_alloc(&sg, sizeof (struct semid_ds));
+ if ((error = copyout((caddr_t)&bm, dsp, sizeof bm)))
+ return error;
+ if ((error = copyout((caddr_t)&dsp, unptr, sizeof dsp)))
+ return error;
+ SCARG(&bsa, arg) = (union semun *)unptr;
+ return __semctl(p, &bsa, retval);
+ case LINUX_IPC_STAT:
+ sg = stackgap_init(p->p_emul);
+ unptr = stackgap_alloc(&sg, sizeof (union semun *));
+ dsp = stackgap_alloc(&sg, sizeof (struct semid_ds));
+ if ((error = copyout((caddr_t)&dsp, unptr, sizeof dsp)))
+ return error;
+ SCARG(&bsa, arg) = (union semun *)unptr;
+ if ((error = __semctl(p, &bsa, retval)))
+ return error;
+ if ((error = copyin(dsp, (caddr_t)&bm, sizeof bm)))
+ return error;
+ bsd_to_linux_semid_ds(&bm, &lm);
+ if ((error = copyin(SCARG(uap, ptr), &ldsp, sizeof ldsp)))
+ return error;
+ return copyout((caddr_t)&lm, ldsp, sizeof lm);
+ default:
+ return EINVAL;
+ }
+ SCARG(&bsa, cmd) = cmd;
+ return __semctl(p, &bsa, retval);
}
#endif /* SYSVSEM */
#ifdef SYSVMSG
-/*
- * Msg functions: not implemented yet.
- */
+
+static void
+linux_to_bsd_msqid_ds(lmp, bmp)
+ struct linux_msqid_ds *lmp;
+ struct msqid_ds *bmp;
+{
+ linux_to_bsd_ipc_perm(&lmp->l_msg_perm, &bmp->msg_perm);
+ bmp->msg_first = lmp->l_msg_first;
+ bmp->msg_last = lmp->l_msg_last;
+ bmp->msg_cbytes = lmp->l_msg_cbytes;
+ bmp->msg_qnum = lmp->l_msg_qnum;
+ bmp->msg_qbytes = lmp->l_msg_qbytes;
+ bmp->msg_lspid = lmp->l_msg_lspid;
+ bmp->msg_lrpid = lmp->l_msg_lrpid;
+ bmp->msg_stime = lmp->l_msg_stime;
+ bmp->msg_rtime = lmp->l_msg_rtime;
+ bmp->msg_ctime = lmp->l_msg_ctime;
+}
+
+static void
+bsd_to_linux_msqid_ds(bmp, lmp)
+ struct msqid_ds *bmp;
+ struct linux_msqid_ds *lmp;
+{
+ bsd_to_linux_ipc_perm(&bmp->msg_perm, &lmp->l_msg_perm);
+ lmp->l_msg_first = bmp->msg_first;
+ lmp->l_msg_last = bmp->msg_last;
+ lmp->l_msg_cbytes = bmp->msg_cbytes;
+ lmp->l_msg_qnum = bmp->msg_qnum;
+ lmp->l_msg_qbytes = bmp->msg_qbytes;
+ lmp->l_msg_lspid = bmp->msg_lspid;
+ lmp->l_msg_lrpid = bmp->msg_lrpid;
+ lmp->l_msg_stime = bmp->msg_stime;
+ lmp->l_msg_rtime = bmp->msg_rtime;
+ lmp->l_msg_ctime = bmp->msg_ctime;
+}
+
int
linux_msgsnd(p, uap, retval)
struct proc *p;
@@ -245,7 +391,14 @@ linux_msgsnd(p, uap, retval)
} */ *uap;
register_t *retval;
{
- return ENOSYS;
+ struct msgsnd_args bma;
+
+ SCARG(&bma, msqid) = SCARG(uap, a1);
+ SCARG(&bma, msgp) = SCARG(uap, ptr);
+ SCARG(&bma, msgsz) = SCARG(uap, a2);
+ SCARG(&bma, msgflg) = SCARG(uap, a3);
+
+ return msgsnd(p, &bma, retval);
}
int
@@ -260,7 +413,19 @@ linux_msgrcv(p, uap, retval)
} */ *uap;
register_t *retval;
{
- return ENOSYS;
+ struct msgrcv_args bma;
+ struct linux_msgrcv_msgarg kluge;
+ int error;
+
+ if ((error = copyin(SCARG(uap, ptr), &kluge, sizeof kluge)))
+ return error;
+
+ SCARG(&bma, msqid) = SCARG(uap, a1);
+ SCARG(&bma, msgp) = kluge.msg;
+ SCARG(&bma, msgsz) = SCARG(uap, a2);
+ SCARG(&bma, msgtyp) = kluge.type;
+ SCARG(&bma, msgflg) = SCARG(uap, a3);
+ return msgrcv(p, &bma, retval);
}
int
@@ -275,7 +440,11 @@ linux_msgget(p, uap, retval)
} */ *uap;
register_t *retval;
{
- return ENOSYS;
+ struct msgget_args bma;
+
+ SCARG(&bma, key) = (key_t)SCARG(uap, a1);
+ SCARG(&bma, msgflg) = SCARG(uap, a2);
+ return msgget(p, &bma, retval);
}
int
@@ -290,7 +459,39 @@ linux_msgctl(p, uap, retval)
} */ *uap;
register_t *retval;
{
- return ENOSYS;
+ struct msgctl_args bma;
+ caddr_t umsgptr, sg;
+ struct linux_msqid_ds lm;
+ struct msqid_ds bm;
+ int error;
+
+ SCARG(&bma, msqid) = SCARG(uap, a1);
+ SCARG(&bma, cmd) = SCARG(uap, a2);
+ switch (SCARG(uap, a2)) {
+ case LINUX_IPC_RMID:
+ return msgctl(p, &bma, retval);
+ case LINUX_IPC_SET:
+ if ((error = copyin(SCARG(uap, ptr), (caddr_t)&lm, sizeof lm)))
+ return error;
+ linux_to_bsd_msqid_ds(&lm, &bm);
+ sg = stackgap_init(p->p_emul);
+ umsgptr = stackgap_alloc(&sg, sizeof bm);
+ if ((error = copyout((caddr_t)&bm, umsgptr, sizeof bm)))
+ return error;
+ SCARG(&bma, buf) = (struct msqid_ds *)umsgptr;
+ return msgctl(p, &bma, retval);
+ case LINUX_IPC_STAT:
+ sg = stackgap_init(p->p_emul);
+ umsgptr = stackgap_alloc(&sg, sizeof (struct msqid_ds));
+ SCARG(&bma, buf) = (struct msqid_ds *)umsgptr;
+ if ((error = msgctl(p, &bma, retval)))
+ return error;
+ if ((error = copyin(umsgptr, (caddr_t)&bm, sizeof bm)))
+ return error;
+ bsd_to_linux_msqid_ds(&bm, &lm);
+ return copyout((caddr_t)&lm, SCARG(uap, ptr), sizeof lm);
+ }
+ return EINVAL;
}
#endif /* SYSVMSG */
diff --git a/sys/compat/linux/linux_ipccall.h b/sys/compat/linux/linux_ipccall.h
index 42f166b5402..854b641dac2 100644
--- a/sys/compat/linux/linux_ipccall.h
+++ b/sys/compat/linux/linux_ipccall.h
@@ -1,4 +1,4 @@
-/* $NetBSD: linux_ipccall.h,v 1.1 1995/02/28 23:25:50 fvdl Exp $ */
+/* $NetBSD: linux_ipccall.h,v 1.2 1995/08/15 21:14:33 fvdl Exp $ */
/*
* Copyright (c) 1995 Frank van der Linden
@@ -51,13 +51,4 @@
#define LINUX_SYS_shmget 23
#define LINUX_SYS_shmctl 24
-/*
- * This kludge is used for the 6th argument to the msgrcv system
- * call, to get around the maximum of 5 arguments to a syscall in Linux.
- */
-struct linux_ipc_kludge {
- struct linux_msgbuf *msg;
- int type;
-};
-
#endif /* _LINUX_IPC_CALL_H */
diff --git a/sys/compat/linux/linux_msg.h b/sys/compat/linux/linux_msg.h
index 9abd614f8b5..b7858236dbb 100644
--- a/sys/compat/linux/linux_msg.h
+++ b/sys/compat/linux/linux_msg.h
@@ -1,4 +1,4 @@
-/* $NetBSD: linux_msg.h,v 1.1 1995/02/28 23:25:54 fvdl Exp $ */
+/* $NetBSD: linux_msg.h,v 1.2 1995/08/15 21:14:34 fvdl Exp $ */
/*
* Copyright (c) 1995 Frank van der Linden
@@ -40,8 +40,8 @@
*/
struct linux_msqid_ds {
struct linux_ipc_perm l_msg_perm;
- struct linux_msg *l_msg_first;
- struct linux_msg *l_msg_last;
+ void *l_msg_first;
+ void *l_msg_last;
linux_time_t l_msg_stime;
linux_time_t l_msg_rtime;
linux_time_t l_msg_ctime;
@@ -66,6 +66,14 @@ struct linux_mymsg {
};
/*
+ * This kludge is used for the 6th argument to the msgrcv system
+ * call, to get around the maximum of 5 arguments to a syscall in Linux.
+ */
+struct linux_msgrcv_msgarg {
+ struct linux_mymsg *msg;
+ int type;
+};
+/*
* For msgctl calls.
*/
struct linux_msginfo {
diff --git a/sys/compat/linux/linux_sem.h b/sys/compat/linux/linux_sem.h
new file mode 100644
index 00000000000..8cfbdab7f9a
--- /dev/null
+++ b/sys/compat/linux/linux_sem.h
@@ -0,0 +1,72 @@
+/* $NetBSD: linux_sem.h,v 1.1 1995/08/15 21:14:35 fvdl Exp $ */
+
+/*
+ * Copyright (c) 1995 Frank van der Linden
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed for the NetBSD Project
+ * by Frank van der Linden
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _LINUX_SEM_H
+#define _LINUX_SEM_H
+
+/*
+ * Operations for semctl(2), in addition to IPC_STAT and IPC_SET
+ */
+#define LINUX_GETPID 11
+#define LINUX_GETVAL 12
+#define LINUX_GETALL 13
+#define LINUX_GETNCNT 14
+#define LINUX_GETZCNT 15
+#define LINUX_SETVAL 16
+#define LINUX_SETALL 17
+
+/*
+ * Linux semid_ds structure. Internally used pointer fields are not
+ * important to us and have been changed to void *
+ */
+
+struct linux_semid_ds {
+ struct linux_ipc_perm l_sem_perm;
+ linux_time_t l_sem_otime;
+ linux_time_t l_sem_ctime;
+ void *l_sem_base;
+ void *l_eventn;
+ void *l_eventz;
+ void *l_undo;
+ ushort l_sem_nsems;
+};
+
+union linux_semun {
+ int l_val;
+ struct linux_semid_ds *l_buf;
+ ushort *l_array;
+ void *l___buf; /* For unsupported IPC_INFO */
+ void *l___pad;
+};
+
+#endif /* _LINUX_SEM_H */
diff --git a/sys/compat/linux/multiarch/linux_ipccall.c b/sys/compat/linux/multiarch/linux_ipccall.c
index 6f6dc728228..a1aceff5ba5 100644
--- a/sys/compat/linux/multiarch/linux_ipccall.c
+++ b/sys/compat/linux/multiarch/linux_ipccall.c
@@ -1,4 +1,4 @@
-/* $NetBSD: linux_ipccall.c,v 1.5 1995/08/14 01:27:52 mycroft Exp $ */
+/* $NetBSD: linux_ipccall.c,v 1.6 1995/08/15 21:14:32 fvdl Exp $ */
/*
* Copyright (c) 1995 Frank van der Linden
@@ -35,6 +35,7 @@
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/shm.h>
+#include <sys/sem.h>
#include <sys/msg.h>
#include <sys/proc.h>
#include <sys/uio.h>
@@ -54,6 +55,7 @@
#include <compat/linux/linux_ipc.h>
#include <compat/linux/linux_msg.h>
#include <compat/linux/linux_shm.h>
+#include <compat/linux/linux_sem.h>
#include <compat/linux/linux_ipccall.h>
/*
@@ -114,35 +116,35 @@ linux_ipc(p, uap, retval)
switch (SCARG(uap, what)) {
#ifdef SYSVSEM
- case LINUX_SYS_semop:
- return linux_semop(p, uap, retval);
- case LINUX_SYS_semget:
- return linux_semget(p, uap, retval);
- case LINUX_SYS_semctl:
- return linux_semctl(p, uap, retval);
+ case LINUX_SYS_semop:
+ return linux_semop(p, uap, retval);
+ case LINUX_SYS_semget:
+ return linux_semget(p, uap, retval);
+ case LINUX_SYS_semctl:
+ return linux_semctl(p, uap, retval);
#endif
#ifdef SYSVMSG
- case LINUX_SYS_msgsnd:
- return linux_msgsnd(p, uap, retval);
- case LINUX_SYS_msgrcv:
- return linux_msgrcv(p, uap, retval);
- case LINUX_SYS_msgget:
- return linux_msgget(p, uap, retval);
- case LINUX_SYS_msgctl:
- return linux_msgctl(p, uap, retval);
+ case LINUX_SYS_msgsnd:
+ return linux_msgsnd(p, uap, retval);
+ case LINUX_SYS_msgrcv:
+ return linux_msgrcv(p, uap, retval);
+ case LINUX_SYS_msgget:
+ return linux_msgget(p, uap, retval);
+ case LINUX_SYS_msgctl:
+ return linux_msgctl(p, uap, retval);
#endif
#ifdef SYSVSHM
- case LINUX_SYS_shmat:
- return linux_shmat(p, uap, retval);
- case LINUX_SYS_shmdt:
- return linux_shmdt(p, uap, retval);
- case LINUX_SYS_shmget:
- return linux_shmget(p, uap, retval);
- case LINUX_SYS_shmctl:
- return linux_shmctl(p, uap, retval);
+ case LINUX_SYS_shmat:
+ return linux_shmat(p, uap, retval);
+ case LINUX_SYS_shmdt:
+ return linux_shmdt(p, uap, retval);
+ case LINUX_SYS_shmget:
+ return linux_shmget(p, uap, retval);
+ case LINUX_SYS_shmctl:
+ return linux_shmctl(p, uap, retval);
#endif
- default:
- return ENOSYS;
+ default:
+ return ENOSYS;
}
}
@@ -181,8 +183,37 @@ bsd_to_linux_ipc_perm(bpp, lpp)
#ifdef SYSVSEM
/*
- * Semaphore operations: not implemented yet.
+ * Semaphore operations. Most constants and structures are the same on
+ * both systems. Only semctl() needs some extra work.
*/
+
+/*
+ * Convert between Linux and NetBSD semid_ds structures.
+ */
+static void
+bsd_to_linux_semid_ds(bs, ls)
+ struct semid_ds *bs;
+ struct linux_semid_ds *ls;
+{
+ bsd_to_linux_ipc_perm(&bs->sem_perm, &ls->l_sem_perm);
+ ls->l_sem_otime = bs->sem_otime;
+ ls->l_sem_ctime = bs->sem_ctime;
+ ls->l_sem_nsems = bs->sem_nsems;
+ ls->l_sem_base = bs->sem_base;
+}
+
+static void
+linux_to_bsd_semid_ds(ls, bs)
+ struct linux_semid_ds *ls;
+ struct semid_ds *bs;
+{
+ linux_to_bsd_ipc_perm(&ls->l_sem_perm, &bs->sem_perm);
+ bs->sem_otime = ls->l_sem_otime;
+ bs->sem_ctime = ls->l_sem_ctime;
+ bs->sem_nsems = ls->l_sem_nsems;
+ bs->sem_base = ls->l_sem_base;
+}
+
int
linux_semop(p, uap, retval)
struct proc *p;
@@ -195,7 +226,13 @@ linux_semop(p, uap, retval)
} */ *uap;
register_t *retval;
{
- return ENOSYS;
+ struct semop_args bsa;
+
+ SCARG(&bsa, semid) = SCARG(uap, a1);
+ SCARG(&bsa, sops) = (struct sembuf *)SCARG(uap, ptr);
+ SCARG(&bsa, nsops) = SCARG(uap, a2);
+
+ return semop(p, &bsa, retval);
}
int
@@ -210,9 +247,21 @@ linux_semget(p, uap, retval)
} */ *uap;
register_t *retval;
{
- return ENOSYS;
+ struct semget_args bsa;
+
+ SCARG(&bsa, key) = (key_t)SCARG(uap, a1);
+ SCARG(&bsa, nsems) = SCARG(uap, a2);
+ SCARG(&bsa, semflg) = SCARG(uap, a3);
+
+ return semget(p, &bsa, retval);
}
+/*
+ * Most of this can be handled by directly passing the arguments on,
+ * buf IPC_* require a lot of copy{in,out} because of the extra indirection
+ * (we are passed a pointer to a union cointaining a pointer to a semid_ds
+ * structure.
+ */
int
linux_semctl(p, uap, retval)
struct proc *p;
@@ -225,14 +274,111 @@ linux_semctl(p, uap, retval)
} */ *uap;
register_t *retval;
{
- return ENOSYS;
+ caddr_t sg, unptr, dsp, ldsp;
+ int error, cmd;
+ struct __semctl_args bsa;
+ struct linux_semid_ds lm;
+ struct semid_ds bm;
+
+ SCARG(&bsa, semid) = SCARG(uap, a1);
+ SCARG(&bsa, semnum) = SCARG(uap, a2);
+ SCARG(&bsa, cmd) = SCARG(uap, a3);
+ SCARG(&bsa, arg) = (union semun *)SCARG(uap, ptr);
+ switch(SCARG(uap, a3)) {
+ case LINUX_GETVAL:
+ cmd = GETVAL;
+ break;
+ case LINUX_GETPID:
+ cmd = GETPID;
+ break;
+ case LINUX_GETNCNT:
+ cmd = GETNCNT;
+ break;
+ case LINUX_GETZCNT:
+ cmd = GETZCNT;
+ break;
+ case LINUX_SETVAL:
+ cmd = SETVAL;
+ break;
+ case LINUX_IPC_RMID:
+ cmd = IPC_RMID;
+ break;
+ case LINUX_IPC_SET:
+ if ((error = copyin(SCARG(uap, ptr), &ldsp, sizeof ldsp)))
+ return error;
+ if ((error = copyin(ldsp, (caddr_t)&lm, sizeof lm)))
+ return error;
+ linux_to_bsd_semid_ds(&lm, &bm);
+ sg = stackgap_init(p->p_emul);
+ unptr = stackgap_alloc(&sg, sizeof (union semun));
+ dsp = stackgap_alloc(&sg, sizeof (struct semid_ds));
+ if ((error = copyout((caddr_t)&bm, dsp, sizeof bm)))
+ return error;
+ if ((error = copyout((caddr_t)&dsp, unptr, sizeof dsp)))
+ return error;
+ SCARG(&bsa, arg) = (union semun *)unptr;
+ return __semctl(p, &bsa, retval);
+ case LINUX_IPC_STAT:
+ sg = stackgap_init(p->p_emul);
+ unptr = stackgap_alloc(&sg, sizeof (union semun *));
+ dsp = stackgap_alloc(&sg, sizeof (struct semid_ds));
+ if ((error = copyout((caddr_t)&dsp, unptr, sizeof dsp)))
+ return error;
+ SCARG(&bsa, arg) = (union semun *)unptr;
+ if ((error = __semctl(p, &bsa, retval)))
+ return error;
+ if ((error = copyin(dsp, (caddr_t)&bm, sizeof bm)))
+ return error;
+ bsd_to_linux_semid_ds(&bm, &lm);
+ if ((error = copyin(SCARG(uap, ptr), &ldsp, sizeof ldsp)))
+ return error;
+ return copyout((caddr_t)&lm, ldsp, sizeof lm);
+ default:
+ return EINVAL;
+ }
+ SCARG(&bsa, cmd) = cmd;
+ return __semctl(p, &bsa, retval);
}
#endif /* SYSVSEM */
#ifdef SYSVMSG
-/*
- * Msg functions: not implemented yet.
- */
+
+static void
+linux_to_bsd_msqid_ds(lmp, bmp)
+ struct linux_msqid_ds *lmp;
+ struct msqid_ds *bmp;
+{
+ linux_to_bsd_ipc_perm(&lmp->l_msg_perm, &bmp->msg_perm);
+ bmp->msg_first = lmp->l_msg_first;
+ bmp->msg_last = lmp->l_msg_last;
+ bmp->msg_cbytes = lmp->l_msg_cbytes;
+ bmp->msg_qnum = lmp->l_msg_qnum;
+ bmp->msg_qbytes = lmp->l_msg_qbytes;
+ bmp->msg_lspid = lmp->l_msg_lspid;
+ bmp->msg_lrpid = lmp->l_msg_lrpid;
+ bmp->msg_stime = lmp->l_msg_stime;
+ bmp->msg_rtime = lmp->l_msg_rtime;
+ bmp->msg_ctime = lmp->l_msg_ctime;
+}
+
+static void
+bsd_to_linux_msqid_ds(bmp, lmp)
+ struct msqid_ds *bmp;
+ struct linux_msqid_ds *lmp;
+{
+ bsd_to_linux_ipc_perm(&bmp->msg_perm, &lmp->l_msg_perm);
+ lmp->l_msg_first = bmp->msg_first;
+ lmp->l_msg_last = bmp->msg_last;
+ lmp->l_msg_cbytes = bmp->msg_cbytes;
+ lmp->l_msg_qnum = bmp->msg_qnum;
+ lmp->l_msg_qbytes = bmp->msg_qbytes;
+ lmp->l_msg_lspid = bmp->msg_lspid;
+ lmp->l_msg_lrpid = bmp->msg_lrpid;
+ lmp->l_msg_stime = bmp->msg_stime;
+ lmp->l_msg_rtime = bmp->msg_rtime;
+ lmp->l_msg_ctime = bmp->msg_ctime;
+}
+
int
linux_msgsnd(p, uap, retval)
struct proc *p;
@@ -245,7 +391,14 @@ linux_msgsnd(p, uap, retval)
} */ *uap;
register_t *retval;
{
- return ENOSYS;
+ struct msgsnd_args bma;
+
+ SCARG(&bma, msqid) = SCARG(uap, a1);
+ SCARG(&bma, msgp) = SCARG(uap, ptr);
+ SCARG(&bma, msgsz) = SCARG(uap, a2);
+ SCARG(&bma, msgflg) = SCARG(uap, a3);
+
+ return msgsnd(p, &bma, retval);
}
int
@@ -260,7 +413,19 @@ linux_msgrcv(p, uap, retval)
} */ *uap;
register_t *retval;
{
- return ENOSYS;
+ struct msgrcv_args bma;
+ struct linux_msgrcv_msgarg kluge;
+ int error;
+
+ if ((error = copyin(SCARG(uap, ptr), &kluge, sizeof kluge)))
+ return error;
+
+ SCARG(&bma, msqid) = SCARG(uap, a1);
+ SCARG(&bma, msgp) = kluge.msg;
+ SCARG(&bma, msgsz) = SCARG(uap, a2);
+ SCARG(&bma, msgtyp) = kluge.type;
+ SCARG(&bma, msgflg) = SCARG(uap, a3);
+ return msgrcv(p, &bma, retval);
}
int
@@ -275,7 +440,11 @@ linux_msgget(p, uap, retval)
} */ *uap;
register_t *retval;
{
- return ENOSYS;
+ struct msgget_args bma;
+
+ SCARG(&bma, key) = (key_t)SCARG(uap, a1);
+ SCARG(&bma, msgflg) = SCARG(uap, a2);
+ return msgget(p, &bma, retval);
}
int
@@ -290,7 +459,39 @@ linux_msgctl(p, uap, retval)
} */ *uap;
register_t *retval;
{
- return ENOSYS;
+ struct msgctl_args bma;
+ caddr_t umsgptr, sg;
+ struct linux_msqid_ds lm;
+ struct msqid_ds bm;
+ int error;
+
+ SCARG(&bma, msqid) = SCARG(uap, a1);
+ SCARG(&bma, cmd) = SCARG(uap, a2);
+ switch (SCARG(uap, a2)) {
+ case LINUX_IPC_RMID:
+ return msgctl(p, &bma, retval);
+ case LINUX_IPC_SET:
+ if ((error = copyin(SCARG(uap, ptr), (caddr_t)&lm, sizeof lm)))
+ return error;
+ linux_to_bsd_msqid_ds(&lm, &bm);
+ sg = stackgap_init(p->p_emul);
+ umsgptr = stackgap_alloc(&sg, sizeof bm);
+ if ((error = copyout((caddr_t)&bm, umsgptr, sizeof bm)))
+ return error;
+ SCARG(&bma, buf) = (struct msqid_ds *)umsgptr;
+ return msgctl(p, &bma, retval);
+ case LINUX_IPC_STAT:
+ sg = stackgap_init(p->p_emul);
+ umsgptr = stackgap_alloc(&sg, sizeof (struct msqid_ds));
+ SCARG(&bma, buf) = (struct msqid_ds *)umsgptr;
+ if ((error = msgctl(p, &bma, retval)))
+ return error;
+ if ((error = copyin(umsgptr, (caddr_t)&bm, sizeof bm)))
+ return error;
+ bsd_to_linux_msqid_ds(&bm, &lm);
+ return copyout((caddr_t)&lm, SCARG(uap, ptr), sizeof lm);
+ }
+ return EINVAL;
}
#endif /* SYSVMSG */
diff --git a/sys/compat/linux/multiarch/linux_ipccall.h b/sys/compat/linux/multiarch/linux_ipccall.h
index 42f166b5402..854b641dac2 100644
--- a/sys/compat/linux/multiarch/linux_ipccall.h
+++ b/sys/compat/linux/multiarch/linux_ipccall.h
@@ -1,4 +1,4 @@
-/* $NetBSD: linux_ipccall.h,v 1.1 1995/02/28 23:25:50 fvdl Exp $ */
+/* $NetBSD: linux_ipccall.h,v 1.2 1995/08/15 21:14:33 fvdl Exp $ */
/*
* Copyright (c) 1995 Frank van der Linden
@@ -51,13 +51,4 @@
#define LINUX_SYS_shmget 23
#define LINUX_SYS_shmctl 24
-/*
- * This kludge is used for the 6th argument to the msgrcv system
- * call, to get around the maximum of 5 arguments to a syscall in Linux.
- */
-struct linux_ipc_kludge {
- struct linux_msgbuf *msg;
- int type;
-};
-
#endif /* _LINUX_IPC_CALL_H */