Back to Blog

ipc消息队列系统函数调用源码入口:如sys_msgsnd

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