Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 31 May 2009 12:16:32 +0000 (UTC)
From:      Dmitry Chagin <dchagin@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r193168 - head/sys/compat/linux
Message-ID:  <200905311216.n4VCGWwP042919@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: dchagin
Date: Sun May 31 12:16:31 2009
New Revision: 193168
URL: http://svn.freebsd.org/changeset/base/193168

Log:
  Implement a variation of the socketpair() syscall which takes a flags
  in addition to the type argument.
  
  Approved by:	kib (mentor)
  MFC after:	1 month

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 31 12:12:38 2009	(r193167)
+++ head/sys/compat/linux/linux_socket.c	Sun May 31 12:16:31 2009	(r193168)
@@ -884,12 +884,20 @@ linux_socketpair(struct thread *td, stru
 		int protocol;
 		int *rsv;
 	} */ bsd_args;
+	int error, socket_flags;
+	int sv[2];
 
 	bsd_args.domain = linux_to_bsd_domain(args->domain);
 	if (bsd_args.domain != PF_LOCAL)
 		return (EAFNOSUPPORT);
 
-	bsd_args.type = args->type;
+	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);
+
 	if (args->protocol != 0 && args->protocol != PF_UNIX)
 
 		/*
@@ -902,7 +910,25 @@ linux_socketpair(struct thread *td, stru
 	else
 		bsd_args.protocol = 0;
 	bsd_args.rsv = (int *)PTRIN(args->rsv);
-	return (socketpair(td, &bsd_args));
+	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);
 }
 
 struct linux_send_args {



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200905311216.n4VCGWwP042919>