home *** CD-ROM | disk | FTP | other *** search
- /*
- * dup.c - /dev/fd driver
- *
- * open("/dev/fd/N") is (theoretically) equivalent to dup(N).
- *
- *
- * The Ditto version of this driver was ported to SCO XENIX by
- * David J. Fiander, with several enhancements added on the way.
- * This version is _not_ in the public domain. The following
- * copyright notice now applies.
- *
- * Copyright 1992, David J. Fiander. Free distribution of
- * unmodified versions of this source is permitted.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice is duplicated in all
- * such forms and that any documentation related to such
- * distribution and use acknowlege that the software was
- * developed by David J. Fiander.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE.
- *
- * (Hey, it worked for Mark Colburn, didn't it?)
- *
- * This program was written by me, Mike "Ford" Ditto, and
- * I hereby release it into the public domain in the interest
- * of promoting the development of free, quality software
- * for the hackers and users of the world.
- *
- * Feel free to use, copy, modify, improve, and redistribute
- * this program, but please keep in mind the spirit of this
- * contribution; always provide source, and always allow
- * free redistribution (shareware is fine with me).
- *
- * -=] Ford [=-
- */
-
- #define KERNEL 1
-
- #include "sys/types.h"
- #include "sys/param.h"
- #include "sys/sysmacros.h"
- #include "sys/dir.h"
- #include "sys/signal.h"
- #include "sys/page.h"
- #include "sys/seg.h"
- #include "sys/user.h"
- #include "sys/file.h"
- #include "sys/systm.h"
- #include "sys/errno.h"
-
- void dupopen(dev, flag, id)
- register dev_t dev;
- int flag;
- int id;
- {
- register struct file *fp;
- register int fd;
-
- /* First, validate the existing fd to be duped */
- if (!(fp = getf(minor(dev))))
- return;
-
- /* Make sure we are not about to return the same fd that was requested */
- fd = u.u_rval1;
- if (minor(dev) == fd)
- {
- u.u_error = EBADF;
- return;
- }
-
- /*
- * Make sure that the flags requested are a subset of the
- * flags already open. That is make sure that the
- * intersection of the requested flags and the existing flags
- * == the requested flags
- */
- if (((fp->f_flag & (FREAD|FWRITE)) & flag) != (flag & (FREAD|FWRITE)))
- {
- u.u_error = EBADF;
- return;
- }
-
- /* Next, find (and undo) the half-open new fd */
- if (fp = getf(fd))
- {
- plock(fp->f_inode);
- iput(fp->f_inode);
- if (--fp->f_count <= 0)
- {
- fp->f_inode = NULL;
- }
- }
-
- /* Finally, dup the existing fd */
- ++(u.u_ofile[fd] = u.u_ofile[minor(dev)])->f_count;
- }
-