patch-2.3.35 linux/arch/sparc64/solaris/socket.c

Next file: linux/arch/sparc64/solaris/timod.c
Previous file: linux/arch/sparc64/solaris/misc.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.34/linux/arch/sparc64/solaris/socket.c linux/arch/sparc64/solaris/socket.c
@@ -1,7 +1,10 @@
-/* $Id: socket.c,v 1.1 1998/10/28 08:12:11 jj Exp $
+/* $Id: socket.c,v 1.2 1999/09/22 09:28:50 davem Exp $
  * socket.c: Socket syscall emulation for Solaris 2.6+
  *
  * Copyright (C) 1998 Jakub Jelinek (jj@ultra.linux.cz)
+ *
+ * 1999-08-19 Fixed socketpair code 
+ *            Jason Rappleye (rappleye@ccr.buffalo.edu)
  */
 
 #include <linux/types.h>
@@ -25,6 +28,18 @@
 #define SOCK_SOL_RDM		5
 #define SOCK_SOL_SEQPACKET	6
 
+#define SOL_SO_SNDLOWAT		0x1003
+#define SOL_SO_RCVLOWAT		0x1004
+#define SOL_SO_SNDTIMEO		0x1005
+#define SOL_SO_RCVTIMEO		0x1006
+#define SOL_SO_STATE		0x2000
+
+#define SOL_SS_NDELAY		0x040
+#define SOL_SS_NONBLOCK		0x080
+#define SOL_SS_ASYNC		0x100
+
+#define SO_STATE		0x000e
+
 static int socket_check(int family, int type)
 {
 	if (family != PF_UNIX && family != PF_INET)
@@ -40,6 +55,19 @@
 	return type;
 }
 
+static int solaris_to_linux_sockopt(int optname) 
+{
+	switch (optname) {
+	case SOL_SO_SNDLOWAT: optname = SO_SNDLOWAT; break;
+	case SOL_SO_RCVLOWAT: optname = SO_RCVLOWAT; break;
+	case SOL_SO_SNDTIMEO: optname = SO_SNDTIMEO; break;
+	case SOL_SO_RCVTIMEO: optname = SO_RCVTIMEO; break;
+	case SOL_SO_STATE: optname = SO_STATE; break;
+	};
+	
+	return optname;
+}
+	
 asmlinkage int solaris_socket(int family, int type, int protocol)
 {
 	int (*sys_socket)(int, int, int) =
@@ -50,14 +78,19 @@
 	return sys_socket(family, type, protocol);
 }
 
-asmlinkage int solaris_socketpair(int family, int type, int protocol, int *usockvec)
+asmlinkage int solaris_socketpair(int *usockvec)
 {
 	int (*sys_socketpair)(int, int, int, int *) =
 		(int (*)(int, int, int, int *))SYS(socketpair);
 
-	type = socket_check (family, type);
-	if (type < 0) return type;
-	return sys_socketpair(family, type, protocol, usockvec);
+	/* solaris socketpair really only takes one arg at the syscall
+	 * level, int * usockvec. The libs apparently take care of 
+	 * making sure that family==AF_UNIX and type==SOCK_STREAM. The 
+	 * pointer we really want ends up residing in the first (and
+	 * supposedly only) argument.
+	 */
+
+	return sys_socketpair(AF_UNIX, SOCK_STREAM, 0, (int *)usockvec);
 }
 
 asmlinkage int solaris_bind(int fd, struct sockaddr *addr, int addrlen)
@@ -73,6 +106,12 @@
 	int (*sunos_setsockopt)(int, int, int, u32, int) =
 		(int (*)(int, int, int, u32, int))SUNOS(105);
 
+	optname = solaris_to_linux_sockopt(optname);
+	if (optname < 0)
+		return optname;
+	if (optname == SO_STATE)
+		return 0;
+
 	return sunos_setsockopt(fd, level, optname, optval, optlen);
 }
 
@@ -80,6 +119,13 @@
 {
 	int (*sunos_getsockopt)(int, int, int, u32, u32) =
 		(int (*)(int, int, int, u32, u32))SUNOS(118);
+
+	optname = solaris_to_linux_sockopt(optname);
+	if (optname < 0)
+		return optname;
+
+	if (optname == SO_STATE)
+		optname = SOL_SO_STATE;
 
 	return sunos_getsockopt(fd, level, optname, optval, optlen);
 }

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)