From nobody@FreeBSD.ORG  Sat Dec 18 13:25:11 1999
Return-Path: <nobody@FreeBSD.ORG>
Received: by hub.freebsd.org (Postfix, from userid 32767)
	id B102F14A2E; Sat, 18 Dec 1999 13:25:11 -0800 (PST)
Message-Id: <19991218212511.B102F14A2E@hub.freebsd.org>
Date: Sat, 18 Dec 1999 13:25:11 -0800 (PST)
From: kumabu@t3.rim.or.jp
Sender: nobody@FreeBSD.ORG
To: freebsd-gnats-submit@freebsd.org
Subject: Linux Emulation don't emulate accept(2) exactly
X-Send-Pr-Version: www-1.0

>Number:         15553
>Category:       i386
>Synopsis:       Linux Emulation don't emulate accept(2) exactly
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    marcel
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sat Dec 18 13:30:00 PST 1999
>Closed-Date:    Sun Nov 12 21:08:02 PST 2000
>Last-Modified:  Sun Nov 12 21:10:55 PST 2000
>Originator:     Shin'ya Kumabuchi
>Release:        3.1-RELEASE or above
>Organization:
>Environment:
FreeBSD blankey 3.1-RELEASE FreeBSD 3.1-RELEASE #0: Sun Jul  4 18:05:38 JST 1999     kumabu1@blankey:/usr/src/sys/compile/PAO_KUMA  i386

>Description:
Linux's accept(2) seems new socket doesn't inherit listening
socket's file flags.(though RedHat's accept(2) man describes
``creates a new socket with the same properties of s ...'')
But FreeBSD's accept(2) creates new socket with the exactly
same properties of parent. And same the Linux Emulation.
(SunOS 5.x is same, 4.x not)
So some Linux program under emulation doesn't work correctly.

>How-To-Repeat:
// simple test code in C
socket() & bind() & listen()
fcntl(sock, F_SETFL, O_NONBLOCK | fcntl(sock, F_GETFL, 0));
printf("0x%08x\n", fcntl(sock, F_GETFL));
new_sock = accept(...);
printf("0x%08x\n", fcntl(new_sock, F_GETFL));
// Linux(non emulation) blocks here, but emulation occurs EAGAIN
read(new_sock, buf, 1);

I found this in linux JDK1.2pre-v2(& 1.2.2-RC3) with emulation.
// in Java code
Socket sock = new ServerSocket(3000).accept();
// read() causes Exception on Linux Emulation,
// if no available data has received
sock.getInputStream().read();

>Fix:
I modified /sys/i386/linux/linux_socket.c(1.16) as below diff
and Linux (blackdown's)JDK works expectedly.
I don't know this is appropriate at all,
but the least O_NONBLOCK shouldn't be inherited to new socket
in Linux Emulation mode.

--- linux_socket.c.~1~	Sun Dec 19 05:39:34 1999
+++ linux_socket.c	Sun Dec 19 05:52:04 1999
@@ -43,6 +43,9 @@
 #include <sys/socket.h>
 #include <sys/uio.h>
 
+#include <sys/socketvar.h>
+#include <sys/file.h>
+
 #include <netinet/in.h>
 #include <netinet/in_systm.h>
 #include <netinet/ip.h>
@@ -448,7 +451,19 @@
     bsd_args.s = linux_args.s;
     bsd_args.name = (caddr_t)linux_args.addr;
     bsd_args.anamelen = linux_args.namelen;
+#if 0
     return oaccept(p, &bsd_args);
+#else
+    {
+	struct file *fp;
+	error = oaccept(p, &bsd_args);
+	if (!error) {
+	    getsock(p->p_fd, p->p_retval[0], &fp);
+	    fp->f_flag = O_RDWR;
+	}
+	return error;
+    }
+#endif
 }
 
 struct linux_getsockname_args {


>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->marcel 
Responsible-Changed-By: sheldonh 
Responsible-Changed-When: Mon Aug 7 07:41:01 PDT 2000 
Responsible-Changed-Why:  
Marcel, this one includes a patch. :-) 

http://www.freebsd.org/cgi/query-pr.cgi?pr=15553 
State-Changed-From-To: open->closed 
State-Changed-By: marcel 
State-Changed-When: Sun Nov 12 21:08:02 PST 2000 
State-Changed-Why:  
Problem does not exist anymore (fixed as part of PR 16946). 

http://www.freebsd.org/cgi/query-pr.cgi?pr=15553 
>Unformatted:
