Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 18 Dec 1999 13:25:11 -0800 (PST)
From:      kumabu@t3.rim.or.jp
To:        freebsd-gnats-submit@freebsd.org
Subject:   i386/15553: Linux Emulation don't emulate accept(2) exactly
Message-ID:  <19991218212511.B102F14A2E@hub.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         15553
>Category:       i386
>Synopsis:       Linux Emulation don't emulate accept(2) exactly
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sat Dec 18 13:30:00 PST 1999
>Closed-Date:
>Last-Modified:
>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:
>Unformatted:


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




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