Subject: handling flags in linux compat recvfrom and recvmsg
To: None <tech-kern@netbsd.org>
From: None <assar@netbsd.org>
List: tech-kern
Date: 12/19/2000 09:05:07
--=-=-=

Comments?

/assar

--=-=-=
Content-Disposition: attachment; filename=nld

Index: common/linux_socket.c
===================================================================
RCS file: /cvsroot/syssrc/sys/compat/linux/common/linux_socket.c,v
retrieving revision 1.25
diff -u -w -r1.25 linux_socket.c
--- common/linux_socket.c	2000/12/18 14:46:36	1.25
+++ common/linux_socket.c	2000/12/19 07:18:26
@@ -94,6 +94,7 @@
 int linux_to_bsd_ip_sockopt __P((int));
 int linux_to_bsd_tcp_sockopt __P((int));
 int linux_to_bsd_udp_sockopt __P((int));
+int linux_to_bsd_msg_flags __P((int));
 int linux_getifhwaddr __P((struct proc *, register_t *, u_int, void *));
 
 /*
@@ -133,6 +134,47 @@
 }
 
 int
+linux_to_bsd_msg_flags(flags)
+	int flags;
+{
+	int ret_flags = 0;
+
+	if (flags & LINUX_MSG_OOB)
+		ret_flags |= MSG_OOB;
+	if (flags & LINUX_MSG_PEEK)
+		ret_flags |= MSG_PEEK;
+	if (flags & LINUX_MSG_DONTROUTE)
+		ret_flags |= MSG_DONTROUTE;
+	if (flags & LINUX_MSG_CTRUNC)
+		ret_flags |= MSG_CTRUNC;
+	if (flags & LINUX_MSG_TRUNC)
+		ret_flags |= MSG_TRUNC;
+	if (flags & LINUX_MSG_DONTWAIT)
+		ret_flags |= MSG_DONTWAIT;
+	if (flags & LINUX_MSG_EOR)
+		ret_flags |= MSG_EOR;
+	if (flags & LINUX_MSG_WAITALL)
+		ret_flags |= MSG_WAITALL;
+#if 0 /* not handled */
+	if (flags & LINUX_MSG_PROXY)
+		;
+	if (flags & LINUX_MSG_FIN)
+		;
+	if (flags & LINUX_MSG_SYN)
+		;
+	if (flags & LINUX_MSG_CONFIRM)
+		;
+	if (flags & LINUX_MSG_RST)
+		;
+	if (flags & LINUX_MSG_ERRQUEUE)
+		;
+	if (flags & LINUX_MSG_NOSIGNAL)
+		;
+#endif
+	return ret_flags;
+}
+
+int
 linux_sys_socket(p, v, retval)
 	struct proc *p;
 	void *v;
@@ -222,11 +264,31 @@
 	SCARG(&bra, s) = SCARG(uap, s);
 	SCARG(&bra, buf) = SCARG(uap, buf);
 	SCARG(&bra, len) = SCARG(uap, len);
-	SCARG(&bra, flags) = SCARG(uap, flags);
+	SCARG(&bra, flags) = linux_to_bsd_msg_flags(SCARG(uap, flags));
 	SCARG(&bra, from) = (caddr_t) SCARG(uap, from);
 	SCARG(&bra, fromlenaddr) = SCARG(uap, fromlen);
 
 	return compat_43_sys_recvfrom(p, &bra, retval);
+}
+
+int
+linux_sys_recvmsg(p, v, retval)
+	struct proc *p;
+	void *v;
+	register_t *retval;
+{
+	struct linux_sys_recvmsg_args /* {
+		syscallarg(int) s;
+		syscallarg(struct msghdr *) msg;
+		syscallarg(u_int) flags;
+	} */ *uap = v;
+	struct sys_recvmsg_args bra;
+
+	SCARG(&bra, s) = SCARG(uap, s);
+	SCARG(&bra, msg) = SCARG(uap, msg);
+	SCARG(&bra, flags) = linux_to_bsd_msg_flags(SCARG(uap, flags));
+
+	return sys_recvmsg(p, &bra, retval);
 }
 
 /*
Index: common/linux_socket.h
===================================================================
RCS file: /cvsroot/syssrc/sys/compat/linux/common/linux_socket.h,v
retrieving revision 1.7
diff -u -w -r1.7 linux_socket.h
--- common/linux_socket.h	1998/12/15 19:31:40	1.7
+++ common/linux_socket.h	2000/12/19 07:18:26
@@ -123,6 +123,26 @@
 #define	LINUX_TCP_NODELAY	1
 #define	LINUX_TCP_MAXSEG	2
 
+/*
+ * msg flags in recvfrom/recvmsg 
+ */
+
+#define LINUX_MSG_OOB		0x01
+#define LINUX_MSG_PEEK		0x02
+#define LINUX_MSG_DONTROUTE	0x04
+#define LINUX_MSG_CTRUNC	0x08
+#define LINUX_MSG_PROXY		0x10
+#define LINUX_MSG_TRUNC		0x20
+#define LINUX_MSG_DONTWAIT	0x40
+#define LINUX_MSG_EOR		0x80
+#define LINUX_MSG_WAITALL	0x100
+#define LINUX_MSG_FIN		0x200
+#define LINUX_MSG_SYN		0x400
+#define LINUX_MSG_CONFIRM	0x800
+#define LINUX_MSG_RST		0x1000
+#define LINUX_MSG_ERRQUEUE	0x2000
+#define LINUX_MSG_NOSIGNAL	0x4000
+
 #if defined(__i386__)
 #include <compat/linux/arch/i386/linux_socket.h>
 #elif defined(__m68k__)
Index: common/linux_socketcall.c
===================================================================
RCS file: /cvsroot/syssrc/sys/compat/linux/common/linux_socketcall.c,v
retrieving revision 1.19
diff -u -w -r1.19 linux_socketcall.c
--- common/linux_socketcall.c	1999/03/25 04:26:45	1.19
+++ common/linux_socketcall.c	2000/12/19 07:18:26
@@ -158,7 +158,7 @@
 	case LINUX_SYS_sendmsg:
 		return sys_sendmsg(p, (void *)&lda, retval);
 	case LINUX_SYS_recvmsg:
-		return sys_recvmsg(p, (void *)&lda, retval);
+		return linux_sys_recvmsg(p, (void *)&lda, retval);
 	default:
 		return ENOSYS;
 	}
Index: common/linux_socketcall.h
===================================================================
RCS file: /cvsroot/syssrc/sys/compat/linux/common/linux_socketcall.h,v
retrieving revision 1.5
diff -u -w -r1.5 linux_socketcall.h
--- common/linux_socketcall.h	1999/03/25 04:26:45	1.5
+++ common/linux_socketcall.h	2000/12/19 07:18:26
@@ -233,6 +233,7 @@
 int linux_sys_socketpair __P((struct proc *, void *, register_t *));
 int linux_sys_sendto __P((struct proc *, void *, register_t *));
 int linux_sys_recvfrom __P((struct proc *, void *, register_t *));
+int linux_sys_recvmsg __P((struct proc *, void *, register_t *));
 int linux_sys_setsockopt __P((struct proc *, void *, register_t *));
 int linux_sys_getsockopt __P((struct proc *, void *, register_t *));
 int linux_sys_connect __P((struct proc *, void *, register_t *));

--=-=-=--