Blame view

ipc/syscall.c 2.32 KB
baed7fc9b   Christoph Hellwig   Add generic sys_i...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
  /*
   * sys_ipc() is the old de-multiplexer for the SysV IPC calls.
   *
   * This is really horribly ugly, and new architectures should just wire up
   * the individual syscalls instead.
   */
  #include <linux/unistd.h>
  
  #ifdef __ARCH_WANT_SYS_IPC
  #include <linux/errno.h>
  #include <linux/ipc.h>
  #include <linux/shm.h>
  #include <linux/syscalls.h>
  #include <linux/uaccess.h>
45575f5a4   Anton Blanchard   ppc64 sys_ipc bre...
15
  SYSCALL_DEFINE6(ipc, unsigned int, call, int, first, unsigned long, second,
baed7fc9b   Christoph Hellwig   Add generic sys_i...
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
  		unsigned long, third, void __user *, ptr, long, fifth)
  {
  	int version, ret;
  
  	version = call >> 16; /* hack for backward compatibility */
  	call &= 0xffff;
  
  	switch (call) {
  	case SEMOP:
  		return sys_semtimedop(first, (struct sembuf __user *)ptr,
  				      second, NULL);
  	case SEMTIMEDOP:
  		return sys_semtimedop(first, (struct sembuf __user *)ptr,
  				      second,
  				      (const struct timespec __user *)fifth);
  
  	case SEMGET:
  		return sys_semget(first, second, third);
  	case SEMCTL: {
  		union semun fourth;
  		if (!ptr)
  			return -EINVAL;
  		if (get_user(fourth.__pad, (void __user * __user *) ptr))
  			return -EFAULT;
  		return sys_semctl(first, second, third, fourth);
  	}
  
  	case MSGSND:
  		return sys_msgsnd(first, (struct msgbuf __user *) ptr,
  				  second, third);
  	case MSGRCV:
  		switch (version) {
  		case 0: {
  			struct ipc_kludge tmp;
  			if (!ptr)
  				return -EINVAL;
  
  			if (copy_from_user(&tmp,
  					   (struct ipc_kludge __user *) ptr,
  					   sizeof(tmp)))
  				return -EFAULT;
  			return sys_msgrcv(first, tmp.msgp, second,
  					   tmp.msgtyp, third);
  		}
  		default:
  			return sys_msgrcv(first,
  					   (struct msgbuf __user *) ptr,
  					   second, fifth, third);
  		}
  	case MSGGET:
  		return sys_msgget((key_t) first, second);
  	case MSGCTL:
  		return sys_msgctl(first, second, (struct msqid_ds __user *)ptr);
  
  	case SHMAT:
  		switch (version) {
  		default: {
  			unsigned long raddr;
  			ret = do_shmat(first, (char __user *)ptr,
  				       second, &raddr);
  			if (ret)
  				return ret;
  			return put_user(raddr, (unsigned long __user *) third);
  		}
  		case 1:
  			/*
  			 * This was the entry point for kernel-originating calls
  			 * from iBCS2 in 2.2 days.
  			 */
  			return -EINVAL;
  		}
  	case SHMDT:
  		return sys_shmdt((char __user *)ptr);
  	case SHMGET:
  		return sys_shmget(first, second, third);
  	case SHMCTL:
  		return sys_shmctl(first, second,
  				   (struct shmid_ds __user *) ptr);
  	default:
  		return -ENOSYS;
  	}
  }
  #endif