summaryrefslogtreecommitdiff
path: root/sys/compat/linux
diff options
context:
space:
mode:
authormlelstv <mlelstv@NetBSD.org>2007-02-11 08:00:59 +0000
committermlelstv <mlelstv@NetBSD.org>2007-02-11 08:00:59 +0000
commit8d08c62fcce005036a8adcf5240a42e7655e8feb (patch)
treee0fb36c777b5d3373ad90d215a49993204da3d62 /sys/compat/linux
parent6bcf70b518d18080cc815b9bc3b50f02e4d60916 (diff)
Make setsockopt return compatible error codes for AF_UNIX sockets.
Diffstat (limited to 'sys/compat/linux')
-rw-r--r--sys/compat/linux/common/linux_socket.c28
1 files changed, 26 insertions, 2 deletions
diff --git a/sys/compat/linux/common/linux_socket.c b/sys/compat/linux/common/linux_socket.c
index 014bbeab2de..9d9c04d4e8d 100644
--- a/sys/compat/linux/common/linux_socket.c
+++ b/sys/compat/linux/common/linux_socket.c
@@ -1,4 +1,4 @@
-/* $NetBSD: linux_socket.c,v 1.69 2007/02/09 21:55:19 ad Exp $ */
+/* $NetBSD: linux_socket.c,v 1.70 2007/02/11 08:00:59 mlelstv Exp $ */
/*-
* Copyright (c) 1995, 1998 The NetBSD Foundation, Inc.
@@ -42,7 +42,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: linux_socket.c,v 1.69 2007/02/09 21:55:19 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: linux_socket.c,v 1.70 2007/02/11 08:00:59 mlelstv Exp $");
#if defined(_KERNEL_OPT)
#include "opt_inet.h"
@@ -997,6 +997,7 @@ linux_sys_setsockopt(l, v, retval)
syscallarg(void *) optval;
syscallarg(int) optlen;
} */ *uap = v;
+ struct proc *p = l->l_proc;
struct sys_setsockopt_args bsa;
int name;
@@ -1005,6 +1006,29 @@ linux_sys_setsockopt(l, v, retval)
SCARG(&bsa, val) = SCARG(uap, optval);
SCARG(&bsa, valsize) = SCARG(uap, optlen);
+ /*
+ * Linux supports only SOL_SOCKET for AF_LOCAL domain sockets
+ * and returns EOPNOTSUPP for other levels
+ */
+ if (SCARG(&bsa, level) != SOL_SOCKET) {
+ struct file *fp;
+ struct socket *so;
+ int error, s, family;
+
+ /* getsock() will use the descriptor for us */
+ if ((error = getsock(p->p_fd, SCARG(&bsa, s), &fp)) != 0)
+ return error;
+
+ s = splsoftnet();
+ so = (struct socket *)fp->f_data;
+ family = so->so_proto->pr_domain->dom_family;
+ splx(s);
+ FILE_UNUSE(fp, l);
+
+ if (family == AF_LOCAL)
+ return EOPNOTSUPP;
+ }
+
switch (SCARG(&bsa, level)) {
case SOL_SOCKET:
name = linux_to_bsd_so_sockopt(SCARG(uap, optname));