+ u.u_error = vn_lock(fp, uap->how);
+}
+
+/*
+ * File Descriptor pseudo-device driver (/dev/fd/).
+ *
+ * Fred Blonder - U of Maryland 11-Sep-1984
+ *
+ * Opening minor device N dup()s the file (if any) connected to file
+ * descriptor N belonging to the calling process. Note that this driver
+ * consists of only the ``open()'' routine, because all subsequent
+ * references to this file will be direct to the other driver.
+ */
+/* ARGSUSED */
+fdopen(dev, mode, type)
+ dev_t dev;
+ int mode, type;
+{
+ 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);