Move SysV IPC freebsd32 compat shims from freebsd32_misc.c to corresponding

sysv_{msg,sem,shm}.c files.

Mark SysV IPC freebsd32 syscalls as NOSTD and add required
SYSCALL_INIT_HELPER/SYSCALL32_INIT_HELPERs to provide auto
register/unregister on module load.

This makes COMPAT_FREEBSD32 functional with SysV IPC compiled and loaded
as modules.

Reviewed by:	jhb
MFC after:	2 weeks
This commit is contained in:
Konstantin Belousov 2010-03-19 11:04:42 +00:00
parent 4cfc39cfa6
commit 75d633cbf6
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=205323
5 changed files with 733 additions and 587 deletions

View File

@ -1401,536 +1401,6 @@ freebsd4_freebsd32_fhstatfs(struct thread *td, struct freebsd4_freebsd32_fhstatf
#endif
int
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 (freebsd7_freebsd32_semctl(td,
(struct freebsd7_freebsd32_semctl_args *)&uap->a2));
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;
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_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_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);
}
int
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 (freebsd7_freebsd32_msgctl(td,
(struct freebsd7_freebsd32_msgctl_args *)&uap->a2));
case 2:
return (freebsd32_msgsnd(td,
(struct freebsd32_msgsnd_args *)&uap->a2));
case 3:
return (freebsd32_msgrcv(td,
(struct freebsd32_msgrcv_args *)&uap->a2));
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;
struct msqid_ds32 msqbuf32;
int error;
if (uap->cmd == IPC_SET) {
error = copyin(uap->buf, &msqbuf32, sizeof(msqbuf32));
if (error)
return (error);
freebsd32_ipcperm_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) {
freebsd32_ipcperm_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);
}
int
freebsd32_msgsnd(struct thread *td, struct freebsd32_msgsnd_args *uap)
{
const void *msgp;
long mtype;
int32_t mtype32;
int error;
msgp = PTRIN(uap->msgp);
if ((error = copyin(msgp, &mtype32, sizeof(mtype32))) != 0)
return (error);
mtype = mtype32;
return (kern_msgsnd(td, uap->msqid,
(const char *)msgp + sizeof(mtype32),
uap->msgsz, uap->msgflg, mtype));
}
int
freebsd32_msgrcv(struct thread *td, struct freebsd32_msgrcv_args *uap)
{
void *msgp;
long mtype;
int32_t mtype32;
int error;
msgp = PTRIN(uap->msgp);
if ((error = kern_msgrcv(td, uap->msqid,
(char *)msgp + sizeof(mtype32), uap->msgsz,
uap->msgtyp, uap->msgflg, &mtype)) != 0)
return (error);
mtype32 = (int32_t)mtype;
return (copyout(&mtype32, msgp, sizeof(mtype32)));
}
int
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;
ap.shmid = uap->a2;
ap.shmaddr = PTRIN(uap->a3);
ap.shmflg = uap->a4;
return (sysent[SYS_shmat].sy_call(td, &ap));
}
case 2: { /* shmdt */
struct shmdt_args ap;
ap.shmaddr = PTRIN(uap->a2);
return (sysent[SYS_shmdt].sy_call(td, &ap));
}
case 3: { /* shmget */
struct shmget_args ap;
ap.key = uap->a2;
ap.size = uap->a3;
ap.shmflg = uap->a4;
return (sysent[SYS_shmget].sy_call(td, &ap));
}
case 4: { /* shmctl */
struct freebsd7_freebsd32_shmctl_args ap;
ap.shmid = uap->a2;
ap.cmd = uap->a3;
ap.buf = PTRIN(uap->a4);
return (freebsd7_freebsd32_shmctl(td, &ap));
}
case 1: /* oshmctl */
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;
union {
struct shmid_ds shmid_ds;
struct shm_info shm_info;
struct shminfo shminfo;
} u;
union {
struct shmid_ds32 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_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_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);
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);
}
int
freebsd32_pread(struct thread *td, struct freebsd32_pread_args *uap)
{

View File

@ -309,11 +309,11 @@
struct rtprio *rtp); }
167 AUE_NULL UNIMPL nosys
168 AUE_NULL UNIMPL nosys
169 AUE_SEMSYS STD { int freebsd32_semsys(int which, int a2, \
169 AUE_SEMSYS NOSTD { int freebsd32_semsys(int which, int a2, \
int a3, int a4, int a5); }
170 AUE_MSGSYS STD { int freebsd32_msgsys(int which, int a2, \
170 AUE_MSGSYS NOSTD { int freebsd32_msgsys(int which, int a2, \
int a3, int a4, int a5, int a6); }
171 AUE_SHMSYS STD { int freebsd32_shmsys(uint32_t which, uint32_t a2, \
171 AUE_SHMSYS NOSTD { int freebsd32_shmsys(uint32_t which, uint32_t a2, \
uint32_t a3, uint32_t a4); }
172 AUE_NULL UNIMPL nosys
173 AUE_PREAD COMPAT6 { ssize_t freebsd32_pread(int fd, void *buf, \
@ -401,26 +401,29 @@
; The following were introduced with NetBSD/4.4Lite-2
; They are initialized by their respective modules/sysinits
; XXX PROBLEM!!
220 AUE_SEMCTL COMPAT7 { int freebsd32_semctl(int semid, int semnum, \
220 AUE_SEMCTL COMPAT7|NOSTD { int freebsd32_semctl( \
int semid, int semnum, \
int cmd, union semun32 *arg); }
221 AUE_SEMGET NOPROTO { int semget(key_t key, int nsems, \
221 AUE_SEMGET NOSTD|NOPROTO { int semget(key_t key, int nsems, \
int semflg); }
222 AUE_SEMOP NOPROTO { int semop(int semid, struct sembuf *sops, \
u_int nsops); }
222 AUE_SEMOP NOSTD|NOPROTO { int semop(int semid, \
struct sembuf *sops, u_int nsops); }
223 AUE_NULL UNIMPL semconfig
224 AUE_MSGCTL COMPAT7 { int freebsd32_msgctl(int msqid, int cmd, \
224 AUE_MSGCTL COMPAT7|NOSTD { 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, \
225 AUE_MSGGET NOSTD|NOPROTO { int msgget(key_t key, int msgflg); }
226 AUE_MSGSND NOSTD { int freebsd32_msgsnd(int msqid, void *msgp, \
size_t msgsz, int msgflg); }
227 AUE_MSGRCV STD { int freebsd32_msgrcv(int msqid, void *msgp, \
227 AUE_MSGRCV NOSTD { int freebsd32_msgrcv(int msqid, void *msgp, \
size_t msgsz, long msgtyp, int msgflg); }
228 AUE_SHMAT NOPROTO { int shmat(int shmid, void *shmaddr, \
228 AUE_SHMAT NOSTD|NOPROTO { int shmat(int shmid, void *shmaddr, \
int shmflg); }
229 AUE_SHMCTL COMPAT7 { int freebsd32_shmctl(int shmid, int cmd, \
229 AUE_SHMCTL COMPAT7|NOSTD { 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, \
230 AUE_SHMDT NOSTD|NOPROTO { int shmdt(void *shmaddr); }
231 AUE_SHMGET NOSTD|NOPROTO { int shmget(key_t key, int size, \
int shmflg); }
;
232 AUE_NULL STD { int freebsd32_clock_gettime(clockid_t clock_id, \
@ -925,11 +928,11 @@
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, \
510 AUE_SEMCTL NOSTD { int freebsd32_semctl(int semid, int semnum, \
int cmd, union semun32 *arg); }
511 AUE_MSGCTL STD { int freebsd32_msgctl(int msqid, int cmd, \
511 AUE_MSGCTL NOSTD { int freebsd32_msgctl(int msqid, int cmd, \
struct msqid_ds32 *buf); }
512 AUE_SHMCTL STD { int freebsd32_shmctl(int shmid, int cmd, \
512 AUE_SHMCTL NOSTD { int freebsd32_shmctl(int shmid, int cmd, \
struct shmid_ds32 *buf); }
513 AUE_LPATHCONF NOPROTO { int lpathconf(char *path, int name); }
514 AUE_CAP_NEW UNIMPL cap_new

View File

@ -74,7 +74,7 @@ __FBSDID("$FreeBSD$");
static MALLOC_DEFINE(M_MSG, "msg", "SVID compatible message queues");
static void msginit(void);
static int msginit(void);
static int msgunload(void);
static int sysvmsg_modload(struct module *, int, void *);
@ -152,10 +152,45 @@ static struct msg *msghdrs; /* MSGTQL msg headers */
static struct msqid_kernel *msqids; /* MSGMNI msqid_kernel struct's */
static struct mtx msq_mtx; /* global mutex for message queues. */
static void
static struct syscall_helper_data msg_syscalls[] = {
SYSCALL_INIT_HELPER(msgctl),
SYSCALL_INIT_HELPER(msgget),
SYSCALL_INIT_HELPER(msgsnd),
SYSCALL_INIT_HELPER(msgrcv),
#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
SYSCALL_INIT_HELPER(msgsys),
SYSCALL_INIT_HELPER(freebsd7_msgctl),
#endif
SYSCALL_INIT_LAST
};
#ifdef COMPAT_FREEBSD32
#include <compat/freebsd32/freebsd32.h>
#include <compat/freebsd32/freebsd32_ipc.h>
#include <compat/freebsd32/freebsd32_proto.h>
#include <compat/freebsd32/freebsd32_signal.h>
#include <compat/freebsd32/freebsd32_syscall.h>
#include <compat/freebsd32/freebsd32_util.h>
static struct syscall_helper_data msg32_syscalls[] = {
SYSCALL32_INIT_HELPER(freebsd32_msgctl),
SYSCALL32_INIT_HELPER(freebsd32_msgsnd),
SYSCALL32_INIT_HELPER(freebsd32_msgrcv),
SYSCALL32_INIT_HELPER(msgget),
SYSCALL32_INIT_HELPER(freebsd32_msgsys),
#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
SYSCALL32_INIT_HELPER(freebsd7_freebsd32_msgctl),
#endif
SYSCALL_INIT_LAST
};
#endif
static int
msginit()
{
register int i;
int i, error;
TUNABLE_INT_FETCH("kern.ipc.msgseg", &msginfo.msgseg);
TUNABLE_INT_FETCH("kern.ipc.msgssz", &msginfo.msgssz);
@ -235,6 +270,16 @@ msginit()
#endif
}
mtx_init(&msq_mtx, "msq", NULL, MTX_DEF);
error = syscall_helper_register(msg_syscalls);
if (error != 0)
return (error);
#ifdef COMPAT_FREEBSD32
error = syscall32_helper_register(msg32_syscalls);
if (error != 0)
return (error);
#endif
return (0);
}
static int
@ -246,6 +291,11 @@ msgunload()
int i;
#endif
syscall_helper_unregister(msg_syscalls);
#ifdef COMPAT_FREEBSD32
syscall32_helper_unregister(msg32_syscalls);
#endif
for (msqid = 0; msqid < msginfo.msgmni; msqid++) {
/*
* Look for an unallocated and unlocked msqid_ds.
@ -283,7 +333,9 @@ sysvmsg_modload(struct module *module, int cmd, void *arg)
switch (cmd) {
case MOD_LOAD:
msginit();
error = msginit();
if (error != 0)
msgunload();
break;
case MOD_UNLOAD:
error = msgunload();
@ -303,11 +355,6 @@ static moduledata_t sysvmsg_mod = {
NULL
};
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);
MODULE_VERSION(sysvmsg, 1);
@ -1257,10 +1304,159 @@ SYSCTL_INT(_kern_ipc, OID_AUTO, msgseg, CTLFLAG_RDTUN, &msginfo.msgseg, 0,
SYSCTL_PROC(_kern_ipc, OID_AUTO, msqids, CTLFLAG_RD,
NULL, 0, sysctl_msqids, "", "Message queue IDs");
#ifdef COMPAT_FREEBSD32
int
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 (freebsd7_freebsd32_msgctl(td,
(struct freebsd7_freebsd32_msgctl_args *)&uap->a2));
case 2:
return (freebsd32_msgsnd(td,
(struct freebsd32_msgsnd_args *)&uap->a2));
case 3:
return (freebsd32_msgrcv(td,
(struct freebsd32_msgrcv_args *)&uap->a2));
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;
struct msqid_ds32 msqbuf32;
int error;
if (uap->cmd == IPC_SET) {
error = copyin(uap->buf, &msqbuf32, sizeof(msqbuf32));
if (error)
return (error);
freebsd32_ipcperm_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) {
freebsd32_ipcperm_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);
}
int
freebsd32_msgsnd(struct thread *td, struct freebsd32_msgsnd_args *uap)
{
const void *msgp;
long mtype;
int32_t mtype32;
int error;
msgp = PTRIN(uap->msgp);
if ((error = copyin(msgp, &mtype32, sizeof(mtype32))) != 0)
return (error);
mtype = mtype32;
return (kern_msgsnd(td, uap->msqid,
(const char *)msgp + sizeof(mtype32),
uap->msgsz, uap->msgflg, mtype));
}
int
freebsd32_msgrcv(struct thread *td, struct freebsd32_msgrcv_args *uap)
{
void *msgp;
long mtype;
int32_t mtype32;
int error;
msgp = PTRIN(uap->msgp);
if ((error = kern_msgrcv(td, uap->msqid,
(char *)msgp + sizeof(mtype32), uap->msgsz,
uap->msgtyp, uap->msgflg, &mtype)) != 0)
return (error);
mtype32 = (int32_t)mtype;
return (copyout(&mtype32, msgp, sizeof(mtype32)));
}
#endif
#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[] = {
@ -1295,7 +1491,9 @@ msgsys(td, uap)
return (error);
}
#ifndef CP
#define CP(src, dst, fld) do { (dst).fld = (src).fld; } while (0)
#endif
#ifndef _SYS_SYSPROTO_H_
struct freebsd7_msgctl_args {

View File

@ -70,7 +70,7 @@ static MALLOC_DEFINE(M_SEM, "sem", "SVID compatible semaphores");
#define DPRINTF(a)
#endif
static void seminit(void);
static int seminit(void);
static int sysvsem_modload(struct module *, int, void *);
static int semunload(void);
static void semexit_myhook(void *arg, struct proc *p);
@ -214,10 +214,43 @@ SYSCTL_INT(_kern_ipc, OID_AUTO, semaem, CTLFLAG_RW, &seminfo.semaem, 0,
SYSCTL_PROC(_kern_ipc, OID_AUTO, sema, CTLFLAG_RD,
NULL, 0, sysctl_sema, "", "");
static void
static struct syscall_helper_data sem_syscalls[] = {
SYSCALL_INIT_HELPER(__semctl),
SYSCALL_INIT_HELPER(semget),
SYSCALL_INIT_HELPER(semop),
#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
SYSCALL_INIT_HELPER(semsys),
SYSCALL_INIT_HELPER(freebsd7___semctl),
#endif
SYSCALL_INIT_LAST
};
#ifdef COMPAT_FREEBSD32
#include <compat/freebsd32/freebsd32.h>
#include <compat/freebsd32/freebsd32_ipc.h>
#include <compat/freebsd32/freebsd32_proto.h>
#include <compat/freebsd32/freebsd32_signal.h>
#include <compat/freebsd32/freebsd32_syscall.h>
#include <compat/freebsd32/freebsd32_util.h>
static struct syscall_helper_data sem32_syscalls[] = {
SYSCALL32_INIT_HELPER(freebsd32_semctl),
SYSCALL32_INIT_HELPER(semget),
SYSCALL32_INIT_HELPER(semop),
SYSCALL32_INIT_HELPER(freebsd32_semsys),
#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
SYSCALL32_INIT_HELPER(freebsd7_freebsd32_semctl),
#endif
SYSCALL_INIT_LAST
};
#endif
static int
seminit(void)
{
int i;
int i, error;
TUNABLE_INT_FETCH("kern.ipc.semmap", &seminfo.semmap);
TUNABLE_INT_FETCH("kern.ipc.semmni", &seminfo.semmni);
@ -258,6 +291,16 @@ seminit(void)
mtx_init(&sem_undo_mtx, "semu", NULL, MTX_DEF);
semexit_tag = EVENTHANDLER_REGISTER(process_exit, semexit_myhook, NULL,
EVENTHANDLER_PRI_ANY);
error = syscall_helper_register(sem_syscalls);
if (error != 0)
return (error);
#ifdef COMPAT_FREEBSD32
error = syscall32_helper_register(sem32_syscalls);
if (error != 0)
return (error);
#endif
return (0);
}
static int
@ -269,6 +312,10 @@ semunload(void)
if (semtot != 0)
return (EBUSY);
#ifdef COMPAT_FREEBSD32
syscall32_helper_unregister(sem32_syscalls);
#endif
syscall_helper_unregister(sem_syscalls);
EVENTHANDLER_DEREGISTER(process_exit, semexit_tag);
#ifdef MAC
for (i = 0; i < seminfo.semmni; i++)
@ -292,7 +339,9 @@ sysvsem_modload(struct module *module, int cmd, void *arg)
switch (cmd) {
case MOD_LOAD:
seminit();
error = seminit();
if (error != 0)
semunload();
break;
case MOD_UNLOAD:
error = semunload();
@ -312,10 +361,6 @@ static moduledata_t sysvsem_mod = {
NULL
};
SYSCALL_MODULE_HELPER(__semctl);
SYSCALL_MODULE_HELPER(semget);
SYSCALL_MODULE_HELPER(semop);
DECLARE_MODULE(sysvsem, sysvsem_mod, SI_SUB_SYSV_SEM, SI_ORDER_FIRST);
MODULE_VERSION(sysvsem, 1);
@ -1316,8 +1361,6 @@ sysctl_sema(SYSCTL_HANDLER_ARGS)
#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[] = {
@ -1351,7 +1394,9 @@ semsys(td, uap)
return (error);
}
#ifndef CP
#define CP(src, dst, fld) do { (dst).fld = (src).fld; } while (0)
#endif
#ifndef _SYS_SYSPROTO_H_
struct freebsd7___semctl_args {
@ -1432,7 +1477,172 @@ freebsd7___semctl(struct thread *td, struct freebsd7___semctl_args *uap)
return (error);
}
#undef CP
#endif /* COMPAT_FREEBSD{4,5,6,7} */
#endif /* COMPAT_FREEBSD4 || COMPAT_FREEBSD5 || COMPAT_FREEBSD6 ||
COMPAT_FREEBSD7 */
#ifdef COMPAT_FREEBSD32
int
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 (freebsd7_freebsd32_semctl(td,
(struct freebsd7_freebsd32_semctl_args *)&uap->a2));
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;
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_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_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 /* COMPAT_FREEBSD32 */

View File

@ -122,7 +122,7 @@ static struct shmid_kernel *shm_find_segment_by_shmid(int);
static struct shmid_kernel *shm_find_segment_by_shmidx(int);
static int shm_delete_mapping(struct vmspace *vm, struct shmmap_state *);
static void shmrealloc(void);
static void shminit(void);
static int shminit(void);
static int sysvshm_modload(struct module *, int, void *);
static int shmunload(void);
static void shmexit_myhook(struct vmspace *vm);
@ -816,10 +816,47 @@ shmrealloc(void)
shmalloced = shminfo.shmmni;
}
static void
static struct syscall_helper_data shm_syscalls[] = {
SYSCALL_INIT_HELPER(shmat),
SYSCALL_INIT_HELPER(shmctl),
SYSCALL_INIT_HELPER(shmdt),
SYSCALL_INIT_HELPER(shmget),
#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
SYSCALL_INIT_HELPER(freebsd7_shmctl),
#endif
#if defined(__i386__) && (defined(COMPAT_FREEBSD4) || defined(COMPAT_43))
SYSCALL_INIT_HELPER(shmsys),
#endif
SYSCALL_INIT_LAST
};
#ifdef COMPAT_FREEBSD32
#include <compat/freebsd32/freebsd32.h>
#include <compat/freebsd32/freebsd32_ipc.h>
#include <compat/freebsd32/freebsd32_proto.h>
#include <compat/freebsd32/freebsd32_signal.h>
#include <compat/freebsd32/freebsd32_syscall.h>
#include <compat/freebsd32/freebsd32_util.h>
static struct syscall_helper_data shm32_syscalls[] = {
SYSCALL32_INIT_HELPER(shmat),
SYSCALL32_INIT_HELPER(shmdt),
SYSCALL32_INIT_HELPER(shmget),
SYSCALL32_INIT_HELPER(freebsd32_shmsys),
SYSCALL32_INIT_HELPER(freebsd32_shmctl),
#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
SYSCALL32_INIT_HELPER(freebsd7_freebsd32_shmctl),
#endif
SYSCALL_INIT_LAST
};
#endif
static int
shminit()
{
int i;
int i, error;
#ifndef BURN_BRIDGES
if (TUNABLE_ULONG_FETCH("kern.ipc.shmmaxpgs", &shminfo.shmall) != 0)
@ -855,6 +892,16 @@ shminit()
shm_committed = 0;
shmexit_hook = &shmexit_myhook;
shmfork_hook = &shmfork_myhook;
error = syscall_helper_register(shm_syscalls);
if (error != 0)
return (error);
#ifdef COMPAT_FREEBSD32
error = syscall32_helper_register(shm32_syscalls);
if (error != 0)
return (error);
#endif
return (0);
}
static int
@ -867,6 +914,11 @@ shmunload()
if (shm_nused > 0)
return (EBUSY);
#ifdef COMPAT_FREEBSD32
syscall32_helper_unregister(shm32_syscalls);
#endif
syscall_helper_unregister(shm_syscalls);
#ifdef MAC
for (i = 0; i < shmalloced; i++)
mac_sysvshm_destroy(&shmsegs[i]);
@ -985,14 +1037,234 @@ shmsys(td, uap)
return (error);
}
SYSCALL_MODULE_HELPER(shmsys);
#endif /* i386 && (COMPAT_FREEBSD4 || COMPAT_43) */
#ifdef COMPAT_FREEBSD32
int
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;
ap.shmid = uap->a2;
ap.shmaddr = PTRIN(uap->a3);
ap.shmflg = uap->a4;
return (sysent[SYS_shmat].sy_call(td, &ap));
}
case 2: { /* shmdt */
struct shmdt_args ap;
ap.shmaddr = PTRIN(uap->a2);
return (sysent[SYS_shmdt].sy_call(td, &ap));
}
case 3: { /* shmget */
struct shmget_args ap;
ap.key = uap->a2;
ap.size = uap->a3;
ap.shmflg = uap->a4;
return (sysent[SYS_shmget].sy_call(td, &ap));
}
case 4: { /* shmctl */
struct freebsd7_freebsd32_shmctl_args ap;
ap.shmid = uap->a2;
ap.cmd = uap->a3;
ap.buf = PTRIN(uap->a4);
return (freebsd7_freebsd32_shmctl(td, &ap));
}
case 1: /* oshmctl */
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;
union {
struct shmid_ds shmid_ds;
struct shm_info shm_info;
struct shminfo shminfo;
} u;
union {
struct shmid_ds32 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_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_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);
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
#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
#ifndef CP
#define CP(src, dst, fld) do { (dst).fld = (src).fld; } while (0)
#endif
#ifndef _SYS_SYSPROTO_H_
struct freebsd7_shmctl_args {
@ -1068,10 +1340,6 @@ freebsd7_shmctl(td, uap)
return (error);
}
SYSCALL_MODULE_HELPER(freebsd7_shmctl);
#undef CP
#endif /* COMPAT_FREEBSD4 || COMPAT_FREEBSD5 || COMPAT_FREEBSD6 ||
COMPAT_FREEBSD7 */
@ -1082,7 +1350,9 @@ sysvshm_modload(struct module *module, int cmd, void *arg)
switch (cmd) {
case MOD_LOAD:
shminit();
error = shminit();
if (error != 0)
shmunload();
break;
case MOD_UNLOAD:
error = shmunload();
@ -1102,10 +1372,5 @@ static moduledata_t sysvshm_mod = {
NULL
};
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);
MODULE_VERSION(sysvshm, 1);