Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 9 Jan 1998 02:13:25 +0100
From:      pb@fasterix.freenix.org (Pierre Beyssac)
To:        emulation@freebsd.org
Subject:   fixes for the Linuxulator
Message-ID:  <19980109021325.KI01385@@>
In-Reply-To: <34B57A18.6F5C@asme.org>; from Pedro Giffuni on Jan 8, 1998 17:15:04 -0800
References:  <199801070630.RAA00809@word.smith.net.au> <199801081734.KAA19855@harmony.village.org> <19980108195521.OO22099@@> <34B57A18.6F5C@asme.org>

next in thread | previous in thread | raw e-mail | index | archive | help
The notifications for my PRs have arrived (thanks Steve and Pedro!),
these are PR kern/5464 and kern/5465.

Mike, the patch I included with kern/5464 covers only TCP options
in setsockopt(), I forgot to patch for getsockopt(), please don't
commit it. I post here the complete patch for both PRs as it's not
very long.

I haven't actually tested the patch to the getsockopt() part, but
it doesn't seem to break anything I ran.

I also had a look at the OpenBSD code, they seem to correct the
connect() bug by calling getsockopt with SO_ERROR and returning
the error they got, if any, instead of the EISCONN error... They
don't check the socket is non blocking before doing that, though.
I haven't had time to test this under FreeBSD yet.

--- linux_socket.c.orig	Wed Dec 17 21:28:59 1997
+++ linux_socket.c	Fri Jan  9 01:48:37 1998
@@ -39,6 +39,7 @@
 #include <sys/proc.h>
 #include <sys/systm.h>
 #include <sys/sysproto.h>
+#include <sys/fcntl.h>
 #include <sys/socket.h>
 
 #include <netinet/in.h>
@@ -341,14 +342,35 @@
 	caddr_t name;
 	int namelen;
     } */ bsd_args;
-    int error;
+    struct  fcntl_args /* {
+	int fd;
+	int cmd;
+	int arg;
+    } */ bsd_fcntl_args;
+    int error, err_fcntl;
 
     if ((error=copyin((caddr_t)args, (caddr_t)&linux_args, sizeof(linux_args))))
 	return error;
     bsd_args.s = linux_args.s;
     bsd_args.name = (caddr_t)linux_args.name;
     bsd_args.namelen = linux_args.namelen;
-    return connect(p, &bsd_args);
+    error = connect(p, &bsd_args);
+    if (error == EISCONN) {
+	/*
+	 * Linux doesn't return EISCONN the first time it occurs,
+	 * when on a non-blocking socket. We simply ignore it all
+	 * the time if O_NONBLOCK is set; that's not entirely correct.
+	 */
+	bsd_fcntl_args.fd = linux_args.s;
+	bsd_fcntl_args.cmd = F_GETFL;
+	bsd_fcntl_args.arg = 0;
+	err_fcntl = fcntl(p, &bsd_fcntl_args);
+	if (err_fcntl == 0 && (p->p_retval[0] & O_NONBLOCK)) {
+	    error = 0;
+	    p->p_retval[0] = 0;
+	}
+    }
+    return error;
 }
 
 struct linux_listen_args {
@@ -661,6 +683,10 @@
     case IPPROTO_IP:
 	name = linux_to_bsd_ip_sockopt(linux_args.optname);
 	break;
+    case IPPROTO_TCP:
+	/* Linux TCP option values match BSD's */
+	name = linux_args.optname;
+	break;
     default:
 	return EINVAL;
     }
@@ -703,6 +729,10 @@
 	break;
     case IPPROTO_IP:
 	name = linux_to_bsd_ip_sockopt(linux_args.optname);
+	break;
+    case IPPROTO_TCP:
+	/* Linux TCP option values match BSD's */
+	name = linux_args.optname;
 	break;
     default:
 	return EINVAL;

-- 
Pierre Beyssac	      pb@fasterix.frmug.org pb@fasterix.freenix.org
{Free,Net,Open}BSD, Linux : il y a moins bien, mais c'est plus cher
    Free domains: http://www.eu.org/ or mail dns-manager@EU.org



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?19980109021325.KI01385>