mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-13 10:02:38 +00:00
Add freebsd32 compat wrappers for msgctl() and _semctl() using
kern_msgctl() and kern_semctl(). MFC after: 1 week
This commit is contained in:
parent
d43c6fa4fe
commit
3c39e0d8d4
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=174381
@ -39,6 +39,41 @@ struct ipc_perm32 {
|
||||
uint32_t key;
|
||||
};
|
||||
|
||||
struct semid_ds32 {
|
||||
struct ipc_perm32 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];
|
||||
};
|
||||
|
||||
union semun32 {
|
||||
int val;
|
||||
uint32_t buf;
|
||||
uint32_t array;
|
||||
};
|
||||
|
||||
struct msqid_ds32 {
|
||||
struct ipc_perm32 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 {
|
||||
struct ipc_perm32 shm_perm;
|
||||
int32_t shm_segsz;
|
||||
|
@ -71,6 +71,8 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/vnode.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/msg.h>
|
||||
#include <sys/sem.h>
|
||||
#include <sys/shm.h>
|
||||
|
||||
#include <vm/vm.h>
|
||||
@ -1319,36 +1321,203 @@ freebsd4_freebsd32_fhstatfs(struct thread *td, struct freebsd4_freebsd32_fhstatf
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
freebsd32_ipcperm_in(struct ipc_perm32 *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_out(struct ipc_perm *ip, struct ipc_perm32 *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);
|
||||
}
|
||||
|
||||
int
|
||||
freebsd32_semsys(struct thread *td, struct freebsd32_semsys_args *uap)
|
||||
{
|
||||
/*
|
||||
* Vector through to semsys if it is loaded.
|
||||
*/
|
||||
return sysent[SYS_semsys].sy_call(td, uap);
|
||||
|
||||
switch (uap->which) {
|
||||
case 0:
|
||||
return (freebsd32_semctl(td,
|
||||
(struct freebsd32_semctl_args *)&uap->a2));
|
||||
default:
|
||||
return (semsys(td, (struct semsys_args *)uap));
|
||||
}
|
||||
}
|
||||
|
||||
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_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:
|
||||
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:
|
||||
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;
|
||||
}
|
||||
|
||||
if (error == 0)
|
||||
td->td_retval[0] = rval;
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
freebsd32_msgsys(struct thread *td, struct freebsd32_msgsys_args *uap)
|
||||
{
|
||||
|
||||
switch (uap->which) {
|
||||
case 0:
|
||||
return (freebsd32_msgctl(td,
|
||||
(struct freebsd32_msgctl_args *)&uap->a2));
|
||||
case 2:
|
||||
return (freebsd32_msgsnd(td,
|
||||
(struct freebsd32_msgsnd_args *)&uap->a2));
|
||||
break;
|
||||
case 3:
|
||||
return (freebsd32_msgrcv(td,
|
||||
(struct freebsd32_msgrcv_args *)&uap->a2));
|
||||
break;
|
||||
default:
|
||||
/*
|
||||
* Vector through to msgsys if it is loaded.
|
||||
*/
|
||||
return (sysent[SYS_msgsys].sy_call(td, uap));
|
||||
break;
|
||||
return (msgsys(td, (struct msgsys_args *)uap));
|
||||
}
|
||||
}
|
||||
|
||||
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_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)
|
||||
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_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);
|
||||
}
|
||||
|
||||
int
|
||||
freebsd32_msgsnd(struct thread *td, struct freebsd32_msgsnd_args *uap)
|
||||
{
|
||||
@ -1444,13 +1613,8 @@ freebsd32_shmctl(struct thread *td, struct freebsd32_shmctl_args *uap)
|
||||
if ((error = copyin(uap->buf, &u32.shmid_ds32,
|
||||
sizeof(u32.shmid_ds32))))
|
||||
goto done;
|
||||
CP(u32.shmid_ds32, u.shmid_ds, shm_perm.cuid);
|
||||
CP(u32.shmid_ds32, u.shmid_ds, shm_perm.cgid);
|
||||
CP(u32.shmid_ds32, u.shmid_ds, shm_perm.uid);
|
||||
CP(u32.shmid_ds32, u.shmid_ds, shm_perm.gid);
|
||||
CP(u32.shmid_ds32, u.shmid_ds, shm_perm.mode);
|
||||
CP(u32.shmid_ds32, u.shmid_ds, shm_perm.seq);
|
||||
CP(u32.shmid_ds32, u.shmid_ds, shm_perm.key);
|
||||
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);
|
||||
@ -1488,13 +1652,8 @@ freebsd32_shmctl(struct thread *td, struct freebsd32_shmctl_args *uap)
|
||||
break;
|
||||
case SHM_STAT:
|
||||
case IPC_STAT:
|
||||
CP(u.shmid_ds, u32.shmid_ds32, shm_perm.cuid);
|
||||
CP(u.shmid_ds, u32.shmid_ds32, shm_perm.cgid);
|
||||
CP(u.shmid_ds, u32.shmid_ds32, shm_perm.uid);
|
||||
CP(u.shmid_ds, u32.shmid_ds32, shm_perm.gid);
|
||||
CP(u.shmid_ds, u32.shmid_ds32, shm_perm.mode);
|
||||
CP(u.shmid_ds, u32.shmid_ds32, shm_perm.seq);
|
||||
CP(u.shmid_ds, u32.shmid_ds32, shm_perm.key);
|
||||
freebsd32_ipcperm_out(&u.shmid_ds.shm_perm,
|
||||
&u32.shmid_ds32.shm_perm);
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user