|
@@ -349,11 +349,11 @@ static struct dentry_operations sockfs_dentry_operations = {
|
|
* but we take care of internal coherence yet.
|
|
* but we take care of internal coherence yet.
|
|
*/
|
|
*/
|
|
|
|
|
|
-static int sock_alloc_fd(struct file **filep)
|
|
|
|
|
|
+static int sock_alloc_fd(struct file **filep, int flags)
|
|
{
|
|
{
|
|
int fd;
|
|
int fd;
|
|
|
|
|
|
- fd = get_unused_fd();
|
|
|
|
|
|
+ fd = get_unused_fd_flags(flags);
|
|
if (likely(fd >= 0)) {
|
|
if (likely(fd >= 0)) {
|
|
struct file *file = get_empty_filp();
|
|
struct file *file = get_empty_filp();
|
|
|
|
|
|
@@ -396,10 +396,10 @@ static int sock_attach_fd(struct socket *sock, struct file *file)
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
-int sock_map_fd(struct socket *sock)
|
|
|
|
|
|
+int sock_map_fd(struct socket *sock, int flags)
|
|
{
|
|
{
|
|
struct file *newfile;
|
|
struct file *newfile;
|
|
- int fd = sock_alloc_fd(&newfile);
|
|
|
|
|
|
+ int fd = sock_alloc_fd(&newfile, flags);
|
|
|
|
|
|
if (likely(fd >= 0)) {
|
|
if (likely(fd >= 0)) {
|
|
int err = sock_attach_fd(sock, newfile);
|
|
int err = sock_attach_fd(sock, newfile);
|
|
@@ -1218,12 +1218,18 @@ asmlinkage long sys_socket(int family, int type, int protocol)
|
|
{
|
|
{
|
|
int retval;
|
|
int retval;
|
|
struct socket *sock;
|
|
struct socket *sock;
|
|
|
|
+ int flags;
|
|
|
|
+
|
|
|
|
+ flags = type & ~SOCK_TYPE_MASK;
|
|
|
|
+ if (flags & ~SOCK_CLOEXEC)
|
|
|
|
+ return -EINVAL;
|
|
|
|
+ type &= SOCK_TYPE_MASK;
|
|
|
|
|
|
retval = sock_create(family, type, protocol, &sock);
|
|
retval = sock_create(family, type, protocol, &sock);
|
|
if (retval < 0)
|
|
if (retval < 0)
|
|
goto out;
|
|
goto out;
|
|
|
|
|
|
- retval = sock_map_fd(sock);
|
|
|
|
|
|
+ retval = sock_map_fd(sock, flags & O_CLOEXEC);
|
|
if (retval < 0)
|
|
if (retval < 0)
|
|
goto out_release;
|
|
goto out_release;
|
|
|
|
|
|
@@ -1246,6 +1252,12 @@ asmlinkage long sys_socketpair(int family, int type, int protocol,
|
|
struct socket *sock1, *sock2;
|
|
struct socket *sock1, *sock2;
|
|
int fd1, fd2, err;
|
|
int fd1, fd2, err;
|
|
struct file *newfile1, *newfile2;
|
|
struct file *newfile1, *newfile2;
|
|
|
|
+ int flags;
|
|
|
|
+
|
|
|
|
+ flags = type & ~SOCK_TYPE_MASK;
|
|
|
|
+ if (flags & ~SOCK_CLOEXEC)
|
|
|
|
+ return -EINVAL;
|
|
|
|
+ type &= SOCK_TYPE_MASK;
|
|
|
|
|
|
/*
|
|
/*
|
|
* Obtain the first socket and check if the underlying protocol
|
|
* Obtain the first socket and check if the underlying protocol
|
|
@@ -1264,13 +1276,13 @@ asmlinkage long sys_socketpair(int family, int type, int protocol,
|
|
if (err < 0)
|
|
if (err < 0)
|
|
goto out_release_both;
|
|
goto out_release_both;
|
|
|
|
|
|
- fd1 = sock_alloc_fd(&newfile1);
|
|
|
|
|
|
+ fd1 = sock_alloc_fd(&newfile1, flags & O_CLOEXEC);
|
|
if (unlikely(fd1 < 0)) {
|
|
if (unlikely(fd1 < 0)) {
|
|
err = fd1;
|
|
err = fd1;
|
|
goto out_release_both;
|
|
goto out_release_both;
|
|
}
|
|
}
|
|
|
|
|
|
- fd2 = sock_alloc_fd(&newfile2);
|
|
|
|
|
|
+ fd2 = sock_alloc_fd(&newfile2, flags & O_CLOEXEC);
|
|
if (unlikely(fd2 < 0)) {
|
|
if (unlikely(fd2 < 0)) {
|
|
err = fd2;
|
|
err = fd2;
|
|
put_filp(newfile1);
|
|
put_filp(newfile1);
|
|
@@ -1426,7 +1438,7 @@ asmlinkage long sys_accept(int fd, struct sockaddr __user *upeer_sockaddr,
|
|
*/
|
|
*/
|
|
__module_get(newsock->ops->owner);
|
|
__module_get(newsock->ops->owner);
|
|
|
|
|
|
- newfd = sock_alloc_fd(&newfile);
|
|
|
|
|
|
+ newfd = sock_alloc_fd(&newfile, 0);
|
|
if (unlikely(newfd < 0)) {
|
|
if (unlikely(newfd < 0)) {
|
|
err = newfd;
|
|
err = newfd;
|
|
sock_release(newsock);
|
|
sock_release(newsock);
|