summaryrefslogtreecommitdiffstats
path: root/ipc/util.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1994-11-28 11:59:19 +0000
committer <ralf@linux-mips.org>1994-11-28 11:59:19 +0000
commit1513ff9b7899ab588401c89db0e99903dbf5f886 (patch)
treef69cc81a940a502ea23d664c3ffb2d215a479667 /ipc/util.c
Import of Linus's Linux 1.1.68
Diffstat (limited to 'ipc/util.c')
-rw-r--r--ipc/util.c150
1 files changed, 150 insertions, 0 deletions
diff --git a/ipc/util.c b/ipc/util.c
new file mode 100644
index 000000000..fb0e6970d
--- /dev/null
+++ b/ipc/util.c
@@ -0,0 +1,150 @@
+/*
+ * linux/ipc/util.c
+ * Copyright (C) 1992 Krishna Balasubramanian
+ */
+
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <asm/segment.h>
+#include <linux/sched.h>
+#include <linux/sem.h>
+#include <linux/msg.h>
+#include <linux/shm.h>
+#include <linux/stat.h>
+
+void ipc_init (void);
+asmlinkage int sys_ipc (uint call, int first, int second, int third, void *ptr);
+
+#ifdef CONFIG_SYSVIPC
+
+int ipcperms (struct ipc_perm *ipcp, short flag);
+extern void sem_init (void), msg_init (void), shm_init (void);
+extern int sys_semget (key_t key, int nsems, int semflg);
+extern int sys_semop (int semid, struct sembuf *sops, unsigned nsops);
+extern int sys_semctl (int semid, int semnum, int cmd, union semun arg);
+extern int sys_msgget (key_t key, int msgflg);
+extern int sys_msgsnd (int msqid, struct msgbuf *msgp, int msgsz, int msgflg);
+extern int sys_msgrcv (int msqid, struct msgbuf *msgp, int msgsz, long msgtyp,
+ int msgflg);
+extern int sys_msgctl (int msqid, int cmd, struct msqid_ds *buf);
+extern int sys_shmget (key_t key, int size, int flag);
+extern int sys_shmat (int shmid, char *shmaddr, int shmflg, ulong *addr);
+extern int sys_shmdt (char *shmaddr);
+extern int sys_shmctl (int shmid, int cmd, struct shmid_ds *buf);
+
+void ipc_init (void)
+{
+ sem_init();
+ msg_init();
+ shm_init();
+ return;
+}
+
+/*
+ * Check user, group, other permissions for access
+ * to ipc resources. return 0 if allowed
+ */
+int ipcperms (struct ipc_perm *ipcp, short flag)
+{ /* flag will most probably be 0 or S_...UGO from <linux/stat.h> */
+ int requested_mode, granted_mode;
+
+ if (suser())
+ return 0;
+ requested_mode = (flag >> 6) | (flag >> 3) | flag;
+ granted_mode = ipcp->mode;
+ if (current->euid == ipcp->cuid || current->euid == ipcp->uid)
+ granted_mode >>= 6;
+ else if (in_group_p(ipcp->cgid) || in_group_p(ipcp->gid))
+ granted_mode >>= 3;
+ /* is there some bit set in requested_mode but not in granted_mode? */
+ if (requested_mode & ~granted_mode & 0007)
+ return -1;
+ return 0;
+}
+
+asmlinkage int sys_ipc (uint call, int first, int second, int third, void *ptr)
+{
+
+ if (call <= SEMCTL)
+ switch (call) {
+ case SEMOP:
+ return sys_semop (first, (struct sembuf *)ptr, second);
+ case SEMGET:
+ return sys_semget (first, second, third);
+ case SEMCTL: {
+ union semun fourth;
+ int err;
+ if (!ptr)
+ return -EINVAL;
+ if ((err = verify_area (VERIFY_READ, ptr, sizeof(long))))
+ return err;
+ fourth.__pad = (void *) get_fs_long(ptr);
+ return sys_semctl (first, second, third, fourth);
+ }
+ default:
+ return -EINVAL;
+ }
+ if (call <= MSGCTL)
+ switch (call) {
+ case MSGSND:
+ return sys_msgsnd (first, (struct msgbuf *) ptr,
+ second, third);
+ case MSGRCV: {
+ struct ipc_kludge tmp;
+ int err;
+ if (!ptr)
+ return -EINVAL;
+ if ((err = verify_area (VERIFY_READ, ptr, sizeof(tmp))))
+ return err;
+ memcpy_fromfs (&tmp,(struct ipc_kludge *) ptr,
+ sizeof (tmp));
+ return sys_msgrcv (first, tmp.msgp, second, tmp.msgtyp,
+ third);
+ }
+ case MSGGET:
+ return sys_msgget ((key_t) first, second);
+ case MSGCTL:
+ return sys_msgctl (first, second, (struct msqid_ds *) ptr);
+ default:
+ return -EINVAL;
+ }
+ if (call <= SHMCTL)
+ switch (call) {
+ case SHMAT:
+ return sys_shmat (first, (char *) ptr, second,
+ (ulong *) third);
+ case SHMDT:
+ return sys_shmdt ((char *)ptr);
+ case SHMGET:
+ return sys_shmget (first, second, third);
+ case SHMCTL:
+ return sys_shmctl (first, second, (struct shmid_ds *) ptr);
+ default:
+ return -EINVAL;
+ }
+ return -EINVAL;
+}
+
+#else /* not CONFIG_SYSVIPC */
+
+asmlinkage int sys_ipc (uint call, int first, int second, int third, void *ptr)
+{
+ return -ENOSYS;
+}
+
+void sem_exit (void)
+{
+ return;
+}
+
+int shm_swap (int prio)
+{
+ return 0;
+}
+
+void shm_no_page (unsigned long *ptent)
+{
+ return;
+}
+
+#endif /* CONFIG_SYSVIPC */