Module Name:    src
Committed By:   njoly
Date:           Fri May 23 12:28:51 UTC 2014

Modified Files:
        src/sys/compat/linux/common: linux_socket.c

Log Message:
Add a funtion that translate socket type value from Linux to NetBSD.
Use it for socket and socketpair syscalls.


To generate a diff of this commit:
cvs rdiff -u -r1.118 -r1.119 src/sys/compat/linux/common/linux_socket.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/compat/linux/common/linux_socket.c
diff -u src/sys/compat/linux/common/linux_socket.c:1.118 src/sys/compat/linux/common/linux_socket.c:1.119
--- src/sys/compat/linux/common/linux_socket.c:1.118	Sat May 17 21:26:20 2014
+++ src/sys/compat/linux/common/linux_socket.c	Fri May 23 12:28:51 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: linux_socket.c,v 1.118 2014/05/17 21:26:20 rmind Exp $	*/
+/*	$NetBSD: linux_socket.c,v 1.119 2014/05/23 12:28:51 njoly Exp $	*/
 
 /*-
  * Copyright (c) 1995, 1998, 2008 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: linux_socket.c,v 1.118 2014/05/17 21:26:20 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: linux_socket.c,v 1.119 2014/05/23 12:28:51 njoly Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_inet.h"
@@ -70,7 +70,6 @@ __KERNEL_RCSID(0, "$NetBSD: linux_socket
 #include <sys/kauth.h>
 #include <sys/syscallargs.h>
 #include <sys/ktrace.h>
-#include <sys/fcntl.h>
 
 #include <lib/libkern/libkern.h>
 
@@ -111,6 +110,7 @@ __KERNEL_RCSID(0, "$NetBSD: linux_socket
 
 static int linux_to_bsd_domain(int);
 static int bsd_to_linux_domain(int);
+static int linux_to_bsd_type(int);
 int linux_to_bsd_sopt_level(int);
 int linux_to_bsd_so_sockopt(int);
 int linux_to_bsd_ip_sockopt(int);
@@ -238,6 +238,27 @@ bsd_to_linux_domain(int bdom)
 }
 
 static int
+linux_to_bsd_type(int ltype)
+{
+	int type, flags;
+
+	/* Real types are identical between Linux and NetBSD */
+	type = ltype & LINUX_SOCK_TYPE_MASK;
+
+	/* But flags are not .. */
+	flags = ltype & ~LINUX_SOCK_TYPE_MASK;
+	if (flags & ~(LINUX_SOCK_CLOEXEC|LINUX_SOCK_NONBLOCK))
+		return -1;
+
+	if (flags & LINUX_SOCK_CLOEXEC)
+		type |= SOCK_CLOEXEC;
+	if (flags & LINUX_SOCK_NONBLOCK)
+		type |= SOCK_NONBLOCK;
+
+	return type;
+}
+
+static int
 linux_to_bsd_msg_flags(int lflag)
 {
 	int i, lfl, bfl;
@@ -300,16 +321,16 @@ linux_sys_socket(struct lwp *l, const st
 		syscallarg(int) protocol;
 	} */
 	struct sys___socket30_args bsa;
-	struct sys_fcntl_args fsa;
-	register_t fretval[2];
-	int error, flags;
+	int error;
 
 
 	SCARG(&bsa, protocol) = SCARG(uap, protocol);
-	SCARG(&bsa, type) = SCARG(uap, type) & LINUX_SOCK_TYPE_MASK;
 	SCARG(&bsa, domain) = linux_to_bsd_domain(SCARG(uap, domain));
 	if (SCARG(&bsa, domain) == -1)
 		return EINVAL;
+	SCARG(&bsa, type) = linux_to_bsd_type(SCARG(uap, type));
+	if (SCARG(&bsa, type) == -1)
+		return EINVAL;
 	/*
 	 * Apparently linux uses this to talk to ISDN sockets. If we fail
 	 * now programs seems to handle it, but if we don't we are going
@@ -317,36 +338,8 @@ linux_sys_socket(struct lwp *l, const st
 	 */
 	if (SCARG(&bsa, domain) == AF_ROUTE && SCARG(&bsa, type) == SOCK_RAW)
 		return ENOTSUP;
-	flags = SCARG(uap, type) & ~LINUX_SOCK_TYPE_MASK;
-	if (flags & ~(LINUX_SOCK_CLOEXEC | LINUX_SOCK_NONBLOCK))
-		return EINVAL;
 	error = sys___socket30(l, &bsa, retval);
 
-	/*
-	 * Linux overloads the "type" parameter to include some
-	 * fcntl flags to be set on the file descriptor.
-	 * Process those if creating the socket succeeded.
-	 */
-
-	if (!error && flags & LINUX_SOCK_CLOEXEC) {
-		SCARG(&fsa, fd) = *retval;
-		SCARG(&fsa, cmd) = F_SETFD;
-		SCARG(&fsa, arg) = (void *)(uintptr_t)FD_CLOEXEC;
-		(void) sys_fcntl(l, &fsa, fretval);
-	}
-	if (!error && flags & LINUX_SOCK_NONBLOCK) {
-		SCARG(&fsa, fd) = *retval;
-		SCARG(&fsa, cmd) = F_SETFL;
-		SCARG(&fsa, arg) = (void *)(uintptr_t)O_NONBLOCK;
-		error = sys_fcntl(l, &fsa, fretval);
-		if (error) {
-			struct sys_close_args csa;
-
-			SCARG(&csa, fd) = *retval;
-			(void) sys_close(l, &csa, fretval);
-		}
-	}
-
 #ifdef INET6
 	/*
 	 * Linux AF_INET6 socket has IPV6_V6ONLY setsockopt set to 0 by
@@ -385,7 +378,9 @@ linux_sys_socketpair(struct lwp *l, cons
 	SCARG(&bsa, domain) = linux_to_bsd_domain(SCARG(uap, domain));
 	if (SCARG(&bsa, domain) == -1)
 		return EINVAL;
-	SCARG(&bsa, type) = SCARG(uap, type);
+	SCARG(&bsa, type) = linux_to_bsd_type(SCARG(uap, type));
+	if (SCARG(&bsa, type) == -1)
+		return EINVAL;
 	SCARG(&bsa, protocol) = SCARG(uap, protocol);
 	SCARG(&bsa, rsv) = SCARG(uap, rsv);
 

Reply via email to