+++ /dev/null
-Upstream-Status: Backport
-
-From 53d09b761f032f50c4424e8649396a9041070bae Mon Sep 17 00:00:00 2001
-From: "Edgar E. Iglesias" <edgar.iglesias@gmail.com>
-Date: Mon, 23 Sep 2013 14:11:53 +0200
-Subject: [PATCH] linux-user: Handle SOCK_CLOEXEC/NONBLOCK if unavailable on
- host
-
-If the host lacks SOCK_CLOEXEC, bail out with -EINVAL.
-If the host lacks SOCK_ONONBLOCK, try to emulate it with fcntl()
-and O_NONBLOCK.
-
-Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
-Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
----
- linux-user/syscall.c | 40 +++++++++++++++++++++++++++++++++++++---
- 1 file changed, 37 insertions(+), 3 deletions(-)
-
-diff --git a/linux-user/syscall.c b/linux-user/syscall.c
-index b3822b3..4a14a43 100644
---- a/linux-user/syscall.c
-+++ b/linux-user/syscall.c
-@@ -1773,7 +1773,7 @@ static void unlock_iovec(struct iovec *vec, abi_ulong target_addr,
- free(vec);
- }
-
--static inline void target_to_host_sock_type(int *type)
-+static inline int target_to_host_sock_type(int *type)
- {
- int host_type = 0;
- int target_type = *type;
-@@ -1790,22 +1790,56 @@ static inline void target_to_host_sock_type(int *type)
- break;
- }
- if (target_type & TARGET_SOCK_CLOEXEC) {
-+#if defined(SOCK_CLOEXEC)
- host_type |= SOCK_CLOEXEC;
-+#else
-+ return -TARGET_EINVAL;
-+#endif
- }
- if (target_type & TARGET_SOCK_NONBLOCK) {
-+#if defined(SOCK_NONBLOCK)
- host_type |= SOCK_NONBLOCK;
-+#elif !defined(O_NONBLOCK)
-+ return -TARGET_EINVAL;
-+#endif
- }
- *type = host_type;
-+ return 0;
-+}
-+
-+/* Try to emulate socket type flags after socket creation. */
-+static int sock_flags_fixup(int fd, int target_type)
-+{
-+#if !defined(SOCK_NONBLOCK) && defined(O_NONBLOCK)
-+ if (target_type & TARGET_SOCK_NONBLOCK) {
-+ int flags = fcntl(fd, F_GETFL);
-+ if (fcntl(fd, F_SETFL, O_NONBLOCK | flags) == -1) {
-+ close(fd);
-+ return -TARGET_EINVAL;
-+ }
-+ }
-+#endif
-+ return fd;
- }
-
- /* do_socket() Must return target values and target errnos. */
- static abi_long do_socket(int domain, int type, int protocol)
- {
-- target_to_host_sock_type(&type);
-+ int target_type = type;
-+ int ret;
-+
-+ ret = target_to_host_sock_type(&type);
-+ if (ret) {
-+ return ret;
-+ }
-
- if (domain == PF_NETLINK)
- return -EAFNOSUPPORT; /* do not NETLINK socket connections possible */
-- return get_errno(socket(domain, type, protocol));
-+ ret = get_errno(socket(domain, type, protocol));
-+ if (ret >= 0) {
-+ ret = sock_flags_fixup(ret, target_type);
-+ }
-+ return ret;
- }
-
- /* do_bind() Must return target values and target errnos. */
---
-1.8.2.1