summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/compat/linux/linux_socket.c21
-rw-r--r--sys/i386/linux/linux_socket.c21
2 files changed, 40 insertions, 2 deletions
diff --git a/sys/compat/linux/linux_socket.c b/sys/compat/linux/linux_socket.c
index d29efb63d8..d2be9b9 100644
--- a/sys/compat/linux/linux_socket.c
+++ b/sys/compat/linux/linux_socket.c
@@ -441,6 +441,11 @@ linux_accept(struct proc *p, struct linux_accept_args *args)
caddr_t name;
int *anamelen;
} */ bsd_args;
+ struct fcntl_args /* {
+ int fd;
+ int cmd;
+ long arg;
+ } */ f_args;
int error;
if ((error=copyin((caddr_t)args, (caddr_t)&linux_args, sizeof(linux_args))))
@@ -448,7 +453,21 @@ linux_accept(struct proc *p, struct linux_accept_args *args)
bsd_args.s = linux_args.s;
bsd_args.name = (caddr_t)linux_args.addr;
bsd_args.anamelen = linux_args.namelen;
- return oaccept(p, &bsd_args);
+ error = oaccept(p, &bsd_args);
+ if (error)
+ 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.
+ */
+ f_args.fd = p->p_retval[0];
+ f_args.cmd = F_SETFL;
+ f_args.arg = 0;
+ (void)fcntl(p, &f_args);
+ p->p_retval[0] = f_args.fd;
+ return (0);
}
struct linux_getsockname_args {
diff --git a/sys/i386/linux/linux_socket.c b/sys/i386/linux/linux_socket.c
index d29efb63d8..d2be9b9 100644
--- a/sys/i386/linux/linux_socket.c
+++ b/sys/i386/linux/linux_socket.c
@@ -441,6 +441,11 @@ linux_accept(struct proc *p, struct linux_accept_args *args)
caddr_t name;
int *anamelen;
} */ bsd_args;
+ struct fcntl_args /* {
+ int fd;
+ int cmd;
+ long arg;
+ } */ f_args;
int error;
if ((error=copyin((caddr_t)args, (caddr_t)&linux_args, sizeof(linux_args))))
@@ -448,7 +453,21 @@ linux_accept(struct proc *p, struct linux_accept_args *args)
bsd_args.s = linux_args.s;
bsd_args.name = (caddr_t)linux_args.addr;
bsd_args.anamelen = linux_args.namelen;
- return oaccept(p, &bsd_args);
+ error = oaccept(p, &bsd_args);
+ if (error)
+ 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.
+ */
+ f_args.fd = p->p_retval[0];
+ f_args.cmd = F_SETFL;
+ f_args.arg = 0;
+ (void)fcntl(p, &f_args);
+ p->p_retval[0] = f_args.fd;
+ return (0);
}
struct linux_getsockname_args {
OpenPOWER on IntegriCloud