mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-03-31 19:45:21 +00:00
ipc: unify the syscalls code
This patch introduces a change into the sys_msgget(), sys_semget() and sys_shmget() routines: they now share a common code, which is better for maintainability. Signed-off-by: Nadia Derbey <Nadia.Derbey@bull.net> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
7ca7e564e0
commit
7748dbfaa0
5 changed files with 215 additions and 139 deletions
61
ipc/msg.c
61
ipc/msg.c
|
@ -81,7 +81,7 @@ static struct ipc_ids init_msg_ids;
|
||||||
ipc_buildid(&msg_ids(ns), id, seq)
|
ipc_buildid(&msg_ids(ns), id, seq)
|
||||||
|
|
||||||
static void freeque(struct ipc_namespace *, struct msg_queue *);
|
static void freeque(struct ipc_namespace *, struct msg_queue *);
|
||||||
static int newque (struct ipc_namespace *ns, key_t key, int msgflg);
|
static int newque(struct ipc_namespace *, struct ipc_params *);
|
||||||
#ifdef CONFIG_PROC_FS
|
#ifdef CONFIG_PROC_FS
|
||||||
static int sysvipc_msg_proc_show(struct seq_file *s, void *it);
|
static int sysvipc_msg_proc_show(struct seq_file *s, void *it);
|
||||||
#endif
|
#endif
|
||||||
|
@ -144,10 +144,12 @@ static inline void msg_rmid(struct ipc_namespace *ns, struct msg_queue *s)
|
||||||
ipc_rmid(&msg_ids(ns), &s->q_perm);
|
ipc_rmid(&msg_ids(ns), &s->q_perm);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int newque (struct ipc_namespace *ns, key_t key, int msgflg)
|
static int newque(struct ipc_namespace *ns, struct ipc_params *params)
|
||||||
{
|
{
|
||||||
struct msg_queue *msq;
|
struct msg_queue *msq;
|
||||||
int id, retval;
|
int id, retval;
|
||||||
|
key_t key = params->key;
|
||||||
|
int msgflg = params->flg;
|
||||||
|
|
||||||
msq = ipc_rcu_alloc(sizeof(*msq));
|
msq = ipc_rcu_alloc(sizeof(*msq));
|
||||||
if (!msq)
|
if (!msq)
|
||||||
|
@ -264,56 +266,27 @@ static void freeque(struct ipc_namespace *ns, struct msg_queue *msq)
|
||||||
ipc_rcu_putref(msq);
|
ipc_rcu_putref(msq);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int msg_security(void *msq, int msgflg)
|
||||||
|
{
|
||||||
|
return security_msg_queue_associate((struct msg_queue *) msq, msgflg);
|
||||||
|
}
|
||||||
|
|
||||||
asmlinkage long sys_msgget(key_t key, int msgflg)
|
asmlinkage long sys_msgget(key_t key, int msgflg)
|
||||||
{
|
{
|
||||||
struct msg_queue *msq;
|
|
||||||
int ret;
|
|
||||||
struct ipc_namespace *ns;
|
struct ipc_namespace *ns;
|
||||||
|
struct ipc_ops msg_ops;
|
||||||
|
struct ipc_params msg_params;
|
||||||
|
|
||||||
ns = current->nsproxy->ipc_ns;
|
ns = current->nsproxy->ipc_ns;
|
||||||
|
|
||||||
ret = idr_pre_get(&msg_ids(ns).ipcs_idr, GFP_KERNEL);
|
msg_ops.getnew = newque;
|
||||||
|
msg_ops.associate = msg_security;
|
||||||
|
msg_ops.more_checks = NULL;
|
||||||
|
|
||||||
if (key == IPC_PRIVATE) {
|
msg_params.key = key;
|
||||||
if (!ret)
|
msg_params.flg = msgflg;
|
||||||
ret = -ENOMEM;
|
|
||||||
else {
|
|
||||||
mutex_lock(&msg_ids(ns).mutex);
|
|
||||||
ret = newque(ns, key, msgflg);
|
|
||||||
mutex_unlock(&msg_ids(ns).mutex);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
mutex_lock(&msg_ids(ns).mutex);
|
|
||||||
msq = (struct msg_queue *) ipc_findkey(&msg_ids(ns), key);
|
|
||||||
if (msq == NULL) {
|
|
||||||
/* key not used */
|
|
||||||
if (!(msgflg & IPC_CREAT))
|
|
||||||
ret = -ENOENT;
|
|
||||||
else if (!ret)
|
|
||||||
ret = -ENOMEM;
|
|
||||||
else
|
|
||||||
ret = newque(ns, key, msgflg);
|
|
||||||
} else {
|
|
||||||
/* msq has been locked by ipc_findkey() */
|
|
||||||
|
|
||||||
if (msgflg & IPC_CREAT && msgflg & IPC_EXCL)
|
return ipcget(ns, &msg_ids(ns), &msg_ops, &msg_params);
|
||||||
ret = -EEXIST;
|
|
||||||
else {
|
|
||||||
if (ipcperms(&msq->q_perm, msgflg))
|
|
||||||
ret = -EACCES;
|
|
||||||
else {
|
|
||||||
ret = security_msg_queue_associate(
|
|
||||||
msq, msgflg);
|
|
||||||
if (!ret)
|
|
||||||
ret = msq->q_perm.id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
msg_unlock(msq);
|
|
||||||
}
|
|
||||||
mutex_unlock(&msg_ids(ns).mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline unsigned long
|
static inline unsigned long
|
||||||
|
|
76
ipc/sem.c
76
ipc/sem.c
|
@ -97,7 +97,7 @@
|
||||||
|
|
||||||
static struct ipc_ids init_sem_ids;
|
static struct ipc_ids init_sem_ids;
|
||||||
|
|
||||||
static int newary(struct ipc_namespace *, key_t, int, int);
|
static int newary(struct ipc_namespace *, struct ipc_params *);
|
||||||
static void freeary(struct ipc_namespace *, struct sem_array *);
|
static void freeary(struct ipc_namespace *, struct sem_array *);
|
||||||
#ifdef CONFIG_PROC_FS
|
#ifdef CONFIG_PROC_FS
|
||||||
static int sysvipc_sem_proc_show(struct seq_file *s, void *it);
|
static int sysvipc_sem_proc_show(struct seq_file *s, void *it);
|
||||||
|
@ -214,12 +214,15 @@ static inline void sem_rmid(struct ipc_namespace *ns, struct sem_array *s)
|
||||||
*/
|
*/
|
||||||
#define IN_WAKEUP 1
|
#define IN_WAKEUP 1
|
||||||
|
|
||||||
static int newary (struct ipc_namespace *ns, key_t key, int nsems, int semflg)
|
static int newary(struct ipc_namespace *ns, struct ipc_params *params)
|
||||||
{
|
{
|
||||||
int id;
|
int id;
|
||||||
int retval;
|
int retval;
|
||||||
struct sem_array *sma;
|
struct sem_array *sma;
|
||||||
int size;
|
int size;
|
||||||
|
key_t key = params->key;
|
||||||
|
int nsems = params->u.nsems;
|
||||||
|
int semflg = params->flg;
|
||||||
|
|
||||||
if (!nsems)
|
if (!nsems)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -263,61 +266,40 @@ static int newary (struct ipc_namespace *ns, key_t key, int nsems, int semflg)
|
||||||
return sma->sem_perm.id;
|
return sma->sem_perm.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
asmlinkage long sys_semget (key_t key, int nsems, int semflg)
|
|
||||||
|
static inline int sem_security(void *sma, int semflg)
|
||||||
|
{
|
||||||
|
return security_sem_associate((struct sem_array *) sma, semflg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int sem_more_checks(void *sma, struct ipc_params *params)
|
||||||
|
{
|
||||||
|
if (params->u.nsems > ((struct sem_array *)sma)->sem_nsems)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
asmlinkage long sys_semget(key_t key, int nsems, int semflg)
|
||||||
{
|
{
|
||||||
int err;
|
|
||||||
struct sem_array *sma;
|
|
||||||
struct ipc_namespace *ns;
|
struct ipc_namespace *ns;
|
||||||
|
struct ipc_ops sem_ops;
|
||||||
|
struct ipc_params sem_params;
|
||||||
|
|
||||||
ns = current->nsproxy->ipc_ns;
|
ns = current->nsproxy->ipc_ns;
|
||||||
|
|
||||||
if (nsems < 0 || nsems > ns->sc_semmsl)
|
if (nsems < 0 || nsems > ns->sc_semmsl)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
err = idr_pre_get(&sem_ids(ns).ipcs_idr, GFP_KERNEL);
|
sem_ops.getnew = newary;
|
||||||
|
sem_ops.associate = sem_security;
|
||||||
|
sem_ops.more_checks = sem_more_checks;
|
||||||
|
|
||||||
if (key == IPC_PRIVATE) {
|
sem_params.key = key;
|
||||||
if (!err)
|
sem_params.flg = semflg;
|
||||||
err = -ENOMEM;
|
sem_params.u.nsems = nsems;
|
||||||
else {
|
|
||||||
mutex_lock(&sem_ids(ns).mutex);
|
|
||||||
err = newary(ns, key, nsems, semflg);
|
|
||||||
mutex_unlock(&sem_ids(ns).mutex);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
mutex_lock(&sem_ids(ns).mutex);
|
|
||||||
sma = (struct sem_array *) ipc_findkey(&sem_ids(ns), key);
|
|
||||||
if (sma == NULL) {
|
|
||||||
/* key not used */
|
|
||||||
if (!(semflg & IPC_CREAT))
|
|
||||||
err = -ENOENT;
|
|
||||||
else if (!err)
|
|
||||||
err = -ENOMEM;
|
|
||||||
else
|
|
||||||
err = newary(ns, key, nsems, semflg);
|
|
||||||
} else {
|
|
||||||
/* sma has been locked by ipc_findkey() */
|
|
||||||
|
|
||||||
if (semflg & IPC_CREAT && semflg & IPC_EXCL)
|
return ipcget(ns, &sem_ids(ns), &sem_ops, &sem_params);
|
||||||
err = -EEXIST;
|
|
||||||
else {
|
|
||||||
if (nsems > sma->sem_nsems)
|
|
||||||
err = -EINVAL;
|
|
||||||
else if (ipcperms(&sma->sem_perm, semflg))
|
|
||||||
err = -EACCES;
|
|
||||||
else {
|
|
||||||
err = security_sem_associate(sma,
|
|
||||||
semflg);
|
|
||||||
if (!err)
|
|
||||||
err = sma->sem_perm.id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sem_unlock(sma);
|
|
||||||
}
|
|
||||||
mutex_unlock(&sem_ids(ns).mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Manage the doubly linked list sma->sem_pending as a FIFO:
|
/* Manage the doubly linked list sma->sem_pending as a FIFO:
|
||||||
|
|
73
ipc/shm.c
73
ipc/shm.c
|
@ -68,8 +68,7 @@ static struct ipc_ids init_shm_ids;
|
||||||
#define shm_buildid(ns, id, seq) \
|
#define shm_buildid(ns, id, seq) \
|
||||||
ipc_buildid(&shm_ids(ns), id, seq)
|
ipc_buildid(&shm_ids(ns), id, seq)
|
||||||
|
|
||||||
static int newseg (struct ipc_namespace *ns, key_t key,
|
static int newseg(struct ipc_namespace *, struct ipc_params *);
|
||||||
int shmflg, size_t size);
|
|
||||||
static void shm_open(struct vm_area_struct *vma);
|
static void shm_open(struct vm_area_struct *vma);
|
||||||
static void shm_close(struct vm_area_struct *vma);
|
static void shm_close(struct vm_area_struct *vma);
|
||||||
static void shm_destroy (struct ipc_namespace *ns, struct shmid_kernel *shp);
|
static void shm_destroy (struct ipc_namespace *ns, struct shmid_kernel *shp);
|
||||||
|
@ -341,8 +340,11 @@ static struct vm_operations_struct shm_vm_ops = {
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
static int newseg (struct ipc_namespace *ns, key_t key, int shmflg, size_t size)
|
static int newseg(struct ipc_namespace *ns, struct ipc_params *params)
|
||||||
{
|
{
|
||||||
|
key_t key = params->key;
|
||||||
|
int shmflg = params->flg;
|
||||||
|
size_t size = params->u.size;
|
||||||
int error;
|
int error;
|
||||||
struct shmid_kernel *shp;
|
struct shmid_kernel *shp;
|
||||||
int numpages = (size + PAGE_SIZE -1) >> PAGE_SHIFT;
|
int numpages = (size + PAGE_SIZE -1) >> PAGE_SHIFT;
|
||||||
|
@ -423,57 +425,36 @@ no_file:
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int shm_security(void *shp, int shmflg)
|
||||||
|
{
|
||||||
|
return security_shm_associate((struct shmid_kernel *) shp, shmflg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int shm_more_checks(void *shp, struct ipc_params *params)
|
||||||
|
{
|
||||||
|
if (((struct shmid_kernel *)shp)->shm_segsz < params->u.size)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
asmlinkage long sys_shmget (key_t key, size_t size, int shmflg)
|
asmlinkage long sys_shmget (key_t key, size_t size, int shmflg)
|
||||||
{
|
{
|
||||||
struct shmid_kernel *shp;
|
|
||||||
int err;
|
|
||||||
struct ipc_namespace *ns;
|
struct ipc_namespace *ns;
|
||||||
|
struct ipc_ops shm_ops;
|
||||||
|
struct ipc_params shm_params;
|
||||||
|
|
||||||
ns = current->nsproxy->ipc_ns;
|
ns = current->nsproxy->ipc_ns;
|
||||||
|
|
||||||
err = idr_pre_get(&shm_ids(ns).ipcs_idr, GFP_KERNEL);
|
shm_ops.getnew = newseg;
|
||||||
|
shm_ops.associate = shm_security;
|
||||||
|
shm_ops.more_checks = shm_more_checks;
|
||||||
|
|
||||||
if (key == IPC_PRIVATE) {
|
shm_params.key = key;
|
||||||
if (!err)
|
shm_params.flg = shmflg;
|
||||||
err = -ENOMEM;
|
shm_params.u.size = size;
|
||||||
else {
|
|
||||||
mutex_lock(&shm_ids(ns).mutex);
|
|
||||||
err = newseg(ns, key, shmflg, size);
|
|
||||||
mutex_unlock(&shm_ids(ns).mutex);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
mutex_lock(&shm_ids(ns).mutex);
|
|
||||||
shp = (struct shmid_kernel *) ipc_findkey(&shm_ids(ns), key);
|
|
||||||
if (shp == NULL) {
|
|
||||||
if (!(shmflg & IPC_CREAT))
|
|
||||||
err = -ENOENT;
|
|
||||||
else if (!err)
|
|
||||||
err = -ENOMEM;
|
|
||||||
else
|
|
||||||
err = newseg(ns, key, shmflg, size);
|
|
||||||
} else {
|
|
||||||
/* shp has been locked by ipc_findkey() */
|
|
||||||
|
|
||||||
if ((shmflg & IPC_CREAT) && (shmflg & IPC_EXCL))
|
return ipcget(ns, &shm_ids(ns), &shm_ops, &shm_params);
|
||||||
err = -EEXIST;
|
|
||||||
else {
|
|
||||||
if (shp->shm_segsz < size)
|
|
||||||
err = -EINVAL;
|
|
||||||
else if (ipcperms(&shp->shm_perm, shmflg))
|
|
||||||
err = -EACCES;
|
|
||||||
else {
|
|
||||||
err = security_shm_associate(shp,
|
|
||||||
shmflg);
|
|
||||||
if (!err)
|
|
||||||
err = shp->shm_perm.id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
shm_unlock(shp);
|
|
||||||
}
|
|
||||||
mutex_unlock(&shm_ids(ns).mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline unsigned long copy_shmid_to_user(void __user *buf, struct shmid64_ds *in, int version)
|
static inline unsigned long copy_shmid_to_user(void __user *buf, struct shmid64_ds *in, int version)
|
||||||
|
|
101
ipc/util.c
101
ipc/util.c
|
@ -197,7 +197,7 @@ void __init ipc_init_proc_interface(const char *path, const char *header,
|
||||||
* If key is found ipc contains its ipc structure
|
* If key is found ipc contains its ipc structure
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct kern_ipc_perm *ipc_findkey(struct ipc_ids *ids, key_t key)
|
static struct kern_ipc_perm *ipc_findkey(struct ipc_ids *ids, key_t key)
|
||||||
{
|
{
|
||||||
struct kern_ipc_perm *ipc;
|
struct kern_ipc_perm *ipc;
|
||||||
int next_id;
|
int next_id;
|
||||||
|
@ -300,6 +300,105 @@ int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size)
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ipcget_new - create a new ipc object
|
||||||
|
* @ns: namespace
|
||||||
|
* @ids: identifer set
|
||||||
|
* @ops: the actual creation routine to call
|
||||||
|
* @params: its parameters
|
||||||
|
*
|
||||||
|
* This routine is called sys_msgget, sys_semget() and sys_shmget() when
|
||||||
|
* the key is IPC_PRIVATE
|
||||||
|
*/
|
||||||
|
int ipcget_new(struct ipc_namespace *ns, struct ipc_ids *ids,
|
||||||
|
struct ipc_ops *ops, struct ipc_params *params)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
|
err = idr_pre_get(&ids->ipcs_idr, GFP_KERNEL);
|
||||||
|
|
||||||
|
if (!err)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
mutex_lock(&ids->mutex);
|
||||||
|
err = ops->getnew(ns, params);
|
||||||
|
mutex_unlock(&ids->mutex);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ipc_check_perms - check security and permissions for an IPC
|
||||||
|
* @ipcp: ipc permission set
|
||||||
|
* @ids: identifer set
|
||||||
|
* @ops: the actual security routine to call
|
||||||
|
* @params: its parameters
|
||||||
|
*/
|
||||||
|
static int ipc_check_perms(struct kern_ipc_perm *ipcp, struct ipc_ops *ops,
|
||||||
|
struct ipc_params *params)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (ipcperms(ipcp, params->flg))
|
||||||
|
err = -EACCES;
|
||||||
|
else {
|
||||||
|
err = ops->associate(ipcp, params->flg);
|
||||||
|
if (!err)
|
||||||
|
err = ipcp->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ipcget_public - get an ipc object or create a new one
|
||||||
|
* @ns: namespace
|
||||||
|
* @ids: identifer set
|
||||||
|
* @ops: the actual creation routine to call
|
||||||
|
* @params: its parameters
|
||||||
|
*
|
||||||
|
* This routine is called sys_msgget, sys_semget() and sys_shmget() when
|
||||||
|
* the key is not IPC_PRIVATE
|
||||||
|
*/
|
||||||
|
int ipcget_public(struct ipc_namespace *ns, struct ipc_ids *ids,
|
||||||
|
struct ipc_ops *ops, struct ipc_params *params)
|
||||||
|
{
|
||||||
|
struct kern_ipc_perm *ipcp;
|
||||||
|
int flg = params->flg;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
err = idr_pre_get(&ids->ipcs_idr, GFP_KERNEL);
|
||||||
|
|
||||||
|
mutex_lock(&ids->mutex);
|
||||||
|
ipcp = ipc_findkey(ids, params->key);
|
||||||
|
if (ipcp == NULL) {
|
||||||
|
/* key not used */
|
||||||
|
if (!(flg & IPC_CREAT))
|
||||||
|
err = -ENOENT;
|
||||||
|
else if (!err)
|
||||||
|
err = -ENOMEM;
|
||||||
|
else
|
||||||
|
err = ops->getnew(ns, params);
|
||||||
|
} else {
|
||||||
|
/* ipc object has been locked by ipc_findkey() */
|
||||||
|
|
||||||
|
if (flg & IPC_CREAT && flg & IPC_EXCL)
|
||||||
|
err = -EEXIST;
|
||||||
|
else {
|
||||||
|
err = 0;
|
||||||
|
if (ops->more_checks)
|
||||||
|
err = ops->more_checks(ipcp, params);
|
||||||
|
if (!err)
|
||||||
|
err = ipc_check_perms(ipcp, ops, params);
|
||||||
|
}
|
||||||
|
ipc_unlock(ipcp);
|
||||||
|
}
|
||||||
|
mutex_unlock(&ids->mutex);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ipc_rmid - remove an IPC identifier
|
* ipc_rmid - remove an IPC identifier
|
||||||
* @ids: identifier set
|
* @ids: identifier set
|
||||||
|
|
43
ipc/util.h
43
ipc/util.h
|
@ -35,6 +35,35 @@ struct ipc_ids {
|
||||||
struct idr ipcs_idr;
|
struct idr ipcs_idr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Structure that holds the parameters needed by the ipc operations
|
||||||
|
* (see after)
|
||||||
|
*/
|
||||||
|
struct ipc_params {
|
||||||
|
key_t key;
|
||||||
|
int flg;
|
||||||
|
union {
|
||||||
|
size_t size; /* for shared memories */
|
||||||
|
int nsems; /* for semaphores */
|
||||||
|
} u; /* holds the getnew() specific param */
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Structure that holds some ipc operations. This structure is used to unify
|
||||||
|
* the calls to sys_msgget(), sys_semget(), sys_shmget()
|
||||||
|
* . routine to call to create a new ipc object. Can be one of newque,
|
||||||
|
* newary, newseg
|
||||||
|
* . routine to call to call to check permissions for a new ipc object.
|
||||||
|
* Can be one of security_msg_associate, security_sem_associate,
|
||||||
|
* security_shm_associate
|
||||||
|
* . routine to call for an extra check if needed
|
||||||
|
*/
|
||||||
|
struct ipc_ops {
|
||||||
|
int (*getnew) (struct ipc_namespace *, struct ipc_params *);
|
||||||
|
int (*associate) (void *, int);
|
||||||
|
int (*more_checks) (void *, struct ipc_params *);
|
||||||
|
};
|
||||||
|
|
||||||
struct seq_file;
|
struct seq_file;
|
||||||
|
|
||||||
void ipc_init_ids(struct ipc_ids *);
|
void ipc_init_ids(struct ipc_ids *);
|
||||||
|
@ -50,7 +79,6 @@ void __init ipc_init_proc_interface(const char *path, const char *header,
|
||||||
#define IPC_SHM_IDS 2
|
#define IPC_SHM_IDS 2
|
||||||
|
|
||||||
/* must be called with ids->mutex acquired.*/
|
/* must be called with ids->mutex acquired.*/
|
||||||
struct kern_ipc_perm *ipc_findkey(struct ipc_ids *ids, key_t key);
|
|
||||||
int ipc_addid(struct ipc_ids *, struct kern_ipc_perm *, int);
|
int ipc_addid(struct ipc_ids *, struct kern_ipc_perm *, int);
|
||||||
int ipc_get_maxid(struct ipc_ids *);
|
int ipc_get_maxid(struct ipc_ids *);
|
||||||
|
|
||||||
|
@ -95,5 +123,18 @@ int ipc_parse_version (int *cmd);
|
||||||
extern void free_msg(struct msg_msg *msg);
|
extern void free_msg(struct msg_msg *msg);
|
||||||
extern struct msg_msg *load_msg(const void __user *src, int len);
|
extern struct msg_msg *load_msg(const void __user *src, int len);
|
||||||
extern int store_msg(void __user *dest, struct msg_msg *msg, int len);
|
extern int store_msg(void __user *dest, struct msg_msg *msg, int len);
|
||||||
|
extern int ipcget_new(struct ipc_namespace *, struct ipc_ids *,
|
||||||
|
struct ipc_ops *, struct ipc_params *);
|
||||||
|
extern int ipcget_public(struct ipc_namespace *, struct ipc_ids *,
|
||||||
|
struct ipc_ops *, struct ipc_params *);
|
||||||
|
|
||||||
|
static inline int ipcget(struct ipc_namespace *ns, struct ipc_ids *ids,
|
||||||
|
struct ipc_ops *ops, struct ipc_params *params)
|
||||||
|
{
|
||||||
|
if (params->key == IPC_PRIVATE)
|
||||||
|
return ipcget_new(ns, ids, ops, params);
|
||||||
|
else
|
||||||
|
return ipcget_public(ns, ids, ops, params);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Reference in a new issue