diff options
author | dchagin <dchagin@FreeBSD.org> | 2009-06-01 20:44:58 +0000 |
---|---|---|
committer | dchagin <dchagin@FreeBSD.org> | 2009-06-01 20:44:58 +0000 |
commit | 76d24c5be3b678fc63b8b3b0cd9fad664c2303ca (patch) | |
tree | d3e8395627e2c9b6e9c90b59028419a759031e1a /sys/compat/linux/linux_socket.c | |
parent | 0cc88e7ca3ae43c15437a869b4f410740d56a881 (diff) | |
download | FreeBSD-src-76d24c5be3b678fc63b8b3b0cd9fad664c2303ca.zip FreeBSD-src-76d24c5be3b678fc63b8b3b0cd9fad664c2303ca.tar.gz |
Implement a variation of the accept_common() which takes
a flags argument.
Do not preserve td_retval before kern_fcntl(F_SETFL) as it does not
changed.
Approved by: kib (mentor)
MFC after: 1 month
Diffstat (limited to 'sys/compat/linux/linux_socket.c')
-rw-r--r-- | sys/compat/linux/linux_socket.c | 35 |
1 files changed, 21 insertions, 14 deletions
diff --git a/sys/compat/linux/linux_socket.c b/sys/compat/linux/linux_socket.c index 62cfc61..176a7213 100644 --- a/sys/compat/linux/linux_socket.c +++ b/sys/compat/linux/linux_socket.c @@ -772,7 +772,10 @@ linux_accept_common(struct thread *td, int s, l_uintptr_t addr, struct sockaddr * __restrict name; socklen_t * __restrict anamelen; } */ bsd_args; - int error, fd; + int error; + + if (flags & ~(LINUX_SOCK_CLOEXEC | LINUX_SOCK_NONBLOCK)) + return (EINVAL); bsd_args.s = s; /* XXX: */ @@ -785,23 +788,27 @@ linux_accept_common(struct thread *td, int s, l_uintptr_t addr, return (EINVAL); return (error); } - if (addr) { - error = linux_sa_put(PTRIN(addr)); - if (error) { - (void)kern_close(td, td->td_retval[0]); - return (error); - } - } /* * linux appears not to copy flags from the parent socket to the - * accepted one, so we must clear the flags in the new descriptor. - * Ignore any errors, because we already have an open fd. + * accepted one, so we must clear the flags in the new descriptor + * and apply the requested flags. */ - fd = td->td_retval[0]; - (void)kern_fcntl(td, fd, F_SETFL, 0); - td->td_retval[0] = fd; - return (0); + error = kern_fcntl(td, td->td_retval[0], F_SETFL, 0); + if (error) + goto out; + error = linux_set_socket_flags(td, td->td_retval[0], flags); + if (error) + goto out; + if (addr) + error = linux_sa_put(PTRIN(addr)); + +out: + if (error) { + (void)kern_close(td, td->td_retval[0]); + td->td_retval[0] = 0; + } + return (error); } struct linux_accept_args { |