Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 23 Feb 2000 16:10:11 -0800 (PST)
From:      salaman@teknos.com
To:        freebsd-gnats-submit@FreeBSD.org
Subject:   i386/16946: ServerSockets are not working properly in Linux Emulation
Message-ID:  <200002240010.QAA37762@freefall.freebsd.org>

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

>Number:         16946
>Category:       i386
>Synopsis:       ServerSockets are not working properly in Linux Emulation
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Feb 23 16:20:00 PST 2000
>Closed-Date:
>Last-Modified:
>Originator:     Victor Salaman
>Release:        4.0-Current 2/22/2000
>Organization:
TEKNOS
>Environment:
FreeBSD centaur.teknos.com 4.0-CURRENT FreeBSD 4.0-CURRENT #30: Tue Feb 22 20:59:32 AST 2000     root@centaur.teknos.com:/usr/src/sys/compile/centaur  i386

>Description:
Applications such as daemons, servers, web servers which use server sockets do not work well. Especifically Web Servers do not work at all
>How-To-Repeat:
Install Linux JDK-1.2.2 RC4
Try to use any java web server program such as ApacheJServ, Resin, Tomcat and you'll see that server sockets die.
>Fix:
--- /usr/src/sys/i386/linux/linux_file.c	Wed Feb 23 16:11:50 2000
+++ /usr/src/sys/i386/linux/linux_file.orig	Wed Feb 23 16:11:37 2000
@@ -199,6 +199,12 @@
     } */ fcntl_args; 
     struct linux_flock linux_flock;
     struct flock *bsd_flock;
+    struct filedesc *fdp;
+    struct file *fp;
+    struct vnode *vp;
+    long pgid;
+    struct pgrp *pgrp;
+    struct tty *tp;
     caddr_t sg;
     dev_t dev;
 
@@ -283,9 +289,47 @@
 
     case LINUX_F_SETOWN:
     case LINUX_F_GETOWN:
-	fcntl_args.cmd = args->cmd == LINUX_F_SETOWN ? F_SETOWN : F_GETOWN;
-	fcntl_args.arg = args->arg;
-	return fcntl(p, &fcntl_args); 
+	/*
+	 * We need to route around the normal fcntl() for these calls,
+	 * since it uses TIOC{G,S}PGRP, which is too restrictive for
+	 * Linux F_{G,S}ETOWN semantics. For sockets, this problem
+	 * does not exist.
+	 */
+	fdp = p->p_fd;
+	if ((u_int)args->fd >= fdp->fd_nfiles ||
+		(fp = fdp->fd_ofiles[args->fd]) == NULL)
+	    return EBADF;
+	if (fp->f_type == DTYPE_SOCKET) {
+	    fcntl_args.cmd = args->cmd == LINUX_F_SETOWN ? F_SETOWN : F_GETOWN;
+    	    fcntl_args.arg = args->arg;
+	    return fcntl(p, &fcntl_args); 
+	}
+	vp = (struct vnode *)fp->f_data;
+	dev = vn_todev(vp);
+	if (dev == NODEV)
+	    return EINVAL;
+	if (!(devsw(dev)->d_flags & D_TTY))
+	    return EINVAL;
+	tp = dev->si_tty;
+	if (!tp)
+	    return EINVAL;
+	if (args->cmd == LINUX_F_GETOWN) {
+	    p->p_retval[0] = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PID;
+	    return 0;
+	}
+	if ((long)args->arg <= 0) {
+	    pgid = -(long)args->arg;
+	} else {
+	    struct proc *p1 = pfind((long)args->arg);
+	    if (p1 == 0)
+		return (ESRCH);
+	    pgid = (long)p1->p_pgrp->pg_id;
+	}
+	pgrp = pgfind(pgid);
+	if (pgrp == NULL || pgrp->pg_session != p->p_session)
+	    return EPERM;
+	tp->t_pgrp = pgrp;
+	return 0;
     }
     return EINVAL;
 }
--- /usr/src/sys/i386/linux/linux_socket.c	Wed Feb 23 16:11:50 2000
+++ /usr/src/sys/i386/linux/linux_socket.orig	Wed Feb 23 16:11:48 2000
@@ -441,11 +441,6 @@
 	caddr_t name;
 	int *anamelen;
     } */ bsd_args;
-    struct fcntl_args /* {
-    int fd;
-    int cmd;
-    long arg;
-    } */ f_args;
     int error;
 
     if ((error=copyin((caddr_t)args, (caddr_t)&linux_args, sizeof(linux_args))))
@@ -453,24 +448,7 @@
     bsd_args.s = linux_args.s;
     bsd_args.name = (caddr_t)linux_args.addr;
     bsd_args.anamelen = linux_args.namelen;
-
-    if (error = oaccept(p, &bsd_args))
-	return error;
-    /*
-     * linux appears not to copy flags from the parent socket to the
-     * accepted one, so we must clear the flags in the new descriptor.
-     */
-    f_args.fd = p->p_retval[0];
-    f_args.cmd = F_SETFL;
-    f_args.arg = 0;
-   /*
-     * we ignore errors here since otherwise we would have an open file
-     * descriptor that wasn't returned to the user.
-     */
-    (void) fcntl(p, &f_args);
-    /* put the file descriptor back as the return value */
-    p->p_retval[0] = f_args.fd;
-    return 0;
+    return oaccept(p, &bsd_args);
 }
 
 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?200002240010.QAA37762>