+ struct file *fp, *wfp;
+ int indx, dfd, rwmode;
+
+ /*
+ * Note the horrid kludge here: u.u_r.r_val1 contains the value
+ * of the new file descriptor, which was set before the call to
+ * vn_open() by copen() in vfs_syscalls.c
+ */
+ indx = u.u_r.r_val1; /* XXX */
+ if ((unsigned)indx >= NOFILE || (fp = u.u_ofile[indx]) == NULL)
+ return (EBADF);
+ dfd = minor(dev);
+ if ((unsigned)dfd >= NOFILE || (wfp = u.u_ofile[dfd]) == NULL)
+ return (EBADF);
+ /*
+ * We must explicitly test for this case because ufalloc() may
+ * have allocated us the same file desriptor we are referring
+ * to, if the proccess referred to an invalid (closed) descriptor.
+ * Ordinarily this would be caught by the check for NULL above,
+ * but by the time we reach this routine u_pofile[minor(dev)]
+ * could already be set to point to our file struct.
+ */
+ if (fp == wfp)
+ return (EBADF);
+ /*
+ * Fake a ``dup()'' sys call.
+ * Check that the mode the file is being opened
+ * for is consistent with the mode of the existing
+ * descriptor. This isn't as clean as it should be,
+ * but this entire driver is a real kludge anyway.
+ */
+ rwmode = mode & (FREAD|FWRITE);
+ if ((fp->f_flag & rwmode) != rwmode)
+ return (EACCES);
+ /*
+ * Delete references to this pseudo-device.
+ * Note that fp->f_count is guaranteed == 1, and
+ * that fp references the vnode for this driver.
+ */
+ if (fp->f_count != 1 || fp->f_type != DTYPE_VNODE)
+ panic("fdopen");
+ vrele((struct vnode *)fp->f_data);
+ fp->f_count = 0;
+ /*
+ * Dup the file descriptor.
+ */
+ dupit(indx, wfp, u.u_pofile[dfd]);
+ return (0);