summaryrefslogtreecommitdiffstats
path: root/sys/i386/ibcs2/ibcs2_ipc.c
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2006-07-08 19:54:12 +0000
committerjhb <jhb@FreeBSD.org>2006-07-08 19:54:12 +0000
commitdf27227bab23aaf42551e2e2ea6f0955e253f135 (patch)
treea38bdf162d8f64f988fcc464dbc7e692f886078a /sys/i386/ibcs2/ibcs2_ipc.c
parent9f226f3f9d1098920e593d19344321d7b419beb2 (diff)
downloadFreeBSD-src-df27227bab23aaf42551e2e2ea6f0955e253f135.zip
FreeBSD-src-df27227bab23aaf42551e2e2ea6f0955e253f135.tar.gz
- Split the IBCS2 ipc foosys() system calls up into subfunctions matching
the organization in svr4_ipc.c. - Use kern_msgctl(), kern_semctl(), and kern_shmctl() instead of the stackgap.
Diffstat (limited to 'sys/i386/ibcs2/ibcs2_ipc.c')
-rw-r--r--sys/i386/ibcs2/ibcs2_ipc.c450
1 files changed, 298 insertions, 152 deletions
diff --git a/sys/i386/ibcs2/ibcs2_ipc.c b/sys/i386/ibcs2/ibcs2_ipc.c
index 5ba7e49..5b6342a 100644
--- a/sys/i386/ibcs2/ibcs2_ipc.c
+++ b/sys/i386/ibcs2/ibcs2_ipc.c
@@ -31,6 +31,7 @@ __FBSDID("$FreeBSD$");
#include <sys/msg.h>
#include <sys/sem.h>
#include <sys/shm.h>
+#include <sys/syscallsubr.h>
#include <sys/sysproto.h>
#include <i386/ibcs2/ibcs2_types.h>
@@ -102,50 +103,118 @@ struct msqid_ds *bp;
return;
}
+struct ibcs2_msgget_args {
+ int what;
+ ibcs2_key_t key;
+ int msgflg;
+};
+
+static int
+ibcs2_msgget(struct thread *td, void *v)
+{
+ struct ibcs2_msgget_args *uap = v;
+ struct msgget_args ap;
+
+ ap.key = uap->key;
+ ap.msgflg = uap->msgflg;
+ return msgget(td, &ap);
+}
+
+struct ibcs2_msgctl_args {
+ int what;
+ int msqid;
+ int cmd;
+ struct ibcs2_msqid_ds *buf;
+};
+
+static int
+ibcs2_msgctl(struct thread *td, void *v)
+{
+ struct ibcs2_msgctl_args *uap = v;
+ struct ibcs2_msqid_ds is;
+ struct msqid_ds bs;
+ int error;
+
+ switch (uap->cmd) {
+ case IBCS2_IPC_STAT:
+ error = kern_msgctl(td, uap->msqid, IPC_STAT, &bs);
+ if (!error) {
+ cvt_msqid2imsqid(&bs, &is);
+ error = copyout(&is, uap->buf, sizeof(is));
+ }
+ return (error);
+ case IBCS2_IPC_SET:
+ error = copyin(uap->buf, &is, sizeof(is));
+ if (error)
+ return (error);
+ cvt_imsqid2msqid(&is, &bs);
+ return (kern_msgctl(td, uap->msqid, IPC_SET, &bs));
+ case IBCS2_IPC_RMID:
+ return (kern_msgctl(td, uap->msqid, IPC_RMID, NULL));
+ }
+ return (EINVAL);
+}
+
+struct ibcs2_msgrcv_args {
+ int what;
+ int msqid;
+ void *msgp;
+ size_t msgsz;
+ long msgtyp;
+ int msgflg;
+};
+
+static int
+ibcs2_msgrcv(struct thread *td, void *v)
+{
+ struct ibcs2_msgrcv_args *uap = v;
+ struct msgrcv_args ap;
+
+ ap.msqid = uap->msqid;
+ ap.msgp = uap->msgp;
+ ap.msgsz = uap->msgsz;
+ ap.msgtyp = uap->msgtyp;
+ ap.msgflg = uap->msgflg;
+ return (msgrcv(td, &ap));
+}
+
+struct ibcs2_msgsnd_args {
+ int what;
+ int msqid;
+ void *msgp;
+ size_t msgsz;
+ int msgflg;
+};
+
+static int
+ibcs2_msgsnd(struct thread *td, void *v)
+{
+ struct ibcs2_msgsnd_args *uap = v;
+ struct msgsnd_args ap;
+
+ ap.msqid = uap->msqid;
+ ap.msgp = uap->msgp;
+ ap.msgsz = uap->msgsz;
+ ap.msgflg = uap->msgflg;
+ return (msgsnd(td, &ap));
+}
+
int
ibcs2_msgsys(td, uap)
struct thread *td;
struct ibcs2_msgsys_args *uap;
{
switch (uap->which) {
- case 0: /* msgget */
- uap->which = 1;
- return msgsys(td, (struct msgsys_args *)uap);
- case 1: { /* msgctl */
- int error;
- struct msgsys_args margs;
- caddr_t sg = stackgap_init();
-
- margs.which = 0;
- margs.a2 = uap->a2;
- margs.a4 =
- (int)stackgap_alloc(&sg, sizeof(struct msqid_ds));
- margs.a3 = uap->a3;
- switch (margs.a3) {
- case IBCS2_IPC_STAT:
- error = msgsys(td, &margs);
- if (!error)
- cvt_msqid2imsqid(
- (struct msqid_ds *)margs.a4,
- (struct ibcs2_msqid_ds *)uap->a4);
- return error;
- case IBCS2_IPC_SET:
- cvt_imsqid2msqid((struct ibcs2_msqid_ds *)uap->a4,
- (struct msqid_ds *)margs.a4);
- return msgsys(td, &margs);
- case IBCS2_IPC_RMID:
- return msgsys(td, &margs);
- }
- return EINVAL;
- }
- case 2: /* msgrcv */
- uap->which = 3;
- return msgsys(td, (struct msgsys_args *)uap);
- case 3: /* msgsnd */
- uap->which = 2;
- return msgsys(td, (struct msgsys_args *)uap);
+ case 0:
+ return (ibcs2_msgget(td, uap));
+ case 1:
+ return (ibcs2_msgctl(td, uap));
+ case 2:
+ return (ibcs2_msgrcv(td, uap));
+ case 3:
+ return (ibcs2_msgsnd(td, uap));
default:
- return EINVAL;
+ return (EINVAL);
}
}
@@ -232,77 +301,104 @@ struct semid_ds *bp;
return;
}
+struct ibcs2_semctl_args {
+ int what;
+ int semid;
+ int semnum;
+ int cmd;
+ union semun arg;
+};
+
+static int
+ibcs2_semctl(struct thread *td, void *v)
+{
+ struct ibcs2_semctl_args *uap = v;
+ struct ibcs2_semid_ds is;
+ struct semid_ds bs;
+ union semun semun;
+ register_t rval;
+ int error;
+
+ switch(uap->cmd) {
+ case IBCS2_IPC_STAT:
+ semun.buf = &bs;
+ error = kern_semctl(td, uap->semid, uap->semnum, IPC_STAT,
+ &semun, &rval);
+ if (error)
+ return (error);
+ cvt_semid2isemid(&bs, &is);
+ error = copyout(&is, uap->arg.buf, sizeof(is));
+ if (error == 0)
+ td->td_retval[0] = rval;
+ return (error);
+
+ case IBCS2_IPC_SET:
+ error = copyin(uap->arg.buf, &is, sizeof(is));
+ if (error)
+ return (error);
+ cvt_isemid2semid(&is, &bs);
+ semun.buf = &bs;
+ return (kern_semctl(td, uap->semid, uap->semnum, IPC_SET,
+ &semun, td->td_retval));
+ }
+
+ return (kern_semctl(td, uap->semid, uap->semnum, uap->cmd, &uap->arg,
+ td->td_retval));
+}
+
+struct ibcs2_semget_args {
+ int what;
+ ibcs2_key_t key;
+ int nsems;
+ int semflg;
+};
+
+static int
+ibcs2_semget(struct thread *td, void *v)
+{
+ struct ibcs2_semget_args *uap = v;
+ struct semget_args ap;
+
+ ap.key = uap->key;
+ ap.nsems = uap->nsems;
+ ap.semflg = uap->semflg;
+ return (semget(td, &ap));
+}
+
+struct ibcs2_semop_args {
+ int what;
+ int semid;
+ struct sembuf *sops;
+ size_t nsops;
+};
+
+static int
+ibcs2_semop(struct thread *td, void *v)
+{
+ struct ibcs2_semop_args *uap = v;
+ struct semop_args ap;
+
+ ap.semid = uap->semid;
+ ap.sops = uap->sops;
+ ap.nsops = uap->nsops;
+ return (semop(td, &ap));
+}
+
int
ibcs2_semsys(td, uap)
struct thread *td;
struct ibcs2_semsys_args *uap;
{
- int error;
switch (uap->which) {
- case 0: /* semctl */
- switch(uap->a4) {
- case IBCS2_IPC_STAT:
- {
- struct ibcs2_semid_ds *isp;
- struct semid_ds *sp;
- union semun *sup, ssu;
- caddr_t sg = stackgap_init();
-
-
- ssu = (union semun) uap->a5;
- sp = stackgap_alloc(&sg, sizeof(struct semid_ds));
- sup = stackgap_alloc(&sg, sizeof(union semun));
- sup->buf = sp;
- uap->a5 = (int)sup;
- error = semsys(td, (struct semsys_args *)uap);
- if (!error) {
- uap->a5 = (int)ssu.buf;
- isp = stackgap_alloc(&sg, sizeof(*isp));
- cvt_semid2isemid(sp, isp);
- error = copyout((caddr_t)isp,
- (caddr_t)ssu.buf,
- sizeof(*isp));
- }
- return error;
- }
- case IBCS2_IPC_SET:
- {
- struct ibcs2_semid_ds *isp;
- struct semid_ds *sp;
- caddr_t sg = stackgap_init();
-
- isp = stackgap_alloc(&sg, sizeof(*isp));
- sp = stackgap_alloc(&sg, sizeof(*sp));
- error = copyin((caddr_t)uap->a5, (caddr_t)isp,
- sizeof(*isp));
- if (error)
- return error;
- cvt_isemid2semid(isp, sp);
- uap->a5 = (int)sp;
- return semsys(td, (struct semsys_args *)uap);
- }
- case IBCS2_SETVAL:
- {
- union semun *sp;
- caddr_t sg = stackgap_init();
-
- sp = stackgap_alloc(&sg, sizeof(*sp));
- sp->val = (int) uap->a5;
- uap->a5 = (int)sp;
- return semsys(td, (struct semsys_args *)uap);
- }
- }
-
- return semsys(td, (struct semsys_args *)uap);
-
- case 1: /* semget */
- return semsys(td, (struct semsys_args *)uap);
-
- case 2: /* semop */
- return semsys(td, (struct semsys_args *)uap);
+ case 0:
+ return (ibcs2_semctl(td, uap));
+ case 1:
+ return (ibcs2_semget(td, uap));
+ case 2:
+ return (ibcs2_semop(td, uap));
}
- return EINVAL;
+ return (EINVAL);
}
@@ -344,66 +440,116 @@ struct shmid_ds *bp;
return;
}
+struct ibcs2_shmat_args {
+ int what;
+ int shmid;
+ const void *shmaddr;
+ int shmflg;
+};
+
+static int
+ibcs2_shmat(struct thread *td, void *v)
+{
+ struct ibcs2_shmat_args *uap = v;
+ struct shmat_args ap;
+
+ ap.shmid = uap->shmid;
+ ap.shmaddr = uap->shmaddr;
+ ap.shmflg = uap->shmflg;
+ return (shmat(td, &ap));
+}
+
+struct ibcs2_shmctl_args {
+ int what;
+ int shmid;
+ int cmd;
+ struct ibcs2_shmid_ds *buf;
+};
+
+static int
+ibcs2_shmctl(struct thread *td, void *v)
+{
+ struct ibcs2_shmctl_args *uap = v;
+ struct ibcs2_shmid_ds is;
+ struct shmid_ds bs;
+ int error;
+
+ switch(uap->cmd) {
+ case IBCS2_IPC_STAT:
+ error = kern_shmctl(td, uap->shmid, IPC_STAT, &bs, NULL);
+ if (error)
+ return (error);
+ cvt_shmid2ishmid(&bs, &is);
+ return (copyout(&is, uap->buf, sizeof(is)));
+
+ case IBCS2_IPC_SET:
+ error = copyin(uap->buf, &is, sizeof(is));
+ if (error)
+ return (error);
+ cvt_ishmid2shmid(&is, &bs);
+ return (kern_shmctl(td, uap->shmid, IPC_SET, &bs, NULL));
+
+ case IPC_INFO:
+ case SHM_INFO:
+ case SHM_STAT:
+ /* XXX: */
+ return (EINVAL);
+ }
+
+ return (kern_shmctl(td, uap->shmid, uap->cmd, NULL, NULL));
+}
+
+struct ibcs2_shmdt_args {
+ int what;
+ const void *shmaddr;
+};
+
+static int
+ibcs2_shmdt(struct thread *td, void *v)
+{
+ struct ibcs2_shmdt_args *uap = v;
+ struct shmdt_args ap;
+
+ ap.shmaddr = uap->shmaddr;
+ return (shmdt(td, &ap));
+}
+
+struct ibcs2_shmget_args {
+ int what;
+ ibcs2_key_t key;
+ size_t size;
+ int shmflg;
+};
+
+static int
+ibcs2_shmget(struct thread *td, void *v)
+{
+ struct ibcs2_shmget_args *uap = v;
+ struct shmget_args ap;
+
+ ap.key = uap->key;
+ ap.size = uap->size;
+ ap.shmflg = uap->shmflg;
+ return (shmget(td, &ap));
+}
+
int
ibcs2_shmsys(td, uap)
struct thread *td;
struct ibcs2_shmsys_args *uap;
{
- int error;
switch (uap->which) {
- case 0: /* shmat */
- return shmsys(td, (struct shmsys_args *)uap);
-
- case 1: /* shmctl */
- switch(uap->a3) {
- case IBCS2_IPC_STAT:
- {
- struct ibcs2_shmid_ds *isp;
- struct shmid_ds *sp;
- caddr_t sg = stackgap_init();
-
- isp = (struct ibcs2_shmid_ds *)uap->a4;
- sp = stackgap_alloc(&sg, sizeof(*sp));
- uap->a4 = (int)sp;
- error = shmsys(td, (struct shmsys_args *)uap);
- if (!error) {
- uap->a4 = (int)isp;
- isp = stackgap_alloc(&sg, sizeof(*isp));
- cvt_shmid2ishmid(sp, isp);
- error = copyout((caddr_t)isp,
- (caddr_t)uap->a4,
- sizeof(*isp));
- }
- return error;
- }
- case IBCS2_IPC_SET:
- {
- struct ibcs2_shmid_ds *isp;
- struct shmid_ds *sp;
- caddr_t sg = stackgap_init();
-
- isp = stackgap_alloc(&sg, sizeof(*isp));
- sp = stackgap_alloc(&sg, sizeof(*sp));
- error = copyin((caddr_t)uap->a4, (caddr_t)isp,
- sizeof(*isp));
- if (error)
- return error;
- cvt_ishmid2shmid(isp, sp);
- uap->a4 = (int)sp;
- return shmsys(td, (struct shmsys_args *)uap);
- }
- }
-
- return shmsys(td, (struct shmsys_args *)uap);
-
- case 2: /* shmdt */
- return shmsys(td, (struct shmsys_args *)uap);
-
- case 3: /* shmget */
- return shmsys(td, (struct shmsys_args *)uap);
+ case 0:
+ return (ibcs2_shmat(td, uap));
+ case 1:
+ return (ibcs2_shmctl(td, uap));
+ case 2:
+ return (ibcs2_shmdt(td, uap));
+ case 3:
+ return (ibcs2_shmget(td, uap));
}
- return EINVAL;
+ return (EINVAL);
}
MODULE_DEPEND(ibcs2, sysvmsg, 1, 1, 1);
OpenPOWER on IntegriCloud