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>
