svn commit: r283490 - head/sys/compat/linux

Dmitry Chagin dchagin at FreeBSD.org
Sun May 24 18:06:13 UTC 2015


Author: dchagin
Date: Sun May 24 18:06:12 2015
New Revision: 283490
URL: https://svnweb.freebsd.org/changeset/base/283490

Log:
  Since FreeBSD supports SOCK_CLOEXEC & SOCK_NONBLOCK options
  remove its emulation via fcntl call from Linuxulator.

Modified:
  head/sys/compat/linux/linux_socket.c

Modified: head/sys/compat/linux/linux_socket.c
==============================================================================
--- head/sys/compat/linux/linux_socket.c	Sun May 24 18:05:21 2015	(r283489)
+++ head/sys/compat/linux/linux_socket.c	Sun May 24 18:06:12 2015	(r283490)
@@ -80,6 +80,7 @@ static int linux_sendmsg_common(struct t
 					l_uint);
 static int linux_recvmsg_common(struct thread *, l_int, struct l_msghdr *,
 					l_uint, struct msghdr *);
+static int linux_set_socket_flags(int, int *);
 
 /*
  * Reads a linux sockaddr and does any necessary translation.
@@ -534,20 +535,15 @@ bsd_to_linux_msghdr(const struct msghdr 
 }
 
 static int
-linux_set_socket_flags(struct thread *td, int s, int flags)
+linux_set_socket_flags(int lflags, int *flags)
 {
-	int error;
 
-	if (flags & LINUX_SOCK_NONBLOCK) {
-		error = kern_fcntl(td, s, F_SETFL, O_NONBLOCK);
-		if (error)
-			return (error);
-	}
-	if (flags & LINUX_SOCK_CLOEXEC) {
-		error = kern_fcntl(td, s, F_SETFD, FD_CLOEXEC);
-		if (error)
-			return (error);
-	}
+	if (lflags & ~(LINUX_SOCK_CLOEXEC | LINUX_SOCK_NONBLOCK))
+		return (EINVAL);
+	if (lflags & LINUX_SOCK_NONBLOCK)
+		*flags |= SOCK_NONBLOCK;
+	if (lflags & LINUX_SOCK_CLOEXEC)
+		*flags |= SOCK_CLOEXEC;
 	return (0);
 }
 
@@ -649,15 +645,16 @@ linux_socket(struct thread *td, struct l
 		int type;
 		int protocol;
 	} */ bsd_args;
-	int retval_socket, socket_flags;
+	int retval_socket;
 
 	bsd_args.protocol = args->protocol;
-	socket_flags = args->type & ~LINUX_SOCK_TYPE_MASK;
-	if (socket_flags & ~(LINUX_SOCK_CLOEXEC | LINUX_SOCK_NONBLOCK))
-		return (EINVAL);
 	bsd_args.type = args->type & LINUX_SOCK_TYPE_MASK;
 	if (bsd_args.type < 0 || bsd_args.type > LINUX_SOCK_MAX)
 		return (EINVAL);
+	retval_socket = linux_set_socket_flags(args->type & ~LINUX_SOCK_TYPE_MASK,
+		&bsd_args.type);
+	if (retval_socket != 0)
+		return (retval_socket);
 	bsd_args.domain = linux_to_bsd_domain(args->domain);
 	if (bsd_args.domain == -1)
 		return (EAFNOSUPPORT);
@@ -666,13 +663,6 @@ linux_socket(struct thread *td, struct l
 	if (retval_socket)
 		return (retval_socket);
 
-	retval_socket = linux_set_socket_flags(td, td->td_retval[0],
-	    socket_flags);
-	if (retval_socket) {
-		(void)kern_close(td, td->td_retval[0]);
-		goto out;
-	}
-
 	if (bsd_args.type == SOCK_RAW
 	    && (bsd_args.protocol == IPPROTO_RAW || bsd_args.protocol == 0)
 	    && bsd_args.domain == PF_INET) {
@@ -701,7 +691,6 @@ linux_socket(struct thread *td, struct l
 	}
 #endif
 
-out:
 	return (retval_socket);
 }
 
@@ -784,43 +773,30 @@ static int
 linux_accept_common(struct thread *td, int s, l_uintptr_t addr,
     l_uintptr_t namelen, int flags)
 {
-	struct accept_args /* {
+	struct accept4_args /* {
 		int	s;
 		struct sockaddr * __restrict name;
 		socklen_t * __restrict anamelen;
+		int	flags;
 	} */ bsd_args;
 	int error;
 
-	if (flags & ~(LINUX_SOCK_CLOEXEC | LINUX_SOCK_NONBLOCK))
-		return (EINVAL);
-
 	bsd_args.s = s;
 	/* XXX: */
 	bsd_args.name = (struct sockaddr * __restrict)PTRIN(addr);
 	bsd_args.anamelen = PTRIN(namelen);/* XXX */
-	error = sys_accept(td, &bsd_args);
+	error = linux_set_socket_flags(flags, &bsd_args.flags);
+	if (error != 0)
+		return (error);
+	error = sys_accept4(td, &bsd_args);
 	bsd_to_linux_sockaddr((struct sockaddr *)bsd_args.name);
 	if (error) {
 		if (error == EFAULT && namelen != sizeof(struct sockaddr_in))
 			return (EINVAL);
 		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
-	 * and apply the requested flags.
-	 */
-	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;
@@ -900,20 +876,18 @@ linux_socketpair(struct thread *td, stru
 		int protocol;
 		int *rsv;
 	} */ bsd_args;
-	int error, socket_flags;
-	int sv[2];
+	int error;
 
 	bsd_args.domain = linux_to_bsd_domain(args->domain);
 	if (bsd_args.domain != PF_LOCAL)
 		return (EAFNOSUPPORT);
-
-	socket_flags = args->type & ~LINUX_SOCK_TYPE_MASK;
-	if (socket_flags & ~(LINUX_SOCK_CLOEXEC | LINUX_SOCK_NONBLOCK))
-		return (EINVAL);
 	bsd_args.type = args->type & LINUX_SOCK_TYPE_MASK;
 	if (bsd_args.type < 0 || bsd_args.type > LINUX_SOCK_MAX)
 		return (EINVAL);
-
+	error = linux_set_socket_flags(args->type & ~LINUX_SOCK_TYPE_MASK,
+		&bsd_args.type);
+	if (error != 0)
+		return (error);
 	if (args->protocol != 0 && args->protocol != PF_UNIX)
 
 		/*
@@ -926,25 +900,7 @@ linux_socketpair(struct thread *td, stru
 	else
 		bsd_args.protocol = 0;
 	bsd_args.rsv = (int *)PTRIN(args->rsv);
-	error = kern_socketpair(td, bsd_args.domain, bsd_args.type,
-	    bsd_args.protocol, sv);
-	if (error)
-		return (error);
-	error = linux_set_socket_flags(td, sv[0], socket_flags);
-	if (error)
-		goto out;
-	error = linux_set_socket_flags(td, sv[1], socket_flags);
-	if (error)
-		goto out;
-
-	error = copyout(sv, bsd_args.rsv, 2 * sizeof(int));
-
-out:
-	if (error) {
-		(void)kern_close(td, sv[0]);
-		(void)kern_close(td, sv[1]);
-	}
-	return (error);
+	return (sys_socketpair(td, &bsd_args));
 }
 
 #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32))


More information about the svn-src-all mailing list