]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - net/socket.c
x86: use WARN() in arch/x86/kernel
[linux-2.6-omap-h63xx.git] / net / socket.c
index a0ce8ad722524b8290ffc6f046e66c9ab2365728..8ef8ba81b9e2048c93363f4a2f98f73b7778cdce 100644 (file)
@@ -69,6 +69,7 @@
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <linux/mutex.h>
+#include <linux/thread_info.h>
 #include <linux/wanrouter.h>
 #include <linux/if_bridge.h>
 #include <linux/if_frad.h>
@@ -264,7 +265,7 @@ static void sock_destroy_inode(struct inode *inode)
                        container_of(inode, struct socket_alloc, vfs_inode));
 }
 
-static void init_once(struct kmem_cache *cachep, void *foo)
+static void init_once(void *foo)
 {
        struct socket_alloc *ei = (struct socket_alloc *)foo;
 
@@ -368,7 +369,7 @@ static int sock_alloc_fd(struct file **filep, int flags)
        return fd;
 }
 
-static int sock_attach_fd(struct socket *sock, struct file *file)
+static int sock_attach_fd(struct socket *sock, struct file *file, int flags)
 {
        struct dentry *dentry;
        struct qstr name = { .name = "" };
@@ -390,7 +391,7 @@ static int sock_attach_fd(struct socket *sock, struct file *file)
        init_file(file, sock_mnt, dentry, FMODE_READ | FMODE_WRITE,
                  &socket_file_ops);
        SOCK_INODE(sock)->i_fop = &socket_file_ops;
-       file->f_flags = O_RDWR;
+       file->f_flags = O_RDWR | (flags & O_NONBLOCK);
        file->f_pos = 0;
        file->private_data = sock;
 
@@ -403,7 +404,7 @@ int sock_map_fd(struct socket *sock, int flags)
        int fd = sock_alloc_fd(&newfile, flags);
 
        if (likely(fd >= 0)) {
-               int err = sock_attach_fd(sock, newfile);
+               int err = sock_attach_fd(sock, newfile, flags);
 
                if (unlikely(err < 0)) {
                        put_filp(newfile);
@@ -1221,8 +1222,14 @@ asmlinkage long sys_socket(int family, int type, int protocol)
        struct socket *sock;
        int flags;
 
+       /* Check the SOCK_* constants for consistency.  */
+       BUILD_BUG_ON(SOCK_CLOEXEC != O_CLOEXEC);
+       BUILD_BUG_ON((SOCK_MAX | SOCK_TYPE_MASK) != SOCK_TYPE_MASK);
+       BUILD_BUG_ON(SOCK_CLOEXEC & SOCK_TYPE_MASK);
+       BUILD_BUG_ON(SOCK_NONBLOCK & SOCK_TYPE_MASK);
+
        flags = type & ~SOCK_TYPE_MASK;
-       if (flags & ~SOCK_CLOEXEC)
+       if (flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK))
                return -EINVAL;
        type &= SOCK_TYPE_MASK;
 
@@ -1233,7 +1240,7 @@ asmlinkage long sys_socket(int family, int type, int protocol)
        if (retval < 0)
                goto out;
 
-       retval = sock_map_fd(sock, flags & O_CLOEXEC);
+       retval = sock_map_fd(sock, flags & (O_CLOEXEC | O_NONBLOCK));
        if (retval < 0)
                goto out_release;
 
@@ -1259,7 +1266,7 @@ asmlinkage long sys_socketpair(int family, int type, int protocol,
        int flags;
 
        flags = type & ~SOCK_TYPE_MASK;
-       if (flags & ~SOCK_CLOEXEC)
+       if (flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK))
                return -EINVAL;
        type &= SOCK_TYPE_MASK;
 
@@ -1297,12 +1304,12 @@ asmlinkage long sys_socketpair(int family, int type, int protocol,
                goto out_release_both;
        }
 
-       err = sock_attach_fd(sock1, newfile1);
+       err = sock_attach_fd(sock1, newfile1, flags & O_NONBLOCK);
        if (unlikely(err < 0)) {
                goto out_fd2;
        }
 
-       err = sock_attach_fd(sock2, newfile2);
+       err = sock_attach_fd(sock2, newfile2, flags & O_NONBLOCK);
        if (unlikely(err < 0)) {
                fput(newfile1);
                goto out_fd1;
@@ -1428,7 +1435,7 @@ long do_accept(int fd, struct sockaddr __user *upeer_sockaddr,
        int err, len, newfd, fput_needed;
        struct sockaddr_storage address;
 
-       if (flags & ~SOCK_CLOEXEC)
+       if (flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK))
                return -EINVAL;
 
        if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK))
@@ -1458,7 +1465,7 @@ long do_accept(int fd, struct sockaddr __user *upeer_sockaddr,
                goto out_put;
        }
 
-       err = sock_attach_fd(newsock, newfile);
+       err = sock_attach_fd(newsock, newfile, flags & O_NONBLOCK);
        if (err < 0)
                goto out_fd_simple;
 
@@ -1504,6 +1511,7 @@ out_fd:
        goto out_put;
 }
 
+#ifdef HAVE_SET_RESTORE_SIGMASK
 asmlinkage long sys_paccept(int fd, struct sockaddr __user *upeer_sockaddr,
                            int __user *upeer_addrlen,
                            const sigset_t __user *sigmask,
@@ -1541,6 +1549,21 @@ asmlinkage long sys_paccept(int fd, struct sockaddr __user *upeer_sockaddr,
 
        return ret;
 }
+#else
+asmlinkage long sys_paccept(int fd, struct sockaddr __user *upeer_sockaddr,
+                           int __user *upeer_addrlen,
+                           const sigset_t __user *sigmask,
+                           size_t sigsetsize, int flags)
+{
+       /* The platform does not support restoring the signal mask in the
+        * return path.  So we do not allow using paccept() with a signal
+        * mask.  */
+       if (sigmask)
+               return -EINVAL;
+
+       return do_accept(fd, upeer_sockaddr, upeer_addrlen, flags);
+}
+#endif
 
 asmlinkage long sys_accept(int fd, struct sockaddr __user *upeer_sockaddr,
                           int __user *upeer_addrlen)