diff options
author | jhb <jhb@FreeBSD.org> | 2006-07-08 19:54:12 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2006-07-08 19:54:12 +0000 |
commit | df27227bab23aaf42551e2e2ea6f0955e253f135 (patch) | |
tree | a38bdf162d8f64f988fcc464dbc7e692f886078a /sys/i386/ibcs2/ibcs2_ipc.c | |
parent | 9f226f3f9d1098920e593d19344321d7b419beb2 (diff) | |
download | FreeBSD-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.c | 450 |
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); |