Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 18 May 2009 04:07:46 +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: r192284 - head/sys/compat/linux
Message-ID:  <200905180407.n4I47kIf048819@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: dchagin
Date: Mon May 18 04:07:46 2009
New Revision: 192284
URL: http://svn.freebsd.org/changeset/base/192284

Log:
  Implement MSG_CMSG_CLOEXEC flag for linux_recvmsg().
  
  Approved by:	kib (mentor)
  MFC after:	1 month

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

Modified: head/sys/compat/linux/linux_socket.c
==============================================================================
--- head/sys/compat/linux/linux_socket.c	Mon May 18 02:40:11 2009	(r192283)
+++ head/sys/compat/linux/linux_socket.c	Mon May 18 04:07:46 2009	(r192284)
@@ -1148,7 +1148,7 @@ linux_recvmsg(struct thread *td, struct 
 	struct mbuf **controlp;
 	caddr_t outbuf;
 	void *data;
-	int error;
+	int error, i, fd, fds, *fdp;
 
 	error = copyin(PTRIN(args->msg), &linux_msg, sizeof(linux_msg));
 	if (error)
@@ -1217,15 +1217,30 @@ linux_recvmsg(struct thread *td, struct 
 			data = CMSG_DATA(cm);
 			datalen = (caddr_t)cm + cm->cmsg_len - (caddr_t)data;
 
-			if (outlen + LINUX_CMSG_LEN(datalen) >
-			    linux_msg.msg_controllen) {
-				if (outlen == 0) {
-					error = EMSGSIZE;
-					goto bad;
-				} else {
-					linux_msg.msg_flags |= LINUX_MSG_CTRUNC;
-					goto out;
+			switch (linux_cmsg->cmsg_type)
+			{
+			case LINUX_SCM_RIGHTS:
+				if (outlen + LINUX_CMSG_LEN(datalen) >
+				    linux_msg.msg_controllen) {
+					if (outlen == 0) {
+						error = EMSGSIZE;
+						goto bad;
+					} else {
+						linux_msg.msg_flags |=
+						    LINUX_MSG_CTRUNC;
+						goto out;
+					}
+				}
+				if (args->flags & LINUX_MSG_CMSG_CLOEXEC) {
+					fds = datalen / sizeof(int);
+					fdp = data;
+					for (i = 0; i < fds; i++) {
+						fd = *fdp++;
+						(void)kern_fcntl(td, fd,
+						    F_SETFD, FD_CLOEXEC);
+					}
 				}
+				break;
 			}
 
 			linux_cmsg->cmsg_len = LINUX_CMSG_LEN(datalen);

Modified: head/sys/compat/linux/linux_socket.h
==============================================================================
--- head/sys/compat/linux/linux_socket.h	Mon May 18 02:40:11 2009	(r192283)
+++ head/sys/compat/linux/linux_socket.h	Mon May 18 04:07:46 2009	(r192284)
@@ -48,6 +48,7 @@
 #define LINUX_MSG_RST		0x1000
 #define LINUX_MSG_ERRQUEUE	0x2000
 #define LINUX_MSG_NOSIGNAL	0x4000
+#define LINUX_MSG_CMSG_CLOEXEC	0x40000000
 
 /* Socket-level control message types */
 



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