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