File: /usr/src/linux/arch/mips/kernel/ipc.c

1     /*
2      * linux/arch/mips/kernel/ipc.c
3      *
4      * This file contains various random system calls that
5      * have a non-standard calling sequence on the Linux/MIPS
6      * platform.
7      */
8     #include <linux/errno.h>
9     #include <linux/sched.h>
10     #include <linux/mm.h>
11     #include <linux/smp.h>
12     #include <linux/smp_lock.h>
13     #include <linux/sem.h>
14     #include <linux/msg.h>
15     #include <linux/shm.h>
16     
17     #include <asm/ipc.h>
18     #include <asm/uaccess.h>
19     
20     /*
21      * sys_ipc() is the de-multiplexer for the SysV IPC calls..
22      *
23      * This is really horribly ugly.
24      */
25     asmlinkage int sys_ipc (uint call, int first, int second,
26     			int third, void *ptr, long fifth)
27     {
28     	int version, ret;
29     
30     	version = call >> 16; /* hack for backward compatibility */
31     	call &= 0xffff;
32     
33     	switch (call) {
34     	case SEMOP:
35     		return sys_semop (first, (struct sembuf *)ptr, second);
36     	case SEMGET:
37     		return sys_semget (first, second, third);
38     	case SEMCTL: {
39     		union semun fourth;
40     		if (!ptr)
41     			return -EINVAL;
42     		if (get_user(fourth.__pad, (void **) ptr))
43     			return -EFAULT;
44     		return sys_semctl (first, second, third, fourth);
45     	}
46     
47     	case MSGSND:
48     		return sys_msgsnd (first, (struct msgbuf *) ptr, 
49     				   second, third);
50     	case MSGRCV:
51     		switch (version) {
52     		case 0: {
53     			struct ipc_kludge tmp;
54     			if (!ptr)
55     				return -EINVAL;
56     			
57     			if (copy_from_user(&tmp,
58     					   (struct ipc_kludge *) ptr, 
59     					   sizeof (tmp)))
60     				return -EFAULT;
61     			return sys_msgrcv (first, tmp.msgp, second,
62     					   tmp.msgtyp, third);
63     		}
64     		default:
65     			return sys_msgrcv (first,
66     					   (struct msgbuf *) ptr,
67     					   second, fifth, third);
68     		}
69     	case MSGGET:
70     		return sys_msgget ((key_t) first, second);
71     	case MSGCTL:
72     		return sys_msgctl (first, second, (struct msqid_ds *) ptr);
73     
74     	case SHMAT:
75     		switch (version) {
76     		default: {
77     			ulong raddr;
78     			ret = sys_shmat (first, (char *) ptr, second, &raddr);
79     			if (ret)
80     				return ret;
81     			return put_user (raddr, (ulong *) third);
82     		}
83     		case 1:	/* iBCS2 emulator entry point */
84     			if (!segment_eq(get_fs(), get_ds()))
85     				return -EINVAL;
86     			return sys_shmat (first, (char *) ptr, second, (ulong *) third);
87     		}
88     	case SHMDT: 
89     		return sys_shmdt ((char *)ptr);
90     	case SHMGET:
91     		return sys_shmget (first, second, third);
92     	case SHMCTL:
93     		return sys_shmctl (first, second,
94     				   (struct shmid_ds *) ptr);
95     	default:
96     		return -EINVAL;
97     	}
98     }
99