Back to home page

LXR

 
 

    


0001 /*
0002  * sys_ipc() is the old de-multiplexer for the SysV IPC calls.
0003  *
0004  * This is really horribly ugly, and new architectures should just wire up
0005  * the individual syscalls instead.
0006  */
0007 #include <linux/unistd.h>
0008 
0009 #ifdef __ARCH_WANT_SYS_IPC
0010 #include <linux/errno.h>
0011 #include <linux/ipc.h>
0012 #include <linux/shm.h>
0013 #include <linux/syscalls.h>
0014 #include <linux/uaccess.h>
0015 
0016 SYSCALL_DEFINE6(ipc, unsigned int, call, int, first, unsigned long, second,
0017         unsigned long, third, void __user *, ptr, long, fifth)
0018 {
0019     int version, ret;
0020 
0021     version = call >> 16; /* hack for backward compatibility */
0022     call &= 0xffff;
0023 
0024     switch (call) {
0025     case SEMOP:
0026         return sys_semtimedop(first, (struct sembuf __user *)ptr,
0027                       second, NULL);
0028     case SEMTIMEDOP:
0029         return sys_semtimedop(first, (struct sembuf __user *)ptr,
0030                       second,
0031                       (const struct timespec __user *)fifth);
0032 
0033     case SEMGET:
0034         return sys_semget(first, second, third);
0035     case SEMCTL: {
0036         unsigned long arg;
0037         if (!ptr)
0038             return -EINVAL;
0039         if (get_user(arg, (unsigned long __user *) ptr))
0040             return -EFAULT;
0041         return sys_semctl(first, second, third, arg);
0042     }
0043 
0044     case MSGSND:
0045         return sys_msgsnd(first, (struct msgbuf __user *) ptr,
0046                   second, third);
0047     case MSGRCV:
0048         switch (version) {
0049         case 0: {
0050             struct ipc_kludge tmp;
0051             if (!ptr)
0052                 return -EINVAL;
0053 
0054             if (copy_from_user(&tmp,
0055                        (struct ipc_kludge __user *) ptr,
0056                        sizeof(tmp)))
0057                 return -EFAULT;
0058             return sys_msgrcv(first, tmp.msgp, second,
0059                        tmp.msgtyp, third);
0060         }
0061         default:
0062             return sys_msgrcv(first,
0063                        (struct msgbuf __user *) ptr,
0064                        second, fifth, third);
0065         }
0066     case MSGGET:
0067         return sys_msgget((key_t) first, second);
0068     case MSGCTL:
0069         return sys_msgctl(first, second, (struct msqid_ds __user *)ptr);
0070 
0071     case SHMAT:
0072         switch (version) {
0073         default: {
0074             unsigned long raddr;
0075             ret = do_shmat(first, (char __user *)ptr,
0076                        second, &raddr, SHMLBA);
0077             if (ret)
0078                 return ret;
0079             return put_user(raddr, (unsigned long __user *) third);
0080         }
0081         case 1:
0082             /*
0083              * This was the entry point for kernel-originating calls
0084              * from iBCS2 in 2.2 days.
0085              */
0086             return -EINVAL;
0087         }
0088     case SHMDT:
0089         return sys_shmdt((char __user *)ptr);
0090     case SHMGET:
0091         return sys_shmget(first, second, third);
0092     case SHMCTL:
0093         return sys_shmctl(first, second,
0094                    (struct shmid_ds __user *) ptr);
0095     default:
0096         return -ENOSYS;
0097     }
0098 }
0099 #endif