From pb@fasterix.frmug.org  Thu Jan  8 10:36:50 1998
Received: from frmug.org (frmug-gw.frmug.org [193.56.58.252])
          by hub.freebsd.org (8.8.7/8.8.7) with ESMTP id KAA12560
          for <FreeBSD-gnats-submit@freebsd.org>; Thu, 8 Jan 1998 10:36:46 -0800 (PST)
          (envelope-from pb@fasterix.frmug.org)
Received: (from uucp@localhost)
	by frmug.org (8.8.8/frmug-2.2/nospam) with UUCP id TAA17947
	for FreeBSD-gnats-submit@freebsd.org; Thu, 8 Jan 1998 19:35:56 +0100 (CET)
	(envelope-from pb@fasterix.frmug.org)
Received: (from pb@localhost)
	by fasterix.frmug.org (8.8.8/8.8.5/pb-19970302) id TAA02446;
	Thu, 8 Jan 1998 19:31:06 +0100 (CET)
Message-Id: <199801081831.TAA02446@fasterix.frmug.org>
Date: Thu, 8 Jan 1998 19:31:06 +0100 (CET)
From: Pierre Beyssac <pb@fasterix.freenix.org>
Reply-To: pb@fasterix.freenix.org
To: FreeBSD-gnats-submit@freebsd.org
Subject: fix for connect() in the Linux emulator
X-Send-Pr-Version: 3.2

>Number:         5465
>Category:       kern
>Synopsis:       fix for connect() in the Linux emulator
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    msmith
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Jan  8 14:33:35 PST 1998
>Closed-Date:    Fri Feb 6 19:48:44 PST 1998
>Last-Modified:  Fri Feb  6 19:52:23 PST 1998
>Originator:     Pierre Beyssac
>Release:        FreeBSD 3.0-CURRENT i386
>Organization:
considered harmful
>Environment:

Linux emulator, Linux JDK 1.1.3.

>Description:

Linux connect() doesn't behave in the same way as BSD connect(),
when called several times on a non-blocking socket. BSD connect()
never returns 0 (it returns EINPROGRESS then EISCONN instead),
Linux connect() returns EINPROGESS, 0 exactly once, then EISCONN
on subsequent calls.

The effect is that connect() under the Linux JDK doesn't work.

>How-To-Repeat:

Use the appletviewer with a URL, as in:

	appletviewer http://some_site/some_applet_page.html

>Fix:

The following proposed patch fixes this:

--- linux_socket.c.orig	Wed Dec 17 21:28:59 1997
+++ linux_socket.c	Thu Jan  8 19:14:30 1998
@@ -40,4 +40,5 @@
 #include <sys/systm.h>
 #include <sys/sysproto.h>
+#include <sys/fcntl.h>
 #include <sys/socket.h>
 
@@ -342,5 +343,10 @@
 	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))))
@@ -349,5 +355,21 @@
     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;
 }
 
>Release-Note:
>Audit-Trail:
State-Changed-From-To: open->closed 
State-Changed-By: msmith 
State-Changed-When: Fri Feb 6 19:48:44 PST 1998 
State-Changed-Why:  
Updated patches were committed. 


Responsible-Changed-From-To: freebsd-bugs->msmith 
Responsible-Changed-By: msmith 
Responsible-Changed-When: Fri Feb 6 19:48:44 PST 1998 
Responsible-Changed-Why:  
I committed the changes. 
>Unformatted:
