Hi:
 
I was wondering who mantains the Linux Emulation? I have some patches that were sent to me for FreeBSD-3.4, I have converted them to FreeBSD 4.0-Current for Linux emulation problems. Specifically anyone trying to use any program that opens a server socket will get bitten by the emulation unless these patches are applied ( JServ, Resin, Tomcat are some Java programs affected by this... and since Sun hasn't release a JDK 1.2 for FreeBSD, well, the only way to run some server programs is with Blackdown, but without these patches they are useless ).
 
Anyways, after sending email to marcel and peter with the patches, I haven't even received a reply. So therefore, I'm posting them here, in case anyone wants to commit them at all. I feel 4.0 shouldn't go out with a known broken linux emulation.
 
--- /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 {

Reply via email to