Index: sys/kern/sysv_msg.c =================================================================== --- sys/kern/sysv_msg.c (revision 194647) +++ sys/kern/sysv_msg.c (working copy) @@ -50,6 +50,7 @@ #include __FBSDID("$FreeBSD$"); +#include "opt_compat.h" #include "opt_sysvipc.h" #include @@ -85,12 +86,6 @@ static void msg_freehdr(struct msg *msghdr); -/* XXX casting to (sy_call_t *) is bogus, as usual. */ -static sy_call_t *msgcalls[] = { - (sy_call_t *)msgctl, (sy_call_t *)msgget, - (sy_call_t *)msgsnd, (sy_call_t *)msgrcv -}; - #ifndef MSGSSZ #define MSGSSZ 8 /* Each segment must be 2^N long */ #endif @@ -308,43 +303,14 @@ NULL }; -SYSCALL_MODULE_HELPER(msgsys); SYSCALL_MODULE_HELPER(msgctl); SYSCALL_MODULE_HELPER(msgget); SYSCALL_MODULE_HELPER(msgsnd); SYSCALL_MODULE_HELPER(msgrcv); -DECLARE_MODULE(sysvmsg, sysvmsg_mod, - SI_SUB_SYSV_MSG, SI_ORDER_FIRST); +DECLARE_MODULE(sysvmsg, sysvmsg_mod, SI_SUB_SYSV_MSG, SI_ORDER_FIRST); MODULE_VERSION(sysvmsg, 1); -/* - * Entry point for all MSG calls. - */ -int -msgsys(td, uap) - struct thread *td; - /* XXX actually varargs. */ - struct msgsys_args /* { - int which; - int a2; - int a3; - int a4; - int a5; - int a6; - } */ *uap; -{ - int error; - - if (!prison_allow(td->td_ucred, PR_ALLOW_SYSVIPC)) - return (ENOSYS); - if (uap->which < 0 || - uap->which >= sizeof(msgcalls)/sizeof(msgcalls[0])) - return (EINVAL); - error = (*msgcalls[uap->which])(td, &uap->a2); - return (error); -} - static void msg_freehdr(msghdr) struct msg *msghdr; @@ -1290,3 +1256,103 @@ "Number of message segments"); SYSCTL_PROC(_kern_ipc, OID_AUTO, msqids, CTLFLAG_RD, NULL, 0, sysctl_msqids, "", "Message queue IDs"); + +#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \ + defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7) +SYSCALL_MODULE_HELPER(msgsys); +SYSCALL_MODULE_HELPER(freebsd7_msgctl); + +/* XXX casting to (sy_call_t *) is bogus, as usual. */ +static sy_call_t *msgcalls[] = { + (sy_call_t *)freebsd7_msgctl, (sy_call_t *)msgget, + (sy_call_t *)msgsnd, (sy_call_t *)msgrcv +}; + +/* + * Entry point for all MSG calls. + */ +int +msgsys(td, uap) + struct thread *td; + /* XXX actually varargs. */ + struct msgsys_args /* { + int which; + int a2; + int a3; + int a4; + int a5; + int a6; + } */ *uap; +{ + int error; + + if (!prison_allow(td->td_ucred, PR_ALLOW_SYSVIPC)) + return (ENOSYS); + if (uap->which < 0 || + uap->which >= sizeof(msgcalls)/sizeof(msgcalls[0])) + return (EINVAL); + error = (*msgcalls[uap->which])(td, &uap->a2); + return (error); +} + +#define CP(src, dst, fld) do { (dst).fld = (src).fld; } while (0) + +#ifndef _SYS_SYSPROTO_H_ +struct freebsd7_msgctl_args { + int msqid; + int cmd; + struct msqid_ds_old *buf; +}; +#endif +int +freebsd7_msgctl(td, uap) + struct thread *td; + struct freebsd7_msgctl_args *uap; +{ + struct msqid_ds_old msqold; + struct msqid_ds msqbuf; + int error; + + DPRINTF(("call to freebsd7_msgctl(%d, %d, %p)\n", uap->msqid, uap->cmd, + uap->buf)); + if (uap->cmd == IPC_SET) { + error = copyin(uap->buf, &msqold, sizeof(msqold)); + if (error) + return (error); + ipcperm_old2new(&msqold.msg_perm, &msqbuf.msg_perm); + CP(msqold, msqbuf, msg_first); + CP(msqold, msqbuf, msg_last); + CP(msqold, msqbuf, msg_cbytes); + CP(msqold, msqbuf, msg_qnum); + CP(msqold, msqbuf, msg_qbytes); + CP(msqold, msqbuf, msg_lspid); + CP(msqold, msqbuf, msg_lrpid); + CP(msqold, msqbuf, msg_stime); + CP(msqold, msqbuf, msg_rtime); + CP(msqold, msqbuf, msg_ctime); + } + error = kern_msgctl(td, uap->msqid, uap->cmd, &msqbuf); + if (error) + return (error); + if (uap->cmd == IPC_STAT) { + bzero(&msqold, sizeof(msqold)); + ipcperm_new2old(&msqbuf.msg_perm, &msqold.msg_perm); + CP(msqbuf, msqold, msg_first); + CP(msqbuf, msqold, msg_last); + CP(msqbuf, msqold, msg_cbytes); + CP(msqbuf, msqold, msg_qnum); + CP(msqbuf, msqold, msg_qbytes); + CP(msqbuf, msqold, msg_lspid); + CP(msqbuf, msqold, msg_lrpid); + CP(msqbuf, msqold, msg_stime); + CP(msqbuf, msqold, msg_rtime); + CP(msqbuf, msqold, msg_ctime); + error = copyout(&msqold, uap->buf, sizeof(struct msqid_ds_old)); + } + return (error); +} + +#undef CP + +#endif /* COMPAT_FREEBSD4 || COMPAT_FREEBSD5 || COMPAT_FREEBSD6 || + COMPAT_FREEBSD7 */ Index: sys/kern/sysv_sem.c =================================================================== --- sys/kern/sysv_sem.c (revision 194647) +++ sys/kern/sysv_sem.c (working copy) @@ -39,6 +39,7 @@ #include __FBSDID("$FreeBSD$"); +#include "opt_compat.h" #include "opt_sysvipc.h" #include @@ -90,12 +91,6 @@ int semid, int semseq, int semnum, int adjval); static void semundo_clear(int semid, int semnum); -/* XXX casting to (sy_call_t *) is bogus, as usual. */ -static sy_call_t *semcalls[] = { - (sy_call_t *)__semctl, (sy_call_t *)semget, - (sy_call_t *)semop -}; - static struct mtx sem_mtx; /* semaphore global lock */ static struct mtx sem_undo_mtx; static int semtot = 0; @@ -317,42 +312,14 @@ NULL }; -SYSCALL_MODULE_HELPER(semsys); SYSCALL_MODULE_HELPER(__semctl); SYSCALL_MODULE_HELPER(semget); SYSCALL_MODULE_HELPER(semop); -DECLARE_MODULE(sysvsem, sysvsem_mod, - SI_SUB_SYSV_SEM, SI_ORDER_FIRST); +DECLARE_MODULE(sysvsem, sysvsem_mod, SI_SUB_SYSV_SEM, SI_ORDER_FIRST); MODULE_VERSION(sysvsem, 1); /* - * Entry point for all SEM calls. - */ -int -semsys(td, uap) - struct thread *td; - /* XXX actually varargs. */ - struct semsys_args /* { - int which; - int a2; - int a3; - int a4; - int a5; - } */ *uap; -{ - int error; - - if (!prison_allow(td->td_ucred, PR_ALLOW_SYSVIPC)) - return (ENOSYS); - if (uap->which < 0 || - uap->which >= sizeof(semcalls)/sizeof(semcalls[0])) - return (EINVAL); - error = (*semcalls[uap->which])(td, &uap->a2); - return (error); -} - -/* * Allocate a new sem_undo structure for a process * (returns ptr to structure or NULL if no more room) */ @@ -1346,3 +1313,126 @@ return (SYSCTL_OUT(req, sema, sizeof(struct semid_kernel) * seminfo.semmni)); } + +#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \ + defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7) +SYSCALL_MODULE_HELPER(semsys); +SYSCALL_MODULE_HELPER(freebsd7___semctl); + +/* XXX casting to (sy_call_t *) is bogus, as usual. */ +static sy_call_t *semcalls[] = { + (sy_call_t *)freebsd7___semctl, (sy_call_t *)semget, + (sy_call_t *)semop +}; + +/* + * Entry point for all SEM calls. + */ +int +semsys(td, uap) + struct thread *td; + /* XXX actually varargs. */ + struct semsys_args /* { + int which; + int a2; + int a3; + int a4; + int a5; + } */ *uap; +{ + int error; + + if (!prison_allow(td->td_ucred, PR_ALLOW_SYSVIPC)) + return (ENOSYS); + if (uap->which < 0 || + uap->which >= sizeof(semcalls)/sizeof(semcalls[0])) + return (EINVAL); + error = (*semcalls[uap->which])(td, &uap->a2); + return (error); +} + +#define CP(src, dst, fld) do { (dst).fld = (src).fld; } while (0) + +#ifndef _SYS_SYSPROTO_H_ +struct freebsd7___semctl_args { + int semid; + int semnum; + int cmd; + union semun_old *arg; +}; +#endif +int +freebsd7___semctl(struct thread *td, struct freebsd7___semctl_args *uap) +{ + struct semid_ds_old dsold; + struct semid_ds dsbuf; + union semun_old arg; + union semun semun; + register_t rval; + int error; + + switch (uap->cmd) { + case SEM_STAT: + case IPC_SET: + case IPC_STAT: + case GETALL: + case SETVAL: + case SETALL: + error = copyin(uap->arg, &arg, sizeof(arg)); + if (error) + return (error); + break; + } + + switch (uap->cmd) { + case SEM_STAT: + case IPC_STAT: + semun.buf = &dsbuf; + break; + case IPC_SET: + error = copyin(arg.buf, &dsold, sizeof(dsold)); + if (error) + return (error); + ipcperm_old2new(&dsold.sem_perm, &dsbuf.sem_perm); + CP(dsold, dsbuf, sem_base); + CP(dsold, dsbuf, sem_nsems); + CP(dsold, dsbuf, sem_otime); + CP(dsold, dsbuf, sem_ctime); + semun.buf = &dsbuf; + break; + case GETALL: + case SETALL: + semun.array = arg.array; + break; + case SETVAL: + semun.val = arg.val; + break; + } + + error = kern_semctl(td, uap->semid, uap->semnum, uap->cmd, &semun, + &rval); + if (error) + return (error); + + switch (uap->cmd) { + case SEM_STAT: + case IPC_STAT: + bzero(&dsold, sizeof(dsold)); + ipcperm_new2old(&dsbuf.sem_perm, &dsold.sem_perm); + CP(dsbuf, dsold, sem_base); + CP(dsbuf, dsold, sem_nsems); + CP(dsbuf, dsold, sem_otime); + CP(dsbuf, dsold, sem_ctime); + error = copyout(&dsold, arg.buf, sizeof(dsold)); + break; + } + + if (error == 0) + td->td_retval[0] = rval; + return (error); +} + +#undef CP + +#endif /* COMPAT_FREEBSD4 || COMPAT_FREEBSD5 || COMPAT_FREEBSD6 || + COMPAT_FREEBSD7 */ Index: sys/kern/sysv_shm.c =================================================================== --- sys/kern/sysv_shm.c (revision 194647) +++ sys/kern/sysv_shm.c (working copy) @@ -68,6 +68,7 @@ #include #include #include +#include #include #include #include @@ -96,25 +97,11 @@ static MALLOC_DEFINE(M_SHM, "shm", "SVID compatible shared memory segments"); -#if defined(__i386__) && (defined(COMPAT_FREEBSD4) || defined(COMPAT_43)) -struct oshmctl_args; -static int oshmctl(struct thread *td, struct oshmctl_args *uap); -#endif - static int shmget_allocate_segment(struct thread *td, struct shmget_args *uap, int mode); static int shmget_existing(struct thread *td, struct shmget_args *uap, int mode, int segnum); -#if defined(__i386__) && (defined(COMPAT_FREEBSD4) || defined(COMPAT_43)) -/* XXX casting to (sy_call_t *) is bogus, as usual. */ -static sy_call_t *shmcalls[] = { - (sy_call_t *)shmat, (sy_call_t *)oshmctl, - (sy_call_t *)shmdt, (sy_call_t *)shmget, - (sy_call_t *)shmctl -}; -#endif - #define SHMSEG_FREE 0x0200 #define SHMSEG_REMOVED 0x0400 #define SHMSEG_ALLOCATED 0x0800 @@ -248,9 +235,9 @@ GIANT_REQUIRED; - vm_object_deallocate(shmseg->u.shm_internal); - shmseg->u.shm_internal = NULL; - size = round_page(shmseg->shm_bsegsz); + vm_object_deallocate(shmseg->object); + shmseg->object = NULL; + size = round_page(shmseg->u.shm_segsz); shm_committed -= btoc(size); shm_nused--; shmseg->u.shm_perm.mode = SHMSEG_FREE; @@ -270,7 +257,7 @@ segnum = IPCID_TO_IX(shmmap_s->shmid); shmseg = &shmsegs[segnum]; - size = round_page(shmseg->shm_bsegsz); + size = round_page(shmseg->u.shm_segsz); result = vm_map_remove(&vm->vm_map, shmmap_s->va, shmmap_s->va + size); if (result != KERN_SUCCESS) return (EINVAL); @@ -390,7 +377,7 @@ error = EMFILE; goto done2; } - size = round_page(shmseg->shm_bsegsz); + size = round_page(shmseg->u.shm_segsz); prot = VM_PROT_READ; if ((shmflg & SHM_RDONLY) == 0) prot |= VM_PROT_WRITE; @@ -416,12 +403,12 @@ PROC_UNLOCK(p); } - vm_object_reference(shmseg->u.shm_internal); - rv = vm_map_find(&p->p_vmspace->vm_map, shmseg->u.shm_internal, + vm_object_reference(shmseg->object); + rv = vm_map_find(&p->p_vmspace->vm_map, shmseg->object, 0, &attach_va, size, (flags & MAP_FIXED) ? VMFS_NO_SPACE : VMFS_ANY_SPACE, prot, prot, 0); if (rv != KERN_SUCCESS) { - vm_object_deallocate(shmseg->u.shm_internal); + vm_object_deallocate(shmseg->object); error = ENOMEM; goto done2; } @@ -447,85 +434,6 @@ return kern_shmat(td, uap->shmid, uap->shmaddr, uap->shmflg); } -#if defined(__i386__) && (defined(COMPAT_FREEBSD4) || defined(COMPAT_43)) -struct oshmid_ds { - struct ipc_perm shm_perm; /* operation perms */ - int shm_segsz; /* size of segment (bytes) */ - u_short shm_cpid; /* pid, creator */ - u_short shm_lpid; /* pid, last operation */ - short shm_nattch; /* no. of current attaches */ - time_t shm_atime; /* last attach time */ - time_t shm_dtime; /* last detach time */ - time_t shm_ctime; /* last change time */ - void *shm_handle; /* internal handle for shm segment */ -}; - -struct oshmctl_args { - int shmid; - int cmd; - struct oshmid_ds *ubuf; -}; -static int -oshmctl(td, uap) - struct thread *td; - struct oshmctl_args *uap; -{ -#ifdef COMPAT_43 - int error = 0; - struct shmid_kernel *shmseg; - struct oshmid_ds outbuf; - - if (!prison_allow(td->td_ucred, PR_ALLOW_SYSVIPC)) - return (ENOSYS); - mtx_lock(&Giant); - shmseg = shm_find_segment_by_shmid(uap->shmid); - if (shmseg == NULL) { - error = EINVAL; - goto done2; - } - switch (uap->cmd) { - case IPC_STAT: - error = ipcperm(td, &shmseg->u.shm_perm, IPC_R); - if (error) - goto done2; -#ifdef MAC - error = mac_sysvshm_check_shmctl(td->td_ucred, shmseg, uap->cmd); - if (error != 0) - goto done2; -#endif - outbuf.shm_perm = shmseg->u.shm_perm; - outbuf.shm_segsz = shmseg->u.shm_segsz; - outbuf.shm_cpid = shmseg->u.shm_cpid; - outbuf.shm_lpid = shmseg->u.shm_lpid; - outbuf.shm_nattch = shmseg->u.shm_nattch; - outbuf.shm_atime = shmseg->u.shm_atime; - outbuf.shm_dtime = shmseg->u.shm_dtime; - outbuf.shm_ctime = shmseg->u.shm_ctime; - outbuf.shm_handle = shmseg->u.shm_internal; - error = copyout(&outbuf, uap->ubuf, sizeof(outbuf)); - if (error) - goto done2; - break; - default: - error = shmctl(td, (struct shmctl_args *)uap); - break; - } -done2: - mtx_unlock(&Giant); - return (error); -#else - return (EINVAL); -#endif -} -#endif - -#ifndef _SYS_SYSPROTO_H_ -struct shmctl_args { - int shmid; - int cmd; - struct shmid_ds *buf; -}; -#endif int kern_shmctl(td, shmid, cmd, buf, bufsz) struct thread *td; @@ -636,6 +544,13 @@ return (error); } +#ifndef _SYS_SYSPROTO_H_ +struct shmctl_args { + int shmid; + int cmd; + struct shmid_ds *buf; +}; +#endif int shmctl(td, uap) struct thread *td; @@ -680,13 +595,6 @@ } -#ifndef _SYS_SYSPROTO_H_ -struct shmget_args { - key_t key; - size_t size; - int shmflg; -}; -#endif static int shmget_existing(td, uap, mode, segnum) struct thread *td; @@ -717,7 +625,7 @@ if (error != 0) return (error); #endif - if (uap->size != 0 && uap->size > shmseg->shm_bsegsz) + if (uap->size != 0 && uap->size > shmseg->u.shm_segsz) return (EINVAL); td->td_retval[0] = IXSEQ_TO_IPCID(segnum, shmseg->u.shm_perm); return (0); @@ -782,13 +690,12 @@ vm_object_set_flag(shm_object, OBJ_NOSPLIT); VM_OBJECT_UNLOCK(shm_object); - shmseg->u.shm_internal = shm_object; + shmseg->object = shm_object; shmseg->u.shm_perm.cuid = shmseg->u.shm_perm.uid = cred->cr_uid; shmseg->u.shm_perm.cgid = shmseg->u.shm_perm.gid = cred->cr_gid; shmseg->u.shm_perm.mode = (shmseg->u.shm_perm.mode & SHMSEG_WANTED) | (mode & ACCESSPERMS) | SHMSEG_ALLOCATED; shmseg->u.shm_segsz = uap->size; - shmseg->shm_bsegsz = uap->size; shmseg->u.shm_cpid = td->td_proc->p_pid; shmseg->u.shm_lpid = shmseg->u.shm_nattch = 0; shmseg->u.shm_atime = shmseg->u.shm_dtime = 0; @@ -810,6 +717,13 @@ return (0); } +#ifndef _SYS_SYSPROTO_H_ +struct shmget_args { + key_t key; + size_t size; + int shmflg; +}; +#endif int shmget(td, uap) struct thread *td; @@ -842,34 +756,6 @@ return (error); } -int -shmsys(td, uap) - struct thread *td; - /* XXX actually varargs. */ - struct shmsys_args /* { - int which; - int a2; - int a3; - int a4; - } */ *uap; -{ -#if defined(__i386__) && (defined(COMPAT_FREEBSD4) || defined(COMPAT_43)) - int error; - - if (!prison_allow(td->td_ucred, PR_ALLOW_SYSVIPC)) - return (ENOSYS); - if (uap->which < 0 || - uap->which >= sizeof(shmcalls)/sizeof(shmcalls[0])) - return (EINVAL); - mtx_lock(&Giant); - error = (*shmcalls[uap->which])(td, &uap->a2); - mtx_unlock(&Giant); - return (error); -#else - return (nosys(td, NULL)); -#endif -} - static void shmfork_myhook(p1, p2) struct proc *p1, *p2; @@ -994,7 +880,200 @@ return (SYSCTL_OUT(req, shmsegs, shmalloced * sizeof(shmsegs[0]))); } +#if defined(__i386__) && (defined(COMPAT_FREEBSD4) || defined(COMPAT_43)) +struct oshmid_ds { + struct ipc_perm_old shm_perm; /* operation perms */ + int shm_segsz; /* size of segment (bytes) */ + u_short shm_cpid; /* pid, creator */ + u_short shm_lpid; /* pid, last operation */ + short shm_nattch; /* no. of current attaches */ + time_t shm_atime; /* last attach time */ + time_t shm_dtime; /* last detach time */ + time_t shm_ctime; /* last change time */ + void *shm_handle; /* internal handle for shm segment */ +}; + +struct oshmctl_args { + int shmid; + int cmd; + struct oshmid_ds *ubuf; +}; + static int +oshmctl(td, uap) + struct thread *td; + struct oshmctl_args *uap; +{ +#ifdef COMPAT_43 + int error = 0; + struct shmid_kernel *shmseg; + struct oshmid_ds outbuf; + + if (!prison_allow(td->td_ucred, PR_ALLOW_SYSVIPC)) + return (ENOSYS); + mtx_lock(&Giant); + shmseg = shm_find_segment_by_shmid(uap->shmid); + if (shmseg == NULL) { + error = EINVAL; + goto done2; + } + switch (uap->cmd) { + case IPC_STAT: + error = ipcperm(td, &shmseg->u.shm_perm, IPC_R); + if (error) + goto done2; +#ifdef MAC + error = mac_sysvshm_check_shmctl(td->td_ucred, shmseg, uap->cmd); + if (error != 0) + goto done2; +#endif + ipcperm_new2old(&shmseg->u.shm_perm, &outbuf.shm_perm); + outbuf.shm_segsz = shmseg->u.shm_segsz; + outbuf.shm_cpid = shmseg->u.shm_cpid; + outbuf.shm_lpid = shmseg->u.shm_lpid; + outbuf.shm_nattch = shmseg->u.shm_nattch; + outbuf.shm_atime = shmseg->u.shm_atime; + outbuf.shm_dtime = shmseg->u.shm_dtime; + outbuf.shm_ctime = shmseg->u.shm_ctime; + outbuf.shm_handle = shmseg->object; + error = copyout(&outbuf, uap->ubuf, sizeof(outbuf)); + if (error) + goto done2; + break; + default: + error = freebsd7_shmctl(td, (struct shmctl_args *)uap); + break; + } +done2: + mtx_unlock(&Giant); + return (error); +#else + return (EINVAL); +#endif +} + +/* XXX casting to (sy_call_t *) is bogus, as usual. */ +static sy_call_t *shmcalls[] = { + (sy_call_t *)shmat, (sy_call_t *)oshmctl, + (sy_call_t *)shmdt, (sy_call_t *)shmget, + (sy_call_t *)freebsd7_shmctl +}; + +int +shmsys(td, uap) + struct thread *td; + /* XXX actually varargs. */ + struct shmsys_args /* { + int which; + int a2; + int a3; + int a4; + } */ *uap; +{ + int error; + + if (!prison_allow(td->td_ucred, PR_ALLOW_SYSVIPC)) + return (ENOSYS); + if (uap->which < 0 || + uap->which >= sizeof(shmcalls)/sizeof(shmcalls[0])) + return (EINVAL); + mtx_lock(&Giant); + error = (*shmcalls[uap->which])(td, &uap->a2); + mtx_unlock(&Giant); + return (error); +} + +SYSCALL_MODULE_HELPER(shmsys); +#endif /* i386 && (COMPAT_FREEBSD4 || COMPAT_43) */ + +#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \ + defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7) + +#define CP(src, dst, fld) do { (dst).fld = (src).fld; } while (0) + + +#ifndef _SYS_SYSPROTO_H_ +struct freebsd7_shmctl_args { + int shmid; + int cmd; + struct shmid_ds_old *buf; +}; +#endif +int +freebsd7_shmctl(td, uap) + struct thread *td; + struct freebsd7_shmctl_args *uap; +{ + int error = 0; + struct shmid_ds_old old; + struct shmid_ds buf; + size_t bufsz; + + /* + * The only reason IPC_INFO, SHM_INFO, SHM_STAT exists is to support + * Linux binaries. If we see the call come through the FreeBSD ABI, + * return an error back to the user since we do not to support this. + */ + if (uap->cmd == IPC_INFO || uap->cmd == SHM_INFO || + uap->cmd == SHM_STAT) + return (EINVAL); + + /* IPC_SET needs to copyin the buffer before calling kern_shmctl */ + if (uap->cmd == IPC_SET) { + if ((error = copyin(uap->buf, &old, sizeof(old)))) + goto done; + ipcperm_old2new(&old.shm_perm, &buf.shm_perm); + CP(old, buf, shm_segsz); + CP(old, buf, shm_lpid); + CP(old, buf, shm_cpid); + CP(old, buf, shm_nattch); + CP(old, buf, shm_atime); + CP(old, buf, shm_dtime); + CP(old, buf, shm_ctime); + } + + error = kern_shmctl(td, uap->shmid, uap->cmd, (void *)&buf, &bufsz); + if (error) + goto done; + + /* Cases in which we need to copyout */ + switch (uap->cmd) { + case IPC_STAT: + ipcperm_new2old(&buf.shm_perm, &old.shm_perm); + if (buf.shm_segsz > INT_MAX) + old.shm_segsz = INT_MAX; + else + CP(buf, old, shm_segsz); + CP(buf, old, shm_lpid); + CP(buf, old, shm_cpid); + if (buf.shm_nattch > SHRT_MAX) + old.shm_nattch = SHRT_MAX; + else + CP(buf, old, shm_nattch); + CP(buf, old, shm_atime); + CP(buf, old, shm_dtime); + CP(buf, old, shm_ctime); + old.shm_internal = NULL; + error = copyout(&old, uap->buf, sizeof(old)); + break; + } + +done: + if (error) { + /* Invalidate the return value */ + td->td_retval[0] = -1; + } + return (error); +} + +SYSCALL_MODULE_HELPER(freebsd7_shmctl); + +#undef CP + +#endif /* COMPAT_FREEBSD4 || COMPAT_FREEBSD5 || COMPAT_FREEBSD6 || + COMPAT_FREEBSD7 */ + +static int sysvshm_modload(struct module *module, int cmd, void *arg) { int error = 0; @@ -1021,12 +1100,10 @@ NULL }; -SYSCALL_MODULE_HELPER(shmsys); SYSCALL_MODULE_HELPER(shmat); SYSCALL_MODULE_HELPER(shmctl); SYSCALL_MODULE_HELPER(shmdt); SYSCALL_MODULE_HELPER(shmget); -DECLARE_MODULE(sysvshm, sysvshm_mod, - SI_SUB_SYSV_SHM, SI_ORDER_FIRST); +DECLARE_MODULE(sysvshm, sysvshm_mod, SI_SUB_SYSV_SHM, SI_ORDER_FIRST); MODULE_VERSION(sysvshm, 1); Index: sys/kern/init_sysent.c =================================================================== --- sys/kern/init_sysent.c (revision 194647) +++ sys/kern/init_sysent.c (working copy) @@ -26,6 +26,12 @@ #define compat4(n, name) 0, (sy_call_t *)nosys #endif +#ifdef COMPAT_FREEBSD7 +#define compat7(n, name) n, (sy_call_t *)__CONCAT(freebsd7_,name) +#else +#define compat7(n, name) 0, (sy_call_t *)nosys +#endif + /* The casts are bogus but will do for now. */ struct sysent sysent[] = { { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 }, /* 0 = syscall */ @@ -248,16 +254,16 @@ { AS(nosys_args), (sy_call_t *)lkmnosys, AUE_NULL, NULL, 0, 0, 0 }, /* 217 = lkmnosys */ { AS(nosys_args), (sy_call_t *)lkmnosys, AUE_NULL, NULL, 0, 0, 0 }, /* 218 = lkmnosys */ { AS(nosys_args), (sy_call_t *)lkmnosys, AUE_NULL, NULL, 0, 0, 0 }, /* 219 = lkmnosys */ - { AS(__semctl_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 }, /* 220 = __semctl */ + { 0, (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 }, /* 220 = freebsd7 __semctl */ { AS(semget_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 }, /* 221 = semget */ { AS(semop_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 }, /* 222 = semop */ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 }, /* 223 = semconfig */ - { AS(msgctl_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 }, /* 224 = msgctl */ + { 0, (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 }, /* 224 = freebsd7 msgctl */ { AS(msgget_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 }, /* 225 = msgget */ { AS(msgsnd_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 }, /* 226 = msgsnd */ { AS(msgrcv_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 }, /* 227 = msgrcv */ { AS(shmat_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 }, /* 228 = shmat */ - { AS(shmctl_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 }, /* 229 = shmctl */ + { 0, (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 }, /* 229 = freebsd7 shmctl */ { AS(shmdt_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 }, /* 230 = shmdt */ { AS(shmget_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 }, /* 231 = shmget */ { AS(clock_gettime_args), (sy_call_t *)clock_gettime, AUE_NULL, NULL, 0, 0, 0 }, /* 232 = clock_gettime */ @@ -538,4 +544,7 @@ { AS(jail_set_args), (sy_call_t *)jail_set, AUE_NULL, NULL, 0, 0, 0 }, /* 507 = jail_set */ { AS(jail_remove_args), (sy_call_t *)jail_remove, AUE_NULL, NULL, 0, 0, 0 }, /* 508 = jail_remove */ { AS(closefrom_args), (sy_call_t *)closefrom, AUE_CLOSEFROM, NULL, 0, 0, 0 }, /* 509 = closefrom */ + { AS(__semctl_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 }, /* 510 = __semctl */ + { AS(msgctl_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 }, /* 511 = msgctl */ + { AS(shmctl_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 }, /* 512 = shmctl */ }; Index: sys/kern/makesyscalls.sh =================================================================== --- sys/kern/makesyscalls.sh (revision 194647) +++ sys/kern/makesyscalls.sh (working copy) @@ -8,6 +8,7 @@ compat=COMPAT_43 compat4=COMPAT_FREEBSD4 compat6=COMPAT_FREEBSD6 +compat7=COMPAT_FREEBSD7 # output files: sysnames="syscalls.c" @@ -30,15 +31,17 @@ syscompat4dcl="sysent.compat4dcl.$$" syscompat6="sysent.compat6.$$" syscompat6dcl="sysent.compat6dcl.$$" +syscompat7="sysent.compat7.$$" +syscompat7dcl="sysent.compat7dcl.$$" sysent="sysent.switch.$$" sysinc="sysinc.switch.$$" sysarg="sysarg.switch.$$" sysprotoend="sysprotoend.$$" systracetmp="systrace.$$" -trap "rm $sysaue $sysdcl $syscompat $syscompatdcl $syscompat4 $syscompat4dcl $syscompat6 $syscompat6dcl $sysent $sysinc $sysarg $sysprotoend $systracetmp" 0 +trap "rm $sysaue $sysdcl $syscompat $syscompatdcl $syscompat4 $syscompat4dcl $syscompat6 $syscompat6dcl $syscompat7 $syscompat7dcl $sysent $sysinc $sysarg $sysprotoend $systracetmp" 0 -touch $sysaue $sysdcl $syscompat $syscompatdcl $syscompat4 $syscompat4dcl $syscompat6 $syscompat6dcl $sysent $sysinc $sysarg $sysprotoend $systracetmp +touch $sysaue $sysdcl $syscompat $syscompatdcl $syscompat4 $syscompat4dcl $syscompat6 $syscompat6dcl $syscompat7 $syscompat7dcl $sysent $sysinc $sysarg $sysprotoend $systracetmp case $# in 0) echo "usage: $0 input-file " 1>&2 @@ -75,6 +78,8 @@ syscompat4dcl = \"$syscompat4dcl\" syscompat6 = \"$syscompat6\" syscompat6dcl = \"$syscompat6dcl\" + syscompat7 = \"$syscompat7\" + syscompat7dcl = \"$syscompat7dcl\" sysent = \"$sysent\" syssw = \"$syssw\" sysinc = \"$sysinc\" @@ -87,6 +92,7 @@ compat = \"$compat\" compat4 = \"$compat4\" compat6 = \"$compat6\" + compat7 = \"$compat7\" syscallprefix = \"$syscallprefix\" switchname = \"$switchname\" namesname = \"$namesname\" @@ -104,6 +110,7 @@ printf "\n#ifdef %s\n\n", compat > syscompat printf "\n#ifdef %s\n\n", compat4 > syscompat4 printf "\n#ifdef %s\n\n", compat6 > syscompat6 + printf "\n#ifdef %s\n\n", compat7 > syscompat7 printf "/*\n * System call names.\n *\n" > sysnames printf " * DO NOT EDIT-- this file is automatically generated.\n" > sysnames @@ -181,6 +188,7 @@ print > syscompat print > syscompat4 print > syscompat6 + print > syscompat7 print > sysnames savesyscall = syscall next @@ -192,6 +200,7 @@ print > syscompat print > syscompat4 print > syscompat6 + print > syscompat7 print > sysnames syscall = savesyscall next @@ -203,6 +212,7 @@ print > syscompat print > syscompat4 print > syscompat6 + print > syscompat7 print > sysnames next } @@ -286,6 +296,8 @@ argalias = "freebsd4_" argalias if (flag("COMPAT6")) argalias = "freebsd6_" argalias + if (flag("COMPAT7")) + argalias = "freebsd7_" argalias } f++ @@ -407,7 +419,8 @@ syscall++ next } - type("COMPAT") || type("COMPAT4") || type("COMPAT6") { + type("COMPAT") || type("COMPAT4") || type("COMPAT6") || \ + type("COMPAT7") { if (flag("COMPAT")) { ncompat++ out = syscompat @@ -429,6 +442,13 @@ wrap = "compat6" prefix = "freebsd6_" descr = "freebsd6" + } else if (flag("COMPAT7")) { + ncompat7++ + out = syscompat7 + outdcl = syscompat7dcl + wrap = "compat7" + prefix = "freebsd7_" + descr = "freebsd7" } parseline() if (argc != 0 && !flag("NOARGS") && !flag("NOPROTO") && \ @@ -520,7 +540,7 @@ END { printf "\n#define AS(name) (sizeof(struct name) / sizeof(register_t))\n" > sysinc - if (ncompat != 0 || ncompat4 != 0 || ncompat6 != 0) + if (ncompat != 0 || ncompat4 != 0 || ncompat6 != 0 || ncompat7 != 0) printf "#include \"opt_compat.h\"\n\n" > syssw if (ncompat != 0) { @@ -547,9 +567,18 @@ printf "#endif\n" > sysinc } + if (ncompat7 != 0) { + printf "\n#ifdef %s\n", compat7 > sysinc + printf "#define compat7(n, name) n, (sy_call_t *)__CONCAT(freebsd7_,name)\n" > sysinc + printf "#else\n" > sysinc + printf "#define compat7(n, name) 0, (sy_call_t *)nosys\n" > sysinc + printf "#endif\n" > sysinc + } + printf("\n#endif /* %s */\n\n", compat) > syscompatdcl printf("\n#endif /* %s */\n\n", compat4) > syscompat4dcl printf("\n#endif /* %s */\n\n", compat6) > syscompat6dcl + printf("\n#endif /* %s */\n\n", compat7) > syscompat7dcl printf("\n#undef PAD_\n") > sysprotoend printf("#undef PADL_\n") > sysprotoend @@ -570,6 +599,7 @@ $syscompat $syscompatdcl \ $syscompat4 $syscompat4dcl \ $syscompat6 $syscompat6dcl \ + $syscompat7 $syscompat7dcl \ $sysaue $sysprotoend > $sysproto cat $systracetmp >> $systrace Index: sys/kern/syscalls.c =================================================================== --- sys/kern/syscalls.c (revision 194647) +++ sys/kern/syscalls.c (working copy) @@ -227,16 +227,16 @@ "lkmnosys", /* 217 = lkmnosys */ "lkmnosys", /* 218 = lkmnosys */ "lkmnosys", /* 219 = lkmnosys */ - "__semctl", /* 220 = __semctl */ + "compat7.__semctl", /* 220 = freebsd7 __semctl */ "semget", /* 221 = semget */ "semop", /* 222 = semop */ "#223", /* 223 = semconfig */ - "msgctl", /* 224 = msgctl */ + "compat7.msgctl", /* 224 = freebsd7 msgctl */ "msgget", /* 225 = msgget */ "msgsnd", /* 226 = msgsnd */ "msgrcv", /* 227 = msgrcv */ "shmat", /* 228 = shmat */ - "shmctl", /* 229 = shmctl */ + "compat7.shmctl", /* 229 = freebsd7 shmctl */ "shmdt", /* 230 = shmdt */ "shmget", /* 231 = shmget */ "clock_gettime", /* 232 = clock_gettime */ @@ -517,4 +517,7 @@ "jail_set", /* 507 = jail_set */ "jail_remove", /* 508 = jail_remove */ "closefrom", /* 509 = closefrom */ + "__semctl", /* 510 = __semctl */ + "msgctl", /* 511 = msgctl */ + "shmctl", /* 512 = shmctl */ }; Index: sys/kern/sysv_ipc.c =================================================================== --- sys/kern/sysv_ipc.c (revision 194647) +++ sys/kern/sysv_ipc.c (working copy) @@ -36,6 +36,7 @@ #include __FBSDID("$FreeBSD$"); +#include "opt_compat.h" #include "opt_sysvipc.h" #include @@ -147,3 +148,33 @@ else return (EACCES); } + +#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \ + defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7) +void +ipcperm_old2new(struct ipc_perm_old *old, struct ipc_perm *new) +{ + + new->cuid = old->cuid; + new->cgid = old->cgid; + new->uid = old->uid; + new->gid = old->gid; + new->mode = old->mode; + new->seq = old->seq; + new->key = old->key; +} + +void +ipcperm_new2old(struct ipc_perm *new, struct ipc_perm_old *old) +{ + + /* XXX: How to handle ID's > USHORT_MAX? */ + old->cuid = new->cuid; + old->cgid = new->cgid; + old->uid = new->uid; + old->gid = new->gid; + old->mode = new->mode; + old->seq = new->seq; + old->key = new->key; +} +#endif Index: sys/kern/syscalls.master =================================================================== --- sys/kern/syscalls.master (revision 194647) +++ sys/kern/syscalls.master (working copy) @@ -12,7 +12,7 @@ ; case where the event exists, but we don't want auditing, the ; event should be #defined to AUE_NULL in audit_kevents.h. ; type one of STD, OBSOL, UNIMPL, COMPAT, COMPAT4, COMPAT6, -; LIBCOMPAT, NODEF, NOARGS, NOPROTO, NOSTD +; COMPAT7, LIBCOMPAT, NODEF, NOARGS, NOPROTO, NOSTD ; The COMPAT* options may be combined with one or more NO* ; options separated by '|' with no spaces (e.g. COMPAT|NOARGS) ; name psuedo-prototype of syscall routine @@ -27,6 +27,7 @@ ; COMPAT included on COMPAT #ifdef ; COMPAT4 included on COMPAT4 #ifdef (FreeBSD 4 compat) ; COMPAT6 included on COMPAT6 #ifdef (FreeBSD 6 compat) +; COMPAT7 included on COMPAT7 #ifdef (FreeBSD 7 compat) ; LIBCOMPAT included on COMPAT #ifdef, and placed in syscall.h ; OBSOL obsolete, not included in system, only specifies name ; UNIMPL not implemented, placeholder only @@ -333,15 +334,12 @@ struct rtprio *rtp); } 167 AUE_NULL UNIMPL nosys 168 AUE_NULL UNIMPL nosys -; 169 is initialized by the SYSVSEM code if present or loaded 169 AUE_SEMSYS NOSTD { int semsys(int which, int a2, int a3, \ int a4, int a5); } ; XXX should be { int semsys(int which, ...); } -; 170 is initialized by the SYSVMSG code if present or loaded 170 AUE_MSGSYS NOSTD { int msgsys(int which, int a2, int a3, \ int a4, int a5, int a6); } ; XXX should be { int msgsys(int which, ...); } -; 171 is initialized by the SYSVSHM code if present or loaded 171 AUE_SHMSYS NOSTD { int shmsys(int which, int a2, int a3, \ int a4); } ; XXX should be { int shmsys(int which, ...); } @@ -419,15 +417,15 @@ ; ; The following were introduced with NetBSD/4.4Lite-2 -220 AUE_SEMCTL NOSTD { int __semctl(int semid, int semnum, \ - int cmd, union semun *arg); } +220 AUE_SEMCTL COMPAT7|NOSTD { int __semctl(int semid, int semnum, \ + int cmd, union semun_old *arg); } 221 AUE_SEMGET NOSTD { int semget(key_t key, int nsems, \ int semflg); } 222 AUE_SEMOP NOSTD { int semop(int semid, struct sembuf *sops, \ size_t nsops); } 223 AUE_NULL UNIMPL semconfig -224 AUE_MSGCTL NOSTD { int msgctl(int msqid, int cmd, \ - struct msqid_ds *buf); } +224 AUE_MSGCTL COMPAT7|NOSTD { int msgctl(int msqid, int cmd, \ + struct msqid_ds_old *buf); } 225 AUE_MSGGET NOSTD { int msgget(key_t key, int msgflg); } 226 AUE_MSGSND NOSTD { int msgsnd(int msqid, const void *msgp, \ size_t msgsz, int msgflg); } @@ -435,8 +433,8 @@ size_t msgsz, long msgtyp, int msgflg); } 228 AUE_SHMAT NOSTD { int shmat(int shmid, const void *shmaddr, \ int shmflg); } -229 AUE_SHMCTL NOSTD { int shmctl(int shmid, int cmd, \ - struct shmid_ds *buf); } +229 AUE_SHMCTL COMPAT7|NOSTD { int shmctl(int shmid, int cmd, \ + struct shmid_ds_old *buf); } 230 AUE_SHMDT NOSTD { int shmdt(const void *shmaddr); } 231 AUE_SHMGET NOSTD { int shmget(key_t key, size_t size, \ int shmflg); } @@ -906,5 +904,11 @@ unsigned int iovcnt, int flags); } 508 AUE_NULL STD { int jail_remove(int jid); } 509 AUE_CLOSEFROM STD { int closefrom(int lowfd); } +510 AUE_SEMCTL NOSTD { int __semctl(int semid, int semnum, \ + int cmd, union semun *arg); } +511 AUE_MSGCTL NOSTD { int msgctl(int msqid, int cmd, \ + struct msqid_ds *buf); } +512 AUE_SHMCTL NOSTD { int shmctl(int shmid, int cmd, \ + struct shmid_ds *buf); } ; Please copy any additions and changes to the following compatability tables: ; sys/compat/freebsd32/syscalls.master Index: sys/kern/systrace_args.c =================================================================== --- sys/kern/systrace_args.c (revision 194647) +++ sys/kern/systrace_args.c (working copy) @@ -1192,16 +1192,6 @@ *n_args = 0; break; } - /* __semctl */ - case 220: { - struct __semctl_args *p = params; - iarg[0] = p->semid; /* int */ - iarg[1] = p->semnum; /* int */ - iarg[2] = p->cmd; /* int */ - uarg[3] = (intptr_t) p->arg; /* union semun * */ - *n_args = 4; - break; - } /* semget */ case 221: { struct semget_args *p = params; @@ -1220,15 +1210,6 @@ *n_args = 3; break; } - /* msgctl */ - case 224: { - struct msgctl_args *p = params; - iarg[0] = p->msqid; /* int */ - iarg[1] = p->cmd; /* int */ - uarg[2] = (intptr_t) p->buf; /* struct msqid_ds * */ - *n_args = 3; - break; - } /* msgget */ case 225: { struct msgget_args *p = params; @@ -1267,15 +1248,6 @@ *n_args = 3; break; } - /* shmctl */ - case 229: { - struct shmctl_args *p = params; - iarg[0] = p->shmid; /* int */ - iarg[1] = p->cmd; /* int */ - uarg[2] = (intptr_t) p->buf; /* struct shmid_ds * */ - *n_args = 3; - break; - } /* shmdt */ case 230: { struct shmdt_args *p = params; @@ -3064,6 +3036,34 @@ *n_args = 1; break; } + /* __semctl */ + case 510: { + struct __semctl_args *p = params; + iarg[0] = p->semid; /* int */ + iarg[1] = p->semnum; /* int */ + iarg[2] = p->cmd; /* int */ + uarg[3] = (intptr_t) p->arg; /* union semun * */ + *n_args = 4; + break; + } + /* msgctl */ + case 511: { + struct msgctl_args *p = params; + iarg[0] = p->msqid; /* int */ + iarg[1] = p->cmd; /* int */ + uarg[2] = (intptr_t) p->buf; /* struct msqid_ds * */ + *n_args = 3; + break; + } + /* shmctl */ + case 512: { + struct shmctl_args *p = params; + iarg[0] = p->shmid; /* int */ + iarg[1] = p->cmd; /* int */ + uarg[2] = (intptr_t) p->buf; /* struct shmid_ds * */ + *n_args = 3; + break; + } default: *n_args = 0; break; @@ -4953,25 +4953,6 @@ /* lkmnosys */ case 219: break; - /* __semctl */ - case 220: - switch(ndx) { - case 0: - p = "int"; - break; - case 1: - p = "int"; - break; - case 2: - p = "int"; - break; - case 3: - p = "union semun *"; - break; - default: - break; - }; - break; /* semget */ case 221: switch(ndx) { @@ -5004,22 +4985,6 @@ break; }; break; - /* msgctl */ - case 224: - switch(ndx) { - case 0: - p = "int"; - break; - case 1: - p = "int"; - break; - case 2: - p = "struct msqid_ds *"; - break; - default: - break; - }; - break; /* msgget */ case 225: switch(ndx) { @@ -5090,22 +5055,6 @@ break; }; break; - /* shmctl */ - case 229: - switch(ndx) { - case 0: - p = "int"; - break; - case 1: - p = "int"; - break; - case 2: - p = "struct shmid_ds *"; - break; - default: - break; - }; - break; /* shmdt */ case 230: switch(ndx) { @@ -8133,6 +8082,57 @@ break; }; break; + /* __semctl */ + case 510: + switch(ndx) { + case 0: + p = "int"; + break; + case 1: + p = "int"; + break; + case 2: + p = "int"; + break; + case 3: + p = "union semun *"; + break; + default: + break; + }; + break; + /* msgctl */ + case 511: + switch(ndx) { + case 0: + p = "int"; + break; + case 1: + p = "int"; + break; + case 2: + p = "struct msqid_ds *"; + break; + default: + break; + }; + break; + /* shmctl */ + case 512: + switch(ndx) { + case 0: + p = "int"; + break; + case 1: + p = "int"; + break; + case 2: + p = "struct shmid_ds *"; + break; + default: + break; + }; + break; default: break; }; Index: sys/compat/freebsd32/freebsd32_syscall.h =================================================================== --- sys/compat/freebsd32/freebsd32_syscall.h (revision 194647) +++ sys/compat/freebsd32/freebsd32_syscall.h (working copy) @@ -190,15 +190,15 @@ #define FREEBSD32_SYS_freebsd32_futimes 206 #define FREEBSD32_SYS_getpgid 207 #define FREEBSD32_SYS_poll 209 -#define FREEBSD32_SYS_freebsd32_semctl 220 +#define FREEBSD32_SYS_freebsd7_freebsd32_semctl 220 #define FREEBSD32_SYS_semget 221 #define FREEBSD32_SYS_semop 222 -#define FREEBSD32_SYS_freebsd32_msgctl 224 +#define FREEBSD32_SYS_freebsd7_freebsd32_msgctl 224 #define FREEBSD32_SYS_msgget 225 #define FREEBSD32_SYS_freebsd32_msgsnd 226 #define FREEBSD32_SYS_freebsd32_msgrcv 227 #define FREEBSD32_SYS_shmat 228 -#define FREEBSD32_SYS_freebsd32_shmctl 229 +#define FREEBSD32_SYS_freebsd7_freebsd32_shmctl 229 #define FREEBSD32_SYS_shmdt 230 #define FREEBSD32_SYS_shmget 231 #define FREEBSD32_SYS_freebsd32_clock_gettime 232 @@ -378,4 +378,7 @@ #define FREEBSD32_SYS_freebsd32_jail_set 507 #define FREEBSD32_SYS_jail_remove 508 #define FREEBSD32_SYS_closefrom 509 -#define FREEBSD32_SYS_MAXSYSCALL 510 +#define FREEBSD32_SYS_freebsd32_semctl 510 +#define FREEBSD32_SYS_freebsd32_msgctl 511 +#define FREEBSD32_SYS_freebsd32_shmctl 512 +#define FREEBSD32_SYS_MAXSYSCALL 513 Index: sys/compat/freebsd32/freebsd32_ipc.h =================================================================== --- sys/compat/freebsd32/freebsd32_ipc.h (revision 194647) +++ sys/compat/freebsd32/freebsd32_ipc.h (working copy) @@ -30,11 +30,11 @@ #define _COMPAT_FREEBSD32_FREEBSD32_IPC_H_ struct ipc_perm32 { - uint16_t cuid; - uint16_t cgid; - uint16_t uid; - uint16_t gid; - uint16_t mode; + uid_t cuid; + gid_t cgid; + uid_t uid; + gid_t gid; + mode_t mode; uint16_t seq; uint32_t key; }; @@ -44,10 +44,7 @@ uint32_t sem_base; unsigned short sem_nsems; int32_t sem_otime; - int32_t sem_pad1; int32_t sem_ctime; - int32_t sem_pad2; - int32_t sem_pad3[4]; }; union semun32 { @@ -66,24 +63,19 @@ pid_t msg_lspid; pid_t msg_lrpid; int32_t msg_stime; - int32_t msg_pad1; int32_t msg_rtime; - int32_t msg_pad2; int32_t msg_ctime; - int32_t msg_pad3; - int32_t msg_pad4[4]; }; struct shmid_ds32 { struct ipc_perm32 shm_perm; int32_t shm_segsz; - int32_t shm_lpid; - int32_t shm_cpid; - int16_t shm_nattch; + pid_t shm_lpid; + pid_t shm_cpid; + int shm_nattch; int32_t shm_atime; int32_t shm_dtime; int32_t shm_ctime; - uint32_t shm_internal; }; struct shm_info32 { @@ -103,4 +95,58 @@ uint32_t shmall; }; +#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \ + defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7) +struct ipc_perm32_old { + uint16_t cuid; + uint16_t cgid; + uint16_t uid; + uint16_t gid; + uint16_t mode; + uint16_t seq; + uint32_t key; +}; + +struct semid_ds32_old { + struct ipc_perm32_old sem_perm; + uint32_t sem_base; + unsigned short sem_nsems; + int32_t sem_otime; + int32_t sem_pad1; + int32_t sem_ctime; + int32_t sem_pad2; + int32_t sem_pad3[4]; +}; + +struct msqid_ds32_old { + struct ipc_perm32_old msg_perm; + uint32_t msg_first; + uint32_t msg_last; + uint32_t msg_cbytes; + uint32_t msg_qnum; + uint32_t msg_qbytes; + pid_t msg_lspid; + pid_t msg_lrpid; + int32_t msg_stime; + int32_t msg_pad1; + int32_t msg_rtime; + int32_t msg_pad2; + int32_t msg_ctime; + int32_t msg_pad3; + int32_t msg_pad4[4]; +}; + +struct shmid_ds32_old { + struct ipc_perm32_old shm_perm; + int32_t shm_segsz; + pid_t shm_lpid; + pid_t shm_cpid; + int16_t shm_nattch; + int32_t shm_atime; + int32_t shm_dtime; + int32_t shm_ctime; + uint32_t shm_internal; +}; +#endif + #endif /* !_COMPAT_FREEBSD32_FREEBSD32_IPC_H_ */ Index: sys/compat/freebsd32/freebsd32_sysent.c =================================================================== --- sys/compat/freebsd32/freebsd32_sysent.c (revision 194647) +++ sys/compat/freebsd32/freebsd32_sysent.c (working copy) @@ -36,6 +36,12 @@ #define compat6(n, name) 0, (sy_call_t *)nosys #endif +#ifdef COMPAT_FREEBSD7 +#define compat7(n, name) n, (sy_call_t *)__CONCAT(freebsd7_,name) +#else +#define compat7(n, name) 0, (sy_call_t *)nosys +#endif + /* The casts are bogus but will do for now. */ struct sysent freebsd32_sysent[] = { { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 }, /* 0 = syscall */ @@ -258,16 +264,16 @@ { AS(nosys_args), (sy_call_t *)lkmnosys, AUE_NULL, NULL, 0, 0, 0 }, /* 217 = lkmnosys */ { AS(nosys_args), (sy_call_t *)lkmnosys, AUE_NULL, NULL, 0, 0, 0 }, /* 218 = lkmnosys */ { AS(nosys_args), (sy_call_t *)lkmnosys, AUE_NULL, NULL, 0, 0, 0 }, /* 219 = lkmnosys */ - { AS(freebsd32_semctl_args), (sy_call_t *)freebsd32_semctl, AUE_SEMCTL, NULL, 0, 0, 0 }, /* 220 = freebsd32_semctl */ + { compat7(AS(freebsd7_freebsd32_semctl_args),freebsd32_semctl), AUE_SEMCTL, NULL, 0, 0, 0 }, /* 220 = freebsd7 freebsd32_semctl */ { AS(semget_args), (sy_call_t *)semget, AUE_SEMGET, NULL, 0, 0, 0 }, /* 221 = semget */ { AS(semop_args), (sy_call_t *)semop, AUE_SEMOP, NULL, 0, 0, 0 }, /* 222 = semop */ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 }, /* 223 = semconfig */ - { AS(freebsd32_msgctl_args), (sy_call_t *)freebsd32_msgctl, AUE_MSGCTL, NULL, 0, 0, 0 }, /* 224 = freebsd32_msgctl */ + { compat7(AS(freebsd7_freebsd32_msgctl_args),freebsd32_msgctl), AUE_MSGCTL, NULL, 0, 0, 0 }, /* 224 = freebsd7 freebsd32_msgctl */ { AS(msgget_args), (sy_call_t *)msgget, AUE_MSGGET, NULL, 0, 0, 0 }, /* 225 = msgget */ { AS(freebsd32_msgsnd_args), (sy_call_t *)freebsd32_msgsnd, AUE_MSGSND, NULL, 0, 0, 0 }, /* 226 = freebsd32_msgsnd */ { AS(freebsd32_msgrcv_args), (sy_call_t *)freebsd32_msgrcv, AUE_MSGRCV, NULL, 0, 0, 0 }, /* 227 = freebsd32_msgrcv */ { AS(shmat_args), (sy_call_t *)shmat, AUE_SHMAT, NULL, 0, 0, 0 }, /* 228 = shmat */ - { AS(freebsd32_shmctl_args), (sy_call_t *)freebsd32_shmctl, AUE_SHMCTL, NULL, 0, 0, 0 }, /* 229 = freebsd32_shmctl */ + { compat7(AS(freebsd7_freebsd32_shmctl_args),freebsd32_shmctl), AUE_SHMCTL, NULL, 0, 0, 0 }, /* 229 = freebsd7 freebsd32_shmctl */ { AS(shmdt_args), (sy_call_t *)shmdt, AUE_SHMDT, NULL, 0, 0, 0 }, /* 230 = shmdt */ { AS(shmget_args), (sy_call_t *)shmget, AUE_SHMGET, NULL, 0, 0, 0 }, /* 231 = shmget */ { AS(freebsd32_clock_gettime_args), (sy_call_t *)freebsd32_clock_gettime, AUE_NULL, NULL, 0, 0, 0 }, /* 232 = freebsd32_clock_gettime */ @@ -548,4 +554,7 @@ { AS(freebsd32_jail_set_args), (sy_call_t *)freebsd32_jail_set, AUE_NULL, NULL, 0, 0, 0 }, /* 507 = freebsd32_jail_set */ { AS(jail_remove_args), (sy_call_t *)jail_remove, AUE_NULL, NULL, 0, 0, 0 }, /* 508 = jail_remove */ { AS(closefrom_args), (sy_call_t *)closefrom, AUE_CLOSEFROM, NULL, 0, 0, 0 }, /* 509 = closefrom */ + { AS(freebsd32_semctl_args), (sy_call_t *)freebsd32_semctl, AUE_SEMCTL, NULL, 0, 0, 0 }, /* 510 = freebsd32_semctl */ + { AS(freebsd32_msgctl_args), (sy_call_t *)freebsd32_msgctl, AUE_MSGCTL, NULL, 0, 0, 0 }, /* 511 = freebsd32_msgctl */ + { AS(freebsd32_shmctl_args), (sy_call_t *)freebsd32_shmctl, AUE_SHMCTL, NULL, 0, 0, 0 }, /* 512 = freebsd32_shmctl */ }; Index: sys/compat/freebsd32/syscalls.master =================================================================== --- sys/compat/freebsd32/syscalls.master (revision 194647) +++ sys/compat/freebsd32/syscalls.master (working copy) @@ -13,7 +13,7 @@ ; case where the event exists, but we don't want auditing, the ; event should be #defined to AUE_NULL in audit_kevents.h. ; type one of STD, OBSOL, UNIMPL, COMPAT, COMPAT4, COMPAT6, -; LIBCOMPAT, NODEF, NOARGS, NOPROTO, NOSTD +; COMPAT7, LIBCOMPAT, NODEF, NOARGS, NOPROTO, NOSTD ; The COMPAT* options may be combined with one or more NO* ; options separated by '|' with no spaces (e.g. COMPAT|NOARGS) ; name psuedo-prototype of syscall routine @@ -28,6 +28,7 @@ ; COMPAT included on COMPAT #ifdef ; COMPAT4 included on COMPAT4 #ifdef (FreeBSD 4 compat) ; COMPAT6 included on COMPAT6 #ifdef (FreeBSD 6 compat) +; COMPAT7 included on COMPAT7 #ifdef (FreeBSD 7 compat) ; LIBCOMPAT included on COMPAT #ifdef, and placed in syscall.h ; OBSOL obsolete, not included in system, only specifies name ; UNIMPL not implemented, placeholder only @@ -404,15 +405,15 @@ ; The following were introduced with NetBSD/4.4Lite-2 ; They are initialized by thier respective modules/sysinits ; XXX PROBLEM!! -220 AUE_SEMCTL STD { int freebsd32_semctl(int semid, int semnum, \ +220 AUE_SEMCTL COMPAT7 { int freebsd32_semctl(int semid, int semnum, \ int cmd, union semun32 *arg); } 221 AUE_SEMGET NOPROTO { int semget(key_t key, int nsems, \ int semflg); } 222 AUE_SEMOP NOPROTO { int semop(int semid, struct sembuf *sops, \ u_int nsops); } 223 AUE_NULL UNIMPL semconfig -224 AUE_MSGCTL STD { int freebsd32_msgctl(int msqid, int cmd, \ - struct msqid_ds32 *buf); } +224 AUE_MSGCTL COMPAT7 { int freebsd32_msgctl(int msqid, int cmd, \ + struct msqid_ds32_old *buf); } 225 AUE_MSGGET NOPROTO { int msgget(key_t key, int msgflg); } 226 AUE_MSGSND STD { int freebsd32_msgsnd(int msqid, void *msgp, \ size_t msgsz, int msgflg); } @@ -420,8 +421,8 @@ size_t msgsz, long msgtyp, int msgflg); } 228 AUE_SHMAT NOPROTO { int shmat(int shmid, void *shmaddr, \ int shmflg); } -229 AUE_SHMCTL STD { int freebsd32_shmctl(int shmid, int cmd, \ - struct shmid_ds *buf); } +229 AUE_SHMCTL COMPAT7 { int freebsd32_shmctl(int shmid, int cmd, \ + struct shmid_ds32_old *buf); } 230 AUE_SHMDT NOPROTO { int shmdt(void *shmaddr); } 231 AUE_SHMGET NOPROTO { int shmget(key_t key, int size, \ int shmflg); } @@ -893,3 +894,9 @@ unsigned int iovcnt, int flags); } 508 AUE_NULL NOPROTO { int jail_remove(int jid); } 509 AUE_CLOSEFROM NOPROTO { int closefrom(int lowfd); } +510 AUE_SEMCTL STD { int freebsd32_semctl(int semid, int semnum, \ + int cmd, union semun32 *arg); } +511 AUE_MSGCTL STD { int freebsd32_msgctl(int msqid, int cmd, \ + struct msqid_ds32 *buf); } +512 AUE_SHMCTL STD { int freebsd32_shmctl(int shmid, int cmd, \ + struct shmid_ds32 *buf); } Index: sys/compat/freebsd32/freebsd32_proto.h =================================================================== --- sys/compat/freebsd32/freebsd32_proto.h (revision 194647) +++ sys/compat/freebsd32/freebsd32_proto.h (working copy) @@ -174,17 +174,6 @@ char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)]; char tptr_l_[PADL_(struct timeval32 *)]; struct timeval32 * tptr; char tptr_r_[PADR_(struct timeval32 *)]; }; -struct freebsd32_semctl_args { - char semid_l_[PADL_(int)]; int semid; char semid_r_[PADR_(int)]; - char semnum_l_[PADL_(int)]; int semnum; char semnum_r_[PADR_(int)]; - char cmd_l_[PADL_(int)]; int cmd; char cmd_r_[PADR_(int)]; - char arg_l_[PADL_(union semun32 *)]; union semun32 * arg; char arg_r_[PADR_(union semun32 *)]; -}; -struct freebsd32_msgctl_args { - char msqid_l_[PADL_(int)]; int msqid; char msqid_r_[PADR_(int)]; - char cmd_l_[PADL_(int)]; int cmd; char cmd_r_[PADR_(int)]; - char buf_l_[PADL_(struct msqid_ds32 *)]; struct msqid_ds32 * buf; char buf_r_[PADR_(struct msqid_ds32 *)]; -}; struct freebsd32_msgsnd_args { char msqid_l_[PADL_(int)]; int msqid; char msqid_r_[PADR_(int)]; char msgp_l_[PADL_(void *)]; void * msgp; char msgp_r_[PADR_(void *)]; @@ -198,11 +187,6 @@ char msgtyp_l_[PADL_(long)]; long msgtyp; char msgtyp_r_[PADR_(long)]; char msgflg_l_[PADL_(int)]; int msgflg; char msgflg_r_[PADR_(int)]; }; -struct freebsd32_shmctl_args { - char shmid_l_[PADL_(int)]; int shmid; char shmid_r_[PADR_(int)]; - char cmd_l_[PADL_(int)]; int cmd; char cmd_r_[PADR_(int)]; - char buf_l_[PADL_(struct shmid_ds *)]; struct shmid_ds * buf; char buf_r_[PADR_(struct shmid_ds *)]; -}; struct freebsd32_clock_gettime_args { char clock_id_l_[PADL_(clockid_t)]; clockid_t clock_id; char clock_id_r_[PADR_(clockid_t)]; char tp_l_[PADL_(struct timespec32 *)]; struct timespec32 * tp; char tp_r_[PADR_(struct timespec32 *)]; @@ -453,6 +437,22 @@ char iovcnt_l_[PADL_(unsigned int)]; unsigned int iovcnt; char iovcnt_r_[PADR_(unsigned int)]; char flags_l_[PADL_(int)]; int flags; char flags_r_[PADR_(int)]; }; +struct freebsd32_semctl_args { + char semid_l_[PADL_(int)]; int semid; char semid_r_[PADR_(int)]; + char semnum_l_[PADL_(int)]; int semnum; char semnum_r_[PADR_(int)]; + char cmd_l_[PADL_(int)]; int cmd; char cmd_r_[PADR_(int)]; + char arg_l_[PADL_(union semun32 *)]; union semun32 * arg; char arg_r_[PADR_(union semun32 *)]; +}; +struct freebsd32_msgctl_args { + char msqid_l_[PADL_(int)]; int msqid; char msqid_r_[PADR_(int)]; + char cmd_l_[PADL_(int)]; int cmd; char cmd_r_[PADR_(int)]; + char buf_l_[PADL_(struct msqid_ds32 *)]; struct msqid_ds32 * buf; char buf_r_[PADR_(struct msqid_ds32 *)]; +}; +struct freebsd32_shmctl_args { + char shmid_l_[PADL_(int)]; int shmid; char shmid_r_[PADR_(int)]; + char cmd_l_[PADL_(int)]; int cmd; char cmd_r_[PADR_(int)]; + char buf_l_[PADL_(struct shmid_ds32 *)]; struct shmid_ds32 * buf; char buf_r_[PADR_(struct shmid_ds32 *)]; +}; int freebsd32_wait4(struct thread *, struct freebsd32_wait4_args *); int freebsd32_recvmsg(struct thread *, struct freebsd32_recvmsg_args *); int freebsd32_sendmsg(struct thread *, struct freebsd32_sendmsg_args *); @@ -480,11 +480,8 @@ int freebsd32_getdirentries(struct thread *, struct freebsd32_getdirentries_args *); int freebsd32_sysctl(struct thread *, struct freebsd32_sysctl_args *); int freebsd32_futimes(struct thread *, struct freebsd32_futimes_args *); -int freebsd32_semctl(struct thread *, struct freebsd32_semctl_args *); -int freebsd32_msgctl(struct thread *, struct freebsd32_msgctl_args *); int freebsd32_msgsnd(struct thread *, struct freebsd32_msgsnd_args *); int freebsd32_msgrcv(struct thread *, struct freebsd32_msgrcv_args *); -int freebsd32_shmctl(struct thread *, struct freebsd32_shmctl_args *); int freebsd32_clock_gettime(struct thread *, struct freebsd32_clock_gettime_args *); int freebsd32_clock_settime(struct thread *, struct freebsd32_clock_settime_args *); int freebsd32_clock_getres(struct thread *, struct freebsd32_clock_getres_args *); @@ -536,6 +533,9 @@ int freebsd32_futimesat(struct thread *, struct freebsd32_futimesat_args *); int freebsd32_jail_get(struct thread *, struct freebsd32_jail_get_args *); int freebsd32_jail_set(struct thread *, struct freebsd32_jail_set_args *); +int freebsd32_semctl(struct thread *, struct freebsd32_semctl_args *); +int freebsd32_msgctl(struct thread *, struct freebsd32_msgctl_args *); +int freebsd32_shmctl(struct thread *, struct freebsd32_shmctl_args *); #ifdef COMPAT_43 @@ -682,6 +682,31 @@ #endif /* COMPAT_FREEBSD6 */ + +#ifdef COMPAT_FREEBSD7 + +struct freebsd7_freebsd32_semctl_args { + char semid_l_[PADL_(int)]; int semid; char semid_r_[PADR_(int)]; + char semnum_l_[PADL_(int)]; int semnum; char semnum_r_[PADR_(int)]; + char cmd_l_[PADL_(int)]; int cmd; char cmd_r_[PADR_(int)]; + char arg_l_[PADL_(union semun32 *)]; union semun32 * arg; char arg_r_[PADR_(union semun32 *)]; +}; +struct freebsd7_freebsd32_msgctl_args { + char msqid_l_[PADL_(int)]; int msqid; char msqid_r_[PADR_(int)]; + char cmd_l_[PADL_(int)]; int cmd; char cmd_r_[PADR_(int)]; + char buf_l_[PADL_(struct msqid_ds32_old *)]; struct msqid_ds32_old * buf; char buf_r_[PADR_(struct msqid_ds32_old *)]; +}; +struct freebsd7_freebsd32_shmctl_args { + char shmid_l_[PADL_(int)]; int shmid; char shmid_r_[PADR_(int)]; + char cmd_l_[PADL_(int)]; int cmd; char cmd_r_[PADR_(int)]; + char buf_l_[PADL_(struct shmid_ds32_old *)]; struct shmid_ds32_old * buf; char buf_r_[PADR_(struct shmid_ds32_old *)]; +}; +int freebsd7_freebsd32_semctl(struct thread *, struct freebsd7_freebsd32_semctl_args *); +int freebsd7_freebsd32_msgctl(struct thread *, struct freebsd7_freebsd32_msgctl_args *); +int freebsd7_freebsd32_shmctl(struct thread *, struct freebsd7_freebsd32_shmctl_args *); + +#endif /* COMPAT_FREEBSD7 */ + #define FREEBSD32_SYS_AUE_freebsd32_wait4 AUE_WAIT4 #define FREEBSD32_SYS_AUE_freebsd4_freebsd32_getfsstat AUE_GETFSSTAT #define FREEBSD32_SYS_AUE_freebsd32_recvmsg AUE_RECVMSG @@ -726,11 +751,11 @@ #define FREEBSD32_SYS_AUE_freebsd6_freebsd32_ftruncate AUE_FTRUNCATE #define FREEBSD32_SYS_AUE_freebsd32_sysctl AUE_SYSCTL #define FREEBSD32_SYS_AUE_freebsd32_futimes AUE_FUTIMES -#define FREEBSD32_SYS_AUE_freebsd32_semctl AUE_SEMCTL -#define FREEBSD32_SYS_AUE_freebsd32_msgctl AUE_MSGCTL +#define FREEBSD32_SYS_AUE_freebsd7_freebsd32_semctl AUE_SEMCTL +#define FREEBSD32_SYS_AUE_freebsd7_freebsd32_msgctl AUE_MSGCTL #define FREEBSD32_SYS_AUE_freebsd32_msgsnd AUE_MSGSND #define FREEBSD32_SYS_AUE_freebsd32_msgrcv AUE_MSGRCV -#define FREEBSD32_SYS_AUE_freebsd32_shmctl AUE_SHMCTL +#define FREEBSD32_SYS_AUE_freebsd7_freebsd32_shmctl AUE_SHMCTL #define FREEBSD32_SYS_AUE_freebsd32_clock_gettime AUE_NULL #define FREEBSD32_SYS_AUE_freebsd32_clock_settime AUE_CLOCK_SETTIME #define FREEBSD32_SYS_AUE_freebsd32_clock_getres AUE_NULL @@ -786,6 +811,9 @@ #define FREEBSD32_SYS_AUE_freebsd32_futimesat AUE_FUTIMESAT #define FREEBSD32_SYS_AUE_freebsd32_jail_get AUE_NULL #define FREEBSD32_SYS_AUE_freebsd32_jail_set AUE_NULL +#define FREEBSD32_SYS_AUE_freebsd32_semctl AUE_SEMCTL +#define FREEBSD32_SYS_AUE_freebsd32_msgctl AUE_MSGCTL +#define FREEBSD32_SYS_AUE_freebsd32_shmctl AUE_SHMCTL #undef PAD_ #undef PADL_ Index: sys/compat/freebsd32/freebsd32_misc.c =================================================================== --- sys/compat/freebsd32/freebsd32_misc.c (revision 194647) +++ sys/compat/freebsd32/freebsd32_misc.c (working copy) @@ -1353,7 +1353,36 @@ } #endif +#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \ + defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7) static void +freebsd32_ipcperm_old_in(struct ipc_perm32_old *ip32, struct ipc_perm *ip) +{ + + CP(*ip32, *ip, cuid); + CP(*ip32, *ip, cgid); + CP(*ip32, *ip, uid); + CP(*ip32, *ip, gid); + CP(*ip32, *ip, mode); + CP(*ip32, *ip, seq); + CP(*ip32, *ip, key); +} + +static void +freebsd32_ipcperm_old_out(struct ipc_perm *ip, struct ipc_perm32_old *ip32) +{ + + CP(*ip, *ip32, cuid); + CP(*ip, *ip32, cgid); + CP(*ip, *ip32, uid); + CP(*ip, *ip32, gid); + CP(*ip, *ip32, mode); + CP(*ip, *ip32, seq); + CP(*ip, *ip32, key); +} +#endif + +static void freebsd32_ipcperm_in(struct ipc_perm32 *ip32, struct ipc_perm *ip) { @@ -1383,6 +1412,8 @@ freebsd32_semsys(struct thread *td, struct freebsd32_semsys_args *uap) { +#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \ + defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7) switch (uap->which) { case 0: return (freebsd32_semctl(td, @@ -1390,9 +1421,87 @@ default: return (semsys(td, (struct semsys_args *)uap)); } +#else + return (nosys(td, NULL)); +#endif } +#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \ + defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7) int +freebsd7_freebsd32_semctl(struct thread *td, + struct freebsd7_freebsd32_semctl_args *uap) +{ + struct semid_ds32_old dsbuf32; + struct semid_ds dsbuf; + union semun semun; + union semun32 arg; + register_t rval; + int error; + + switch (uap->cmd) { + case SEM_STAT: + case IPC_SET: + case IPC_STAT: + case GETALL: + case SETVAL: + case SETALL: + error = copyin(uap->arg, &arg, sizeof(arg)); + if (error) + return (error); + break; + } + + switch (uap->cmd) { + case SEM_STAT: + case IPC_STAT: + semun.buf = &dsbuf; + break; + case IPC_SET: + error = copyin(PTRIN(arg.buf), &dsbuf32, sizeof(dsbuf32)); + if (error) + return (error); + freebsd32_ipcperm_old_in(&dsbuf32.sem_perm, &dsbuf.sem_perm); + PTRIN_CP(dsbuf32, dsbuf, sem_base); + CP(dsbuf32, dsbuf, sem_nsems); + CP(dsbuf32, dsbuf, sem_otime); + CP(dsbuf32, dsbuf, sem_ctime); + semun.buf = &dsbuf; + break; + case GETALL: + case SETALL: + semun.array = PTRIN(arg.array); + break; + case SETVAL: + semun.val = arg.val; + break; + } + + error = kern_semctl(td, uap->semid, uap->semnum, uap->cmd, &semun, + &rval); + if (error) + return (error); + + switch (uap->cmd) { + case SEM_STAT: + case IPC_STAT: + bzero(&dsbuf32, sizeof(dsbuf32)); + freebsd32_ipcperm_old_out(&dsbuf.sem_perm, &dsbuf32.sem_perm); + PTROUT_CP(dsbuf, dsbuf32, sem_base); + CP(dsbuf, dsbuf32, sem_nsems); + CP(dsbuf, dsbuf32, sem_otime); + CP(dsbuf, dsbuf32, sem_ctime); + error = copyout(&dsbuf32, PTRIN(arg.buf), sizeof(dsbuf32)); + break; + } + + if (error == 0) + td->td_retval[0] = rval; + return (error); +} +#endif + +int freebsd32_semctl(struct thread *td, struct freebsd32_semctl_args *uap) { struct semid_ds32 dsbuf32; @@ -1428,13 +1537,7 @@ PTRIN_CP(dsbuf32, dsbuf, sem_base); CP(dsbuf32, dsbuf, sem_nsems); CP(dsbuf32, dsbuf, sem_otime); - CP(dsbuf32, dsbuf, sem_pad1); CP(dsbuf32, dsbuf, sem_ctime); - CP(dsbuf32, dsbuf, sem_pad2); - CP(dsbuf32, dsbuf, sem_pad3[0]); - CP(dsbuf32, dsbuf, sem_pad3[1]); - CP(dsbuf32, dsbuf, sem_pad3[2]); - CP(dsbuf32, dsbuf, sem_pad3[3]); semun.buf = &dsbuf; break; case GETALL: @@ -1454,17 +1557,12 @@ switch (uap->cmd) { case SEM_STAT: case IPC_STAT: + bzero(&dsbuf32, sizeof(dsbuf32)); freebsd32_ipcperm_out(&dsbuf.sem_perm, &dsbuf32.sem_perm); PTROUT_CP(dsbuf, dsbuf32, sem_base); CP(dsbuf, dsbuf32, sem_nsems); CP(dsbuf, dsbuf32, sem_otime); - CP(dsbuf, dsbuf32, sem_pad1); CP(dsbuf, dsbuf32, sem_ctime); - CP(dsbuf, dsbuf32, sem_pad2); - CP(dsbuf, dsbuf32, sem_pad3[0]); - CP(dsbuf, dsbuf32, sem_pad3[1]); - CP(dsbuf, dsbuf32, sem_pad3[2]); - CP(dsbuf, dsbuf32, sem_pad3[3]); error = copyout(&dsbuf32, PTRIN(arg.buf), sizeof(dsbuf32)); break; } @@ -1478,6 +1576,8 @@ freebsd32_msgsys(struct thread *td, struct freebsd32_msgsys_args *uap) { +#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \ + defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7) switch (uap->which) { case 0: return (freebsd32_msgctl(td, @@ -1491,9 +1591,60 @@ default: return (msgsys(td, (struct msgsys_args *)uap)); } +#else + return (nosys(td, NULL)); +#endif } +#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \ + defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7) int +freebsd7_freebsd32_msgctl(struct thread *td, + struct freebsd7_freebsd32_msgctl_args *uap) +{ + struct msqid_ds msqbuf; + struct msqid_ds32_old msqbuf32; + int error; + + if (uap->cmd == IPC_SET) { + error = copyin(uap->buf, &msqbuf32, sizeof(msqbuf32)); + if (error) + return (error); + freebsd32_ipcperm_old_in(&msqbuf32.msg_perm, &msqbuf.msg_perm); + PTRIN_CP(msqbuf32, msqbuf, msg_first); + PTRIN_CP(msqbuf32, msqbuf, msg_last); + CP(msqbuf32, msqbuf, msg_cbytes); + CP(msqbuf32, msqbuf, msg_qnum); + CP(msqbuf32, msqbuf, msg_qbytes); + CP(msqbuf32, msqbuf, msg_lspid); + CP(msqbuf32, msqbuf, msg_lrpid); + CP(msqbuf32, msqbuf, msg_stime); + CP(msqbuf32, msqbuf, msg_rtime); + CP(msqbuf32, msqbuf, msg_ctime); + } + error = kern_msgctl(td, uap->msqid, uap->cmd, &msqbuf); + if (error) + return (error); + if (uap->cmd == IPC_STAT) { + bzero(&msqbuf32, sizeof(msqbuf32)); + freebsd32_ipcperm_old_out(&msqbuf.msg_perm, &msqbuf32.msg_perm); + PTROUT_CP(msqbuf, msqbuf32, msg_first); + PTROUT_CP(msqbuf, msqbuf32, msg_last); + CP(msqbuf, msqbuf32, msg_cbytes); + CP(msqbuf, msqbuf32, msg_qnum); + CP(msqbuf, msqbuf32, msg_qbytes); + CP(msqbuf, msqbuf32, msg_lspid); + CP(msqbuf, msqbuf32, msg_lrpid); + CP(msqbuf, msqbuf32, msg_stime); + CP(msqbuf, msqbuf32, msg_rtime); + CP(msqbuf, msqbuf32, msg_ctime); + error = copyout(&msqbuf32, uap->buf, sizeof(struct msqid_ds32)); + } + return (error); +} +#endif + +int freebsd32_msgctl(struct thread *td, struct freebsd32_msgctl_args *uap) { struct msqid_ds msqbuf; @@ -1513,15 +1664,8 @@ CP(msqbuf32, msqbuf, msg_lspid); CP(msqbuf32, msqbuf, msg_lrpid); CP(msqbuf32, msqbuf, msg_stime); - CP(msqbuf32, msqbuf, msg_pad1); CP(msqbuf32, msqbuf, msg_rtime); - CP(msqbuf32, msqbuf, msg_pad2); CP(msqbuf32, msqbuf, msg_ctime); - CP(msqbuf32, msqbuf, msg_pad3); - CP(msqbuf32, msqbuf, msg_pad4[0]); - CP(msqbuf32, msqbuf, msg_pad4[1]); - CP(msqbuf32, msqbuf, msg_pad4[2]); - CP(msqbuf32, msqbuf, msg_pad4[3]); } error = kern_msgctl(td, uap->msqid, uap->cmd, &msqbuf); if (error) @@ -1536,15 +1680,8 @@ CP(msqbuf, msqbuf32, msg_lspid); CP(msqbuf, msqbuf32, msg_lrpid); CP(msqbuf, msqbuf32, msg_stime); - CP(msqbuf, msqbuf32, msg_pad1); CP(msqbuf, msqbuf32, msg_rtime); - CP(msqbuf, msqbuf32, msg_pad2); CP(msqbuf, msqbuf32, msg_ctime); - CP(msqbuf, msqbuf32, msg_pad3); - CP(msqbuf, msqbuf32, msg_pad4[0]); - CP(msqbuf, msqbuf32, msg_pad4[1]); - CP(msqbuf, msqbuf32, msg_pad4[2]); - CP(msqbuf, msqbuf32, msg_pad4[3]); error = copyout(&msqbuf32, uap->buf, sizeof(struct msqid_ds32)); } return (error); @@ -1588,6 +1725,8 @@ freebsd32_shmsys(struct thread *td, struct freebsd32_shmsys_args *uap) { +#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \ + defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7) switch (uap->which) { case 0: { /* shmat */ struct shmat_args ap; @@ -1623,9 +1762,100 @@ default: return (EINVAL); } +#else + return (nosys(td, NULL)); +#endif } +#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \ + defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7) int +freebsd7_freebsd32_shmctl(struct thread *td, + struct freebsd7_freebsd32_shmctl_args *uap) +{ + int error = 0; + union { + struct shmid_ds shmid_ds; + struct shm_info shm_info; + struct shminfo shminfo; + } u; + union { + struct shmid_ds32_old shmid_ds32; + struct shm_info32 shm_info32; + struct shminfo32 shminfo32; + } u32; + size_t sz; + + if (uap->cmd == IPC_SET) { + if ((error = copyin(uap->buf, &u32.shmid_ds32, + sizeof(u32.shmid_ds32)))) + goto done; + freebsd32_ipcperm_old_in(&u32.shmid_ds32.shm_perm, + &u.shmid_ds.shm_perm); + CP(u32.shmid_ds32, u.shmid_ds, shm_segsz); + CP(u32.shmid_ds32, u.shmid_ds, shm_lpid); + CP(u32.shmid_ds32, u.shmid_ds, shm_cpid); + CP(u32.shmid_ds32, u.shmid_ds, shm_nattch); + CP(u32.shmid_ds32, u.shmid_ds, shm_atime); + CP(u32.shmid_ds32, u.shmid_ds, shm_dtime); + CP(u32.shmid_ds32, u.shmid_ds, shm_ctime); + } + + error = kern_shmctl(td, uap->shmid, uap->cmd, (void *)&u, &sz); + if (error) + goto done; + + /* Cases in which we need to copyout */ + switch (uap->cmd) { + case IPC_INFO: + CP(u.shminfo, u32.shminfo32, shmmax); + CP(u.shminfo, u32.shminfo32, shmmin); + CP(u.shminfo, u32.shminfo32, shmmni); + CP(u.shminfo, u32.shminfo32, shmseg); + CP(u.shminfo, u32.shminfo32, shmall); + error = copyout(&u32.shminfo32, uap->buf, + sizeof(u32.shminfo32)); + break; + case SHM_INFO: + CP(u.shm_info, u32.shm_info32, used_ids); + CP(u.shm_info, u32.shm_info32, shm_rss); + CP(u.shm_info, u32.shm_info32, shm_tot); + CP(u.shm_info, u32.shm_info32, shm_swp); + CP(u.shm_info, u32.shm_info32, swap_attempts); + CP(u.shm_info, u32.shm_info32, swap_successes); + error = copyout(&u32.shm_info32, uap->buf, + sizeof(u32.shm_info32)); + break; + case SHM_STAT: + case IPC_STAT: + freebsd32_ipcperm_old_out(&u.shmid_ds.shm_perm, + &u32.shmid_ds32.shm_perm); + if (u.shmid_ds.shm_segsz > INT32_MAX) + u32.shmid_ds32.shm_segsz = INT32_MAX; + else + CP(u.shmid_ds, u32.shmid_ds32, shm_segsz); + CP(u.shmid_ds, u32.shmid_ds32, shm_lpid); + CP(u.shmid_ds, u32.shmid_ds32, shm_cpid); + CP(u.shmid_ds, u32.shmid_ds32, shm_nattch); + CP(u.shmid_ds, u32.shmid_ds32, shm_atime); + CP(u.shmid_ds, u32.shmid_ds32, shm_dtime); + CP(u.shmid_ds, u32.shmid_ds32, shm_ctime); + u32.shmid_ds32.shm_internal = 0; + error = copyout(&u32.shmid_ds32, uap->buf, + sizeof(u32.shmid_ds32)); + break; + } + +done: + if (error) { + /* Invalidate the return value */ + td->td_retval[0] = -1; + } + return (error); +} +#endif + +int freebsd32_shmctl(struct thread *td, struct freebsd32_shmctl_args *uap) { int error = 0; @@ -1654,7 +1884,6 @@ CP(u32.shmid_ds32, u.shmid_ds, shm_atime); CP(u32.shmid_ds32, u.shmid_ds, shm_dtime); CP(u32.shmid_ds32, u.shmid_ds, shm_ctime); - PTRIN_CP(u32.shmid_ds32, u.shmid_ds, shm_internal); } error = kern_shmctl(td, uap->shmid, uap->cmd, (void *)&u, &sz); @@ -1686,14 +1915,16 @@ case IPC_STAT: freebsd32_ipcperm_out(&u.shmid_ds.shm_perm, &u32.shmid_ds32.shm_perm); - CP(u.shmid_ds, u32.shmid_ds32, shm_segsz); + if (u.shmid_ds.shm_segsz > INT32_MAX) + u32.shmid_ds32.shm_segsz = INT32_MAX; + else + CP(u.shmid_ds, u32.shmid_ds32, shm_segsz); CP(u.shmid_ds, u32.shmid_ds32, shm_lpid); CP(u.shmid_ds, u32.shmid_ds32, shm_cpid); CP(u.shmid_ds, u32.shmid_ds32, shm_nattch); CP(u.shmid_ds, u32.shmid_ds32, shm_atime); CP(u.shmid_ds, u32.shmid_ds32, shm_dtime); CP(u.shmid_ds, u32.shmid_ds32, shm_ctime); - PTROUT_CP(u.shmid_ds, u32.shmid_ds32, shm_internal); error = copyout(&u32.shmid_ds32, uap->buf, sizeof(u32.shmid_ds32)); break; Index: sys/compat/freebsd32/freebsd32_syscalls.c =================================================================== --- sys/compat/freebsd32/freebsd32_syscalls.c (revision 194647) +++ sys/compat/freebsd32/freebsd32_syscalls.c (working copy) @@ -227,16 +227,16 @@ "lkmnosys", /* 217 = lkmnosys */ "lkmnosys", /* 218 = lkmnosys */ "lkmnosys", /* 219 = lkmnosys */ - "freebsd32_semctl", /* 220 = freebsd32_semctl */ + "compat7.freebsd32_semctl", /* 220 = freebsd7 freebsd32_semctl */ "semget", /* 221 = semget */ "semop", /* 222 = semop */ "#223", /* 223 = semconfig */ - "freebsd32_msgctl", /* 224 = freebsd32_msgctl */ + "compat7.freebsd32_msgctl", /* 224 = freebsd7 freebsd32_msgctl */ "msgget", /* 225 = msgget */ "freebsd32_msgsnd", /* 226 = freebsd32_msgsnd */ "freebsd32_msgrcv", /* 227 = freebsd32_msgrcv */ "shmat", /* 228 = shmat */ - "freebsd32_shmctl", /* 229 = freebsd32_shmctl */ + "compat7.freebsd32_shmctl", /* 229 = freebsd7 freebsd32_shmctl */ "shmdt", /* 230 = shmdt */ "shmget", /* 231 = shmget */ "freebsd32_clock_gettime", /* 232 = freebsd32_clock_gettime */ @@ -517,4 +517,7 @@ "freebsd32_jail_set", /* 507 = freebsd32_jail_set */ "jail_remove", /* 508 = jail_remove */ "closefrom", /* 509 = closefrom */ + "freebsd32_semctl", /* 510 = freebsd32_semctl */ + "freebsd32_msgctl", /* 511 = freebsd32_msgctl */ + "freebsd32_shmctl", /* 512 = freebsd32_shmctl */ }; Index: sys/compat/linux/linux_ipc.c =================================================================== --- sys/compat/linux/linux_ipc.c (revision 194647) +++ sys/compat/linux/linux_ipc.c (working copy) @@ -230,23 +230,26 @@ bsp->shm_atime = lsp->shm_atime; bsp->shm_dtime = lsp->shm_dtime; bsp->shm_ctime = lsp->shm_ctime; - /* this goes (yet) SOS */ - bsp->shm_internal = PTRIN(lsp->private3); } static void bsd_to_linux_shmid_ds(struct shmid_ds *bsp, struct l_shmid_ds *lsp) { bsd_to_linux_ipc_perm(&bsp->shm_perm, &lsp->shm_perm); - lsp->shm_segsz = bsp->shm_segsz; + if (bsp->shm_segsz > INT_MAX) + lsp->shm_segsz = INT_MAX; + else + lsp->shm_segsz = bsp->shm_segsz; lsp->shm_lpid = bsp->shm_lpid; lsp->shm_cpid = bsp->shm_cpid; - lsp->shm_nattch = bsp->shm_nattch; + if (bsp->shm_nattch > SHRT_MAX) + lsp->shm_nattch = SHRT_MAX; + else + lsp->shm_nattch = bsp->shm_nattch; lsp->shm_atime = bsp->shm_atime; lsp->shm_dtime = bsp->shm_dtime; lsp->shm_ctime = bsp->shm_ctime; - /* this goes (yet) SOS */ - lsp->private3 = PTROUT(bsp->shm_internal); + lsp->private3 = 0; } static void @@ -424,6 +427,15 @@ { struct l_shmid64_ds linux_shmid64; + /* + * XXX: This is backwards and loses information in shm_nattch + * and shm_segsz. We should probably either expose the BSD + * shmid structure directly and convert it to either the + * non-64 or 64 variant directly or the code should always + * convert to the 64 variant and then truncate values into the + * non-64 variant if needed since the 64 variant has more + * precision. + */ if (ver == LINUX_IPC_64) { bzero(&linux_shmid64, sizeof(linux_shmid64)); Index: sys/compat/svr4/svr4_ipc.c =================================================================== --- sys/compat/svr4/svr4_ipc.c (revision 194647) +++ sys/compat/svr4/svr4_ipc.c (working copy) @@ -169,13 +169,12 @@ const struct semid_ds *bds; struct svr4_semid_ds *sds; { + bzero(sds, sizeof(*sds)); bsd_to_svr4_ipc_perm(&bds->sem_perm, &sds->sem_perm); sds->sem_base = (struct svr4_sem *) bds->sem_base; sds->sem_nsems = bds->sem_nsems; sds->sem_otime = bds->sem_otime; - sds->sem_pad1 = bds->sem_pad1; sds->sem_ctime = bds->sem_ctime; - sds->sem_pad2 = bds->sem_pad2; } static void @@ -187,9 +186,7 @@ bds->sem_base = (struct sem *) bds->sem_base; bds->sem_nsems = sds->sem_nsems; bds->sem_otime = sds->sem_otime; - bds->sem_pad1 = sds->sem_pad1; bds->sem_ctime = sds->sem_ctime; - bds->sem_pad2 = sds->sem_pad2; } struct svr4_sys_semctl_args { @@ -350,6 +347,7 @@ const struct msqid_ds *bds; struct svr4_msqid_ds *sds; { + bzero(sds, sizeof(*sds)); bsd_to_svr4_ipc_perm(&bds->msg_perm, &sds->msg_perm); sds->msg_first = (struct svr4_msg *) bds->msg_first; sds->msg_last = (struct svr4_msg *) bds->msg_last; @@ -359,18 +357,8 @@ sds->msg_lspid = bds->msg_lspid; sds->msg_lrpid = bds->msg_lrpid; sds->msg_stime = bds->msg_stime; - sds->msg_pad1 = bds->msg_pad1; sds->msg_rtime = bds->msg_rtime; - sds->msg_pad2 = bds->msg_pad2; sds->msg_ctime = bds->msg_ctime; - sds->msg_pad3 = bds->msg_pad3; - - /* use the padding for the rest of the fields */ - { - const short *pad = (const short *) bds->msg_pad4; - sds->msg_cv = pad[0]; - sds->msg_qnum_cv = pad[1]; - } } static void @@ -387,18 +375,8 @@ bds->msg_lspid = sds->msg_lspid; bds->msg_lrpid = sds->msg_lrpid; bds->msg_stime = sds->msg_stime; - bds->msg_pad1 = sds->msg_pad1; bds->msg_rtime = sds->msg_rtime; - bds->msg_pad2 = sds->msg_pad2; bds->msg_ctime = sds->msg_ctime; - bds->msg_pad3 = sds->msg_pad3; - - /* use the padding for the rest of the fields */ - { - short *pad = (short *) bds->msg_pad4; - pad[0] = sds->msg_cv; - pad[1] = sds->msg_qnum_cv; - } } struct svr4_sys_msgsnd_args { @@ -543,20 +521,18 @@ const struct shmid_ds *bds; struct svr4_shmid_ds *sds; { + bzero(sds, sizeof(*sds)); bsd_to_svr4_ipc_perm(&bds->shm_perm, &sds->shm_perm); sds->shm_segsz = bds->shm_segsz; sds->shm_lkcnt = 0; sds->shm_lpid = bds->shm_lpid; sds->shm_cpid = bds->shm_cpid; - sds->shm_amp = bds->shm_internal; + sds->shm_amp = 0; sds->shm_nattch = bds->shm_nattch; sds->shm_cnattch = 0; sds->shm_atime = bds->shm_atime; - sds->shm_pad1 = 0; sds->shm_dtime = bds->shm_dtime; - sds->shm_pad2 = 0; sds->shm_ctime = bds->shm_ctime; - sds->shm_pad3 = 0; } static void @@ -568,7 +544,6 @@ bds->shm_segsz = sds->shm_segsz; bds->shm_lpid = sds->shm_lpid; bds->shm_cpid = sds->shm_cpid; - bds->shm_internal = sds->shm_amp; bds->shm_nattch = sds->shm_nattch; bds->shm_atime = sds->shm_atime; bds->shm_dtime = sds->shm_dtime; Index: sys/i386/ibcs2/ibcs2_ipc.c =================================================================== --- sys/i386/ibcs2/ibcs2_ipc.c (revision 194647) +++ sys/i386/ibcs2/ibcs2_ipc.c (working copy) @@ -415,7 +415,10 @@ ibp->shm_segsz = bp->shm_segsz; ibp->shm_lpid = bp->shm_lpid; ibp->shm_cpid = bp->shm_cpid; - ibp->shm_nattch = bp->shm_nattch; + if (bp->shm_nattch > SHRT_MAX) + ibp->shm_nattch = SHRT_MAX; + else + ibp->shm_nattch = bp->shm_nattch; ibp->shm_cnattch = 0; /* ignored anyway */ ibp->shm_atime = bp->shm_atime; ibp->shm_dtime = bp->shm_dtime; @@ -436,7 +439,6 @@ bp->shm_atime = ibp->shm_atime; bp->shm_dtime = ibp->shm_dtime; bp->shm_ctime = ibp->shm_ctime; - bp->shm_internal = (void *)0; /* ignored anyway */ return; } Index: sys/sys/sem.h =================================================================== --- sys/sys/sem.h (revision 194647) +++ sys/sys/sem.h (working copy) @@ -27,8 +27,10 @@ #define _TIME_T_DECLARED #endif -struct semid_ds { - struct ipc_perm sem_perm; /* operation permission struct */ +#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \ + defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7) +struct semid_ds_old { + struct ipc_perm_old sem_perm; /* operation permission struct */ struct sem *sem_base; /* pointer to first semaphore in set */ unsigned short sem_nsems; /* number of sems in set */ time_t sem_otime; /* last operation time */ @@ -39,7 +41,18 @@ long sem_pad2; /* SVABI/386 says I need this here */ long sem_pad3[4]; /* SVABI/386 says I need this here */ }; +#endif +struct semid_ds { + struct ipc_perm sem_perm; /* operation permission struct */ + struct sem *sem_base; /* pointer to first semaphore in set */ + unsigned short sem_nsems; /* number of sems in set */ + time_t sem_otime; /* last operation time */ + time_t sem_ctime; /* last change time */ + /* Times measured in secs since */ + /* 00:00:00 GMT, Jan. 1, 1970 */ +}; + /* * semop's sops parameter structure */ @@ -50,6 +63,16 @@ }; #define SEM_UNDO 010000 +#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \ + defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7) || \ + defined(_WANT_SEMUN_OLD) +union semun_old { + int val; /* value for SETVAL */ + struct semid_ds_old *buf; /* buffer for IPC_STAT & IPC_SET */ + unsigned short *array; /* array for GETALL & SETALL */ +}; +#endif + /* * semctl's arg parameter structure */ Index: sys/sys/syscall.h =================================================================== --- sys/sys/syscall.h (revision 194647) +++ sys/sys/syscall.h (working copy) @@ -196,15 +196,15 @@ #define SYS_futimes 206 #define SYS_getpgid 207 #define SYS_poll 209 -#define SYS___semctl 220 +#define SYS_freebsd7___semctl 220 #define SYS_semget 221 #define SYS_semop 222 -#define SYS_msgctl 224 +#define SYS_freebsd7_msgctl 224 #define SYS_msgget 225 #define SYS_msgsnd 226 #define SYS_msgrcv 227 #define SYS_shmat 228 -#define SYS_shmctl 229 +#define SYS_freebsd7_shmctl 229 #define SYS_shmdt 230 #define SYS_shmget 231 #define SYS_clock_gettime 232 @@ -424,4 +424,7 @@ #define SYS_jail_set 507 #define SYS_jail_remove 508 #define SYS_closefrom 509 -#define SYS_MAXSYSCALL 510 +#define SYS___semctl 510 +#define SYS_msgctl 511 +#define SYS_shmctl 512 +#define SYS_MAXSYSCALL 513 Index: sys/sys/ipc.h =================================================================== --- sys/sys/ipc.h (revision 194647) +++ sys/sys/ipc.h (working copy) @@ -69,10 +69,9 @@ #define _UID_T_DECLARED #endif -/* - * XXX almost all members have wrong types. - */ -struct ipc_perm { +#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \ + defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7) +struct ipc_perm_old { unsigned short cuid; /* creator user id */ unsigned short cgid; /* creator group id */ unsigned short uid; /* user id */ @@ -81,7 +80,18 @@ unsigned short seq; /* sequence # (to generate unique ipcid) */ key_t key; /* user specified msg/sem/shm key */ }; +#endif +struct ipc_perm { + uid_t cuid; /* creator user id */ + gid_t cgid; /* creator group id */ + uid_t uid; /* user id */ + gid_t gid; /* group id */ + mode_t mode; /* r/w permission */ + unsigned short seq; /* sequence # (to generate unique ipcid) */ + key_t key; /* user specified msg/sem/shm key */ +}; + #if __BSD_VISIBLE /* common mode bits */ #define IPC_R 000400 /* read permission */ @@ -116,6 +126,12 @@ struct proc; struct vmspace; +#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \ + defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7) +void ipcperm_old2new(struct ipc_perm_old *, struct ipc_perm *); +void ipcperm_new2old(struct ipc_perm *, struct ipc_perm_old *); +#endif + int ipcperm(struct thread *, struct ipc_perm *, int); extern void (*shmfork_hook)(struct proc *, struct proc *); extern void (*shmexit_hook)(struct vmspace *); Index: sys/sys/sysproto.h =================================================================== --- sys/sys/sysproto.h (revision 194647) +++ sys/sys/sysproto.h (working copy) @@ -649,12 +649,6 @@ char nfds_l_[PADL_(u_int)]; u_int nfds; char nfds_r_[PADR_(u_int)]; char timeout_l_[PADL_(int)]; int timeout; char timeout_r_[PADR_(int)]; }; -struct __semctl_args { - char semid_l_[PADL_(int)]; int semid; char semid_r_[PADR_(int)]; - char semnum_l_[PADL_(int)]; int semnum; char semnum_r_[PADR_(int)]; - char cmd_l_[PADL_(int)]; int cmd; char cmd_r_[PADR_(int)]; - char arg_l_[PADL_(union semun *)]; union semun * arg; char arg_r_[PADR_(union semun *)]; -}; struct semget_args { char key_l_[PADL_(key_t)]; key_t key; char key_r_[PADR_(key_t)]; char nsems_l_[PADL_(int)]; int nsems; char nsems_r_[PADR_(int)]; @@ -665,11 +659,6 @@ char sops_l_[PADL_(struct sembuf *)]; struct sembuf * sops; char sops_r_[PADR_(struct sembuf *)]; char nsops_l_[PADL_(size_t)]; size_t nsops; char nsops_r_[PADR_(size_t)]; }; -struct msgctl_args { - char msqid_l_[PADL_(int)]; int msqid; char msqid_r_[PADR_(int)]; - char cmd_l_[PADL_(int)]; int cmd; char cmd_r_[PADR_(int)]; - char buf_l_[PADL_(struct msqid_ds *)]; struct msqid_ds * buf; char buf_r_[PADR_(struct msqid_ds *)]; -}; struct msgget_args { char key_l_[PADL_(key_t)]; key_t key; char key_r_[PADR_(key_t)]; char msgflg_l_[PADL_(int)]; int msgflg; char msgflg_r_[PADR_(int)]; @@ -692,11 +681,6 @@ char shmaddr_l_[PADL_(const void *)]; const void * shmaddr; char shmaddr_r_[PADR_(const void *)]; char shmflg_l_[PADL_(int)]; int shmflg; char shmflg_r_[PADR_(int)]; }; -struct shmctl_args { - char shmid_l_[PADL_(int)]; int shmid; char shmid_r_[PADR_(int)]; - char cmd_l_[PADL_(int)]; int cmd; char cmd_r_[PADR_(int)]; - char buf_l_[PADL_(struct shmid_ds *)]; struct shmid_ds * buf; char buf_r_[PADR_(struct shmid_ds *)]; -}; struct shmdt_args { char shmaddr_l_[PADL_(const void *)]; const void * shmaddr; char shmaddr_r_[PADR_(const void *)]; }; @@ -1637,6 +1621,22 @@ struct closefrom_args { char lowfd_l_[PADL_(int)]; int lowfd; char lowfd_r_[PADR_(int)]; }; +struct __semctl_args { + char semid_l_[PADL_(int)]; int semid; char semid_r_[PADR_(int)]; + char semnum_l_[PADL_(int)]; int semnum; char semnum_r_[PADR_(int)]; + char cmd_l_[PADL_(int)]; int cmd; char cmd_r_[PADR_(int)]; + char arg_l_[PADL_(union semun *)]; union semun * arg; char arg_r_[PADR_(union semun *)]; +}; +struct msgctl_args { + char msqid_l_[PADL_(int)]; int msqid; char msqid_r_[PADR_(int)]; + char cmd_l_[PADL_(int)]; int cmd; char cmd_r_[PADR_(int)]; + char buf_l_[PADL_(struct msqid_ds *)]; struct msqid_ds * buf; char buf_r_[PADR_(struct msqid_ds *)]; +}; +struct shmctl_args { + char shmid_l_[PADL_(int)]; int shmid; char shmid_r_[PADR_(int)]; + char cmd_l_[PADL_(int)]; int cmd; char cmd_r_[PADR_(int)]; + char buf_l_[PADL_(struct shmid_ds *)]; struct shmid_ds * buf; char buf_r_[PADR_(struct shmid_ds *)]; +}; int nosys(struct thread *, struct nosys_args *); void sys_exit(struct thread *, struct sys_exit_args *); int fork(struct thread *, struct fork_args *); @@ -1775,15 +1775,12 @@ int futimes(struct thread *, struct futimes_args *); int getpgid(struct thread *, struct getpgid_args *); int poll(struct thread *, struct poll_args *); -int __semctl(struct thread *, struct __semctl_args *); int semget(struct thread *, struct semget_args *); int semop(struct thread *, struct semop_args *); -int msgctl(struct thread *, struct msgctl_args *); int msgget(struct thread *, struct msgget_args *); int msgsnd(struct thread *, struct msgsnd_args *); int msgrcv(struct thread *, struct msgrcv_args *); int shmat(struct thread *, struct shmat_args *); -int shmctl(struct thread *, struct shmctl_args *); int shmdt(struct thread *, struct shmdt_args *); int shmget(struct thread *, struct shmget_args *); int clock_gettime(struct thread *, struct clock_gettime_args *); @@ -1994,6 +1991,9 @@ int jail_set(struct thread *, struct jail_set_args *); int jail_remove(struct thread *, struct jail_remove_args *); int closefrom(struct thread *, struct closefrom_args *); +int __semctl(struct thread *, struct __semctl_args *); +int msgctl(struct thread *, struct msgctl_args *); +int shmctl(struct thread *, struct shmctl_args *); #ifdef COMPAT_43 @@ -2233,6 +2233,31 @@ #endif /* COMPAT_FREEBSD6 */ + +#ifdef COMPAT_FREEBSD7 + +struct freebsd7___semctl_args { + char semid_l_[PADL_(int)]; int semid; char semid_r_[PADR_(int)]; + char semnum_l_[PADL_(int)]; int semnum; char semnum_r_[PADR_(int)]; + char cmd_l_[PADL_(int)]; int cmd; char cmd_r_[PADR_(int)]; + char arg_l_[PADL_(union semun_old *)]; union semun_old * arg; char arg_r_[PADR_(union semun_old *)]; +}; +struct freebsd7_msgctl_args { + char msqid_l_[PADL_(int)]; int msqid; char msqid_r_[PADR_(int)]; + char cmd_l_[PADL_(int)]; int cmd; char cmd_r_[PADR_(int)]; + char buf_l_[PADL_(struct msqid_ds_old *)]; struct msqid_ds_old * buf; char buf_r_[PADR_(struct msqid_ds_old *)]; +}; +struct freebsd7_shmctl_args { + char shmid_l_[PADL_(int)]; int shmid; char shmid_r_[PADR_(int)]; + char cmd_l_[PADL_(int)]; int cmd; char cmd_r_[PADR_(int)]; + char buf_l_[PADL_(struct shmid_ds_old *)]; struct shmid_ds_old * buf; char buf_r_[PADR_(struct shmid_ds_old *)]; +}; +int freebsd7___semctl(struct thread *, struct freebsd7___semctl_args *); +int freebsd7_msgctl(struct thread *, struct freebsd7_msgctl_args *); +int freebsd7_shmctl(struct thread *, struct freebsd7_shmctl_args *); + +#endif /* COMPAT_FREEBSD7 */ + #define SYS_AUE_syscall AUE_NULL #define SYS_AUE_exit AUE_EXIT #define SYS_AUE_fork AUE_FORK @@ -2414,15 +2439,15 @@ #define SYS_AUE_futimes AUE_FUTIMES #define SYS_AUE_getpgid AUE_GETPGID #define SYS_AUE_poll AUE_POLL -#define SYS_AUE___semctl AUE_SEMCTL +#define SYS_AUE_freebsd7___semctl AUE_SEMCTL #define SYS_AUE_semget AUE_SEMGET #define SYS_AUE_semop AUE_SEMOP -#define SYS_AUE_msgctl AUE_MSGCTL +#define SYS_AUE_freebsd7_msgctl AUE_MSGCTL #define SYS_AUE_msgget AUE_MSGGET #define SYS_AUE_msgsnd AUE_MSGSND #define SYS_AUE_msgrcv AUE_MSGRCV #define SYS_AUE_shmat AUE_SHMAT -#define SYS_AUE_shmctl AUE_SHMCTL +#define SYS_AUE_freebsd7_shmctl AUE_SHMCTL #define SYS_AUE_shmdt AUE_SHMDT #define SYS_AUE_shmget AUE_SHMGET #define SYS_AUE_clock_gettime AUE_NULL @@ -2637,6 +2662,9 @@ #define SYS_AUE_jail_set AUE_NULL #define SYS_AUE_jail_remove AUE_NULL #define SYS_AUE_closefrom AUE_CLOSEFROM +#define SYS_AUE___semctl AUE_SEMCTL +#define SYS_AUE_msgctl AUE_MSGCTL +#define SYS_AUE_shmctl AUE_SHMCTL #undef PAD_ #undef PADL_ Index: sys/sys/msg.h =================================================================== --- sys/sys/msg.h (revision 194647) +++ sys/sys/msg.h (working copy) @@ -57,6 +57,27 @@ #define _TIME_T_DECLARED #endif +#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \ + defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7) +struct msqid_ds_old { + struct ipc_perm_old msg_perm; /* msg queue permission bits */ + struct msg *msg_first; /* first message in the queue */ + struct msg *msg_last; /* last message in the queue */ + msglen_t msg_cbytes; /* number of bytes in use on the queue */ + msgqnum_t msg_qnum; /* number of msgs in the queue */ + msglen_t msg_qbytes; /* max # of bytes on the queue */ + pid_t msg_lspid; /* pid of last msgsnd() */ + pid_t msg_lrpid; /* pid of last msgrcv() */ + time_t msg_stime; /* time of last msgsnd() */ + long msg_pad1; + time_t msg_rtime; /* time of last msgrcv() */ + long msg_pad2; + time_t msg_ctime; /* time of last msgctl() */ + long msg_pad3; + long msg_pad4[4]; +}; +#endif + /* * XXX there seems to be no prefix reserved for this header, so the name * "msg" in "struct msg" and the names of all of the nonstandard members @@ -73,12 +94,8 @@ pid_t msg_lspid; /* pid of last msgsnd() */ pid_t msg_lrpid; /* pid of last msgrcv() */ time_t msg_stime; /* time of last msgsnd() */ - long msg_pad1; time_t msg_rtime; /* time of last msgrcv() */ - long msg_pad2; time_t msg_ctime; /* time of last msgctl() */ - long msg_pad3; - long msg_pad4[4]; }; #if __BSD_VISIBLE Index: sys/sys/shm.h =================================================================== --- sys/sys/shm.h (revision 194647) +++ sys/sys/shm.h (working copy) @@ -75,8 +75,10 @@ #define _SIZE_T_DECLARED #endif -struct shmid_ds { - struct ipc_perm shm_perm; /* operation permission structure */ +#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \ + defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7) +struct shmid_ds_old { + struct ipc_perm_old shm_perm; /* operation permission structure */ int shm_segsz; /* size of segment in bytes */ pid_t shm_lpid; /* process ID of last shared memory op */ pid_t shm_cpid; /* process ID of creator */ @@ -86,8 +88,21 @@ time_t shm_ctime; /* time of last change by shmctl() */ void *shm_internal; /* sysv stupidity */ }; +#endif +struct shmid_ds { + struct ipc_perm shm_perm; /* operation permission structure */ + size_t shm_segsz; /* size of segment in bytes */ + pid_t shm_lpid; /* process ID of last shared memory op */ + pid_t shm_cpid; /* process ID of creator */ + int shm_nattch; /* number of current attaches */ + time_t shm_atime; /* time of last shmat() */ + time_t shm_dtime; /* time of last shmdt() */ + time_t shm_ctime; /* time of last change by shmctl() */ +}; + #ifdef _KERNEL +#include /* * System 5 style catch-all structure for shared memory constants that @@ -107,8 +122,8 @@ */ struct shmid_kernel { struct shmid_ds u; + vm_object_t object; struct label *label; /* MAC label */ - size_t shm_bsegsz; }; extern struct shminfo shminfo; Index: sys/sys/syscall.mk =================================================================== --- sys/sys/syscall.mk (revision 194647) +++ sys/sys/syscall.mk (working copy) @@ -148,15 +148,15 @@ futimes.o \ getpgid.o \ poll.o \ - __semctl.o \ + freebsd7___semctl.o \ semget.o \ semop.o \ - msgctl.o \ + freebsd7_msgctl.o \ msgget.o \ msgsnd.o \ msgrcv.o \ shmat.o \ - shmctl.o \ + freebsd7_shmctl.o \ shmdt.o \ shmget.o \ clock_gettime.o \ @@ -372,4 +372,7 @@ jail_get.o \ jail_set.o \ jail_remove.o \ - closefrom.o + closefrom.o \ + __semctl.o \ + msgctl.o \ + shmctl.o Index: lib/libc/gen/Symbol.map =================================================================== --- lib/libc/gen/Symbol.map (revision 194642) +++ lib/libc/gen/Symbol.map (working copy) @@ -247,7 +247,6 @@ sem_timedwait; sem_post; sem_getvalue; - semctl; setdomainname; sethostname; longjmperror; @@ -362,6 +361,7 @@ posix_spawnattr_setsigdefault; posix_spawnattr_setsigmask; posix_spawnp; + semctl; tcgetsid; tcsetsid; }; Index: lib/libc/gen/semctl.c =================================================================== --- lib/libc/gen/semctl.c (revision 194642) +++ lib/libc/gen/semctl.c (working copy) @@ -29,15 +29,19 @@ #include __FBSDID("$FreeBSD$"); +#define _WANT_SEMUN_OLD + #include #include #include #include #include -extern int __semctl(int semid, int semnum, int cmd, union semun *arg); +int __semctl(int semid, int semnum, int cmd, union semun *arg); +int freebsd7___semctl(int semid, int semnum, int cmd, union semun_old *arg); -int semctl(int semid, int semnum, int cmd, ...) +int +semctl(int semid, int semnum, int cmd, ...) { va_list ap; union semun semun; @@ -55,3 +59,25 @@ return (__semctl(semid, semnum, cmd, semun_ptr)); } + +int +freebsd7_semctl(int semid, int semnum, int cmd, ...) +{ + va_list ap; + union semun_old semun; + union semun_old *semun_ptr; + + va_start(ap, cmd); + if (cmd == IPC_SET || cmd == IPC_STAT || cmd == GETALL + || cmd == SETVAL || cmd == SETALL) { + semun = va_arg(ap, union semun_old); + semun_ptr = &semun; + } else { + semun_ptr = NULL; + } + va_end(ap); + + return (freebsd7___semctl(semid, semnum, cmd, semun_ptr)); +} + +__sym_compat(semctl, freebsd7_semctl, FBSD_1.0); Index: lib/libc/include/compat.h =================================================================== --- lib/libc/include/compat.h (revision 0) +++ lib/libc/include/compat.h (revision 0) @@ -0,0 +1,48 @@ +/*- + * Copyright (c) 2009 Advanced Computing Technologies LLC + * Written by: John H. Baldwin + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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. + * + * $FreeBSD$ + */ + +/* + * This file defines compatiblity symbol versions for old system calls. It + * is included in all generated system call files. + */ + +#ifndef __LIBC_COMPAT_H__ +#define __LIBC_COMPAT_H__ + +#define __sym_compat(sym,impl,verid) \ + .symver impl , sym @ verid + +__sym_compat(__semctl, freebsd7___semctl, FBSD_1.0); +__sym_compat(msgctl, freebsd7_msgctl, FBSD_1.0); +__sym_compat(shmctl, freebsd7_shmctl, FBSD_1.0); + +#undef __sym_compat + +#endif /* __LIBC_COMPAT_H__ */ + Property changes on: lib/libc/include/compat.h ___________________________________________________________________ Added: svn:mime-type + text/plain Added: svn:keywords + FreeBSD=%H Added: svn:eol-style + native Index: lib/libc/sys/Symbol.map =================================================================== --- lib/libc/sys/Symbol.map (revision 194642) +++ lib/libc/sys/Symbol.map (working copy) @@ -31,7 +31,6 @@ __mac_set_file; __mac_set_link; __mac_set_proc; - __semctl; __setugid; __syscall; __sysctl; @@ -184,7 +183,6 @@ modstat; mount; mprotect; - msgctl; msgget; msgrcv; msgsnd; @@ -267,7 +265,6 @@ shm_open; shm_unlink; shmat; - shmctl; shmdt; shmget; shmsys; @@ -332,6 +329,7 @@ }; FBSD_1.1 { + __semctl; closefrom; cpuset; cpuset_getid; @@ -351,10 +349,12 @@ mkdirat; mkfifoat; mknodat; + msgctl; openat; readlinkat; renameat; setfib; + shmctl; symlinkat; unlinkat; }; Index: lib/libc/sys/Makefile.inc =================================================================== --- lib/libc/sys/Makefile.inc (revision 194642) +++ lib/libc/sys/Makefile.inc (working copy) @@ -53,11 +53,13 @@ CLEANFILES+= ${SASM} ${SPSEUDO} ${SASM}: - printf '#include "SYS.h"\nRSYSCALL(${.PREFIX})\n' > ${.TARGET} + printf '#include "compat.h"\n' > ${.TARGET} + printf '#include "SYS.h"\nRSYSCALL(${.PREFIX})\n' >> ${.TARGET} ${SPSEUDO}: + printf '#include "compat.h"\n' > ${.TARGET} printf '#include "SYS.h"\nPSEUDO(${.PREFIX:S/_//})\n' \ - > ${.TARGET} + >> ${.TARGET} MAN+= abort2.2 accept.2 access.2 acct.2 adjtime.2 \ aio_cancel.2 aio_error.2 aio_read.2 aio_return.2 \ Index: usr.bin/ipcs/ipcs.c =================================================================== --- usr.bin/ipcs/ipcs.c (revision 194642) +++ usr.bin/ipcs/ipcs.c (working copy) @@ -453,7 +453,7 @@ if (option & BIGGEST) printf(" %12zu", - kshmptr->shm_bsegsz); + kshmptr->u.shm_segsz); if (option & PID) printf(" %12d %12d",