Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/compat/linux/common update linux_sys_socket() to underst...
details: https://anonhg.NetBSD.org/src/rev/7b4d93df145e
branches: trunk
changeset: 758339:7b4d93df145e
user: chs <chs%NetBSD.org@localhost>
date: Tue Nov 02 18:02:59 2010 +0000
description:
update linux_sys_socket() to understand the flags that are now
included in the "type" parameter. in linux_sys_sendmsg(),
if we see an SCM_CREDENTIALS control message, just drop it
instead of giving an error. the linux and native versions of
the cred-passing operation are very different and some apps
(eg. linux pulseaudio library talking to a native server)
will work without the control data.
diffstat:
sys/compat/linux/common/linux_socket.c | 54 ++++++++++++++++++++++++++++++---
sys/compat/linux/common/linux_socket.h | 13 +++++++-
2 files changed, 60 insertions(+), 7 deletions(-)
diffs (155 lines):
diff -r ee96d0a5129a -r 7b4d93df145e sys/compat/linux/common/linux_socket.c
--- a/sys/compat/linux/common/linux_socket.c Tue Nov 02 18:01:25 2010 +0000
+++ b/sys/compat/linux/common/linux_socket.c Tue Nov 02 18:02:59 2010 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: linux_socket.c,v 1.107 2009/11/28 22:11:42 dsl Exp $ */
+/* $NetBSD: linux_socket.c,v 1.108 2010/11/02 18:02:59 chs 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.107 2009/11/28 22:11:42 dsl Exp $");
+__KERNEL_RCSID(0, "$NetBSD: linux_socket.c,v 1.108 2010/11/02 18:02:59 chs Exp $");
#if defined(_KERNEL_OPT)
#include "opt_inet.h"
@@ -70,6 +70,7 @@
#include <sys/kauth.h>
#include <sys/syscallargs.h>
#include <sys/ktrace.h>
+#include <sys/fcntl.h>
#include <lib/libkern/libkern.h>
@@ -84,6 +85,7 @@
#include <compat/linux/common/linux_signal.h>
#include <compat/linux/common/linux_ioctl.h>
#include <compat/linux/common/linux_socket.h>
+#include <compat/linux/common/linux_fcntl.h>
#if !defined(__alpha__) && !defined(__amd64__)
#include <compat/linux/common/linux_socketcall.h>
#endif
@@ -200,13 +202,13 @@
{MSG_DONTWAIT, LINUX_MSG_DONTWAIT},
{MSG_BCAST, 0}, /* not supported, clear */
{MSG_MCAST, 0}, /* not supported, clear */
+ {MSG_NOSIGNAL, LINUX_MSG_NOSIGNAL},
{-1, /* not supp */ LINUX_MSG_PROBE},
{-1, /* not supp */ LINUX_MSG_FIN},
{-1, /* not supp */ LINUX_MSG_SYN},
{-1, /* not supp */ LINUX_MSG_CONFIRM},
{-1, /* not supp */ LINUX_MSG_RST},
{-1, /* not supp */ LINUX_MSG_ERRQUEUE},
- {-1, /* not supp */ LINUX_MSG_NOSIGNAL},
{-1, /* not supp */ LINUX_MSG_MORE},
};
@@ -297,15 +299,46 @@
syscallarg(int) protocol;
} */
struct sys___socket30_args bsa;
- int error;
+ struct sys_fcntl_args fsa;
+ register_t fretval[2];
+ int error, flags;
+
SCARG(&bsa, protocol) = SCARG(uap, protocol);
- SCARG(&bsa, type) = SCARG(uap, type);
+ 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;
+ 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
@@ -505,6 +538,14 @@
/* Linux SCM_RIGHTS is same as NetBSD */
break;
+ case LINUX_SCM_CREDENTIALS:
+ /* no native equivalent, just drop it */
+ m_free(ctl_mbuf);
+ ctl_mbuf = NULL;
+ msg.msg_control = NULL;
+ msg.msg_controllen = 0;
+ goto skipcmsg;
+
default:
/* other types not supported */
error = EINVAL;
@@ -545,7 +586,7 @@
cmsg->cmsg_level = l_cmsg.cmsg_level;
cmsg->cmsg_type = l_cmsg.cmsg_type;
- /* Zero are between header and data */
+ /* Zero area between header and data */
memset(cmsg + 1, 0,
CMSG_ALIGN(sizeof(cmsg)) - sizeof(cmsg));
@@ -575,6 +616,7 @@
msg.msg_controllen);
}
+skipcmsg:
error = do_sys_sendmsg(l, SCARG(uap, s), &msg, bflags, retval);
/* Freed internally */
ctl_mbuf = NULL;
diff -r ee96d0a5129a -r 7b4d93df145e sys/compat/linux/common/linux_socket.h
--- a/sys/compat/linux/common/linux_socket.h Tue Nov 02 18:01:25 2010 +0000
+++ b/sys/compat/linux/common/linux_socket.h Tue Nov 02 18:02:59 2010 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: linux_socket.h,v 1.19 2009/11/28 22:11:42 dsl Exp $ */
+/* $NetBSD: linux_socket.h,v 1.20 2010/11/02 18:03:00 chs Exp $ */
/*-
* Copyright (c) 1995, 1998 The NetBSD Foundation, Inc.
@@ -216,4 +216,15 @@
#error Undefined linux_socket.h machine type.
#endif
+/*
+ * Flags for socket().
+ * These are provided in the "type" parameter.
+ */
+
+#define LINUX_SOCK_TYPE_MASK 0xf
+#define LINUX_SOCK_CLOEXEC LINUX_O_CLOEXEC
+#ifndef LINUX_SOCK_NONBLOCK
+#define LINUX_SOCK_NONBLOCK LINUX_O_NONBLOCK
+#endif
+
#endif /* !_LINUX_SOCKET_H */
Home |
Main Index |
Thread Index |
Old Index