diff options
Diffstat (limited to 'net/socket.c')
| -rw-r--r-- | net/socket.c | 52 | 
1 files changed, 42 insertions, 10 deletions
diff --git a/net/socket.c b/net/socket.c index 6887840682bb..bb6a1a12fbde 100644 --- a/net/socket.c +++ b/net/socket.c @@ -504,7 +504,7 @@ static int sock_map_fd(struct socket *sock, int flags)  struct socket *sock_from_file(struct file *file)  {  	if (file->f_op == &socket_file_ops) -		return file->private_data;	/* set in sock_map_fd */ +		return file->private_data;	/* set in sock_alloc_file */  	return NULL;  } @@ -1538,11 +1538,10 @@ int sock_create_kern(struct net *net, int family, int type, int protocol, struct  }  EXPORT_SYMBOL(sock_create_kern); -int __sys_socket(int family, int type, int protocol) +static struct socket *__sys_socket_create(int family, int type, int protocol)  { -	int retval;  	struct socket *sock; -	int flags; +	int retval;  	/* Check the SOCK_* constants for consistency.  */  	BUILD_BUG_ON(SOCK_CLOEXEC != O_CLOEXEC); @@ -1550,17 +1549,50 @@ int __sys_socket(int family, int type, int protocol)  	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 | SOCK_NONBLOCK)) -		return -EINVAL; +	if ((type & ~SOCK_TYPE_MASK) & ~(SOCK_CLOEXEC | SOCK_NONBLOCK)) +		return ERR_PTR(-EINVAL);  	type &= SOCK_TYPE_MASK; +	retval = sock_create(family, type, protocol, &sock); +	if (retval < 0) +		return ERR_PTR(retval); + +	return sock; +} + +struct file *__sys_socket_file(int family, int type, int protocol) +{ +	struct socket *sock; +	struct file *file; +	int flags; + +	sock = __sys_socket_create(family, type, protocol); +	if (IS_ERR(sock)) +		return ERR_CAST(sock); + +	flags = type & ~SOCK_TYPE_MASK;  	if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK))  		flags = (flags & ~SOCK_NONBLOCK) | O_NONBLOCK; -	retval = sock_create(family, type, protocol, &sock); -	if (retval < 0) -		return retval; +	file = sock_alloc_file(sock, flags, NULL); +	if (IS_ERR(file)) +		sock_release(sock); + +	return file; +} + +int __sys_socket(int family, int type, int protocol) +{ +	struct socket *sock; +	int flags; + +	sock = __sys_socket_create(family, type, protocol); +	if (IS_ERR(sock)) +		return PTR_ERR(sock); + +	flags = type & ~SOCK_TYPE_MASK; +	if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK)) +		flags = (flags & ~SOCK_NONBLOCK) | O_NONBLOCK;  	return sock_map_fd(sock, flags & (O_CLOEXEC | O_NONBLOCK));  }  | 
