summaryrefslogtreecommitdiffstats
path: root/sys/compat
diff options
context:
space:
mode:
authordchagin <dchagin@FreeBSD.org>2009-05-18 04:07:46 +0000
committerdchagin <dchagin@FreeBSD.org>2009-05-18 04:07:46 +0000
commit7316b5296a8c60515aa749726e133fec1df8d8dc (patch)
treed322b4f678abeafc93996ff4856d9f8962760a22 /sys/compat
parenta501d9a071f1dfe8471bed22e728be03188465b2 (diff)
downloadFreeBSD-src-7316b5296a8c60515aa749726e133fec1df8d8dc.zip
FreeBSD-src-7316b5296a8c60515aa749726e133fec1df8d8dc.tar.gz
Implement MSG_CMSG_CLOEXEC flag for linux_recvmsg().
Approved by: kib (mentor) MFC after: 1 month
Diffstat (limited to 'sys/compat')
-rw-r--r--sys/compat/linux/linux_socket.c33
-rw-r--r--sys/compat/linux/linux_socket.h1
2 files changed, 25 insertions, 9 deletions
diff --git a/sys/compat/linux/linux_socket.c b/sys/compat/linux/linux_socket.c
index 86cbcd6..114a6d5 100644
--- a/sys/compat/linux/linux_socket.c
+++ b/sys/compat/linux/linux_socket.c
@@ -1148,7 +1148,7 @@ linux_recvmsg(struct thread *td, struct linux_recvmsg_args *args)
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 linux_recvmsg_args *args)
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);
diff --git a/sys/compat/linux/linux_socket.h b/sys/compat/linux/linux_socket.h
index 67903c5..c716f02 100644
--- a/sys/compat/linux/linux_socket.h
+++ b/sys/compat/linux/linux_socket.h
@@ -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 */
OpenPOWER on IntegriCloud