home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Source Code 1992 March
/
Source_Code_CD-ROM_Walnut_Creek_March_1992.iso
/
usenet
/
altsrcs
/
1
/
1626
/
dup.c
next >
Wrap
C/C++ Source or Header
|
1990-12-28
|
3KB
|
106 lines
/*
$Header: /aware0/src/dup/dup.c,v 1.2 90/07/26 12:55:44 sw Exp $
*/
#include <sys/param.h>
#include <sys/types.h>
#include <sys/sysmacros.h>
#include <sys/dir.h>
#include <sys/file.h>
#include <sys/inode.h>
#include <sys/signal.h>
#include <sys/errno.h>
#include <sys/user.h>
/*
4.2 BSD pseudo-device driver for the "fd" device. An attempt to
open this device returns a file descriptor which is a "duplicate"
of the open file descriptor corresponding to the minor device
number of the particular filedesc device opened. For example, the
device /dev/stdin is a fd device with minor device 0. Opening
/dev/stdin returns a duplicate of file descriptor 0, equivalent to
fd(0). The open mode must be the same as the mode of the file
descriptor being duplicated, except that a read/write file
descriptor can be duped for just read or just write.
The idea of "/dev/stdin" originated in Bell Labs UNIX 8th Edition
(research version 8) and was described by Rob Pike at the Summer
1985 Usenix Conference in Portland. We use the names
"/dev/stdin", "/dev/stdout", and "/dev/stderr" for minor devices
0,1, and 2, as well as the names "/dev/fdXX" for XX ranging from 0
to NOFILE-1. The protection mode of the device inodes should be
0666.
"fd" driver written 16-Jun-85 by Darwyn Peachey, Computer Science
Research Lab, University of Saskatchewan, Saskatoon, Canada S7N
0W0 Phone: (306) 966-4909 UUCP: ihnp4!sask!kimnovax!peachey
Suitably adapted to System V/386 rel. 3.2 by Piercarlo Grandi,
July 1990. Name changed to "dup" to avoid conflict with the
floppy disc driver.
*/
dupopen(dev,mode)
dev_t dev;
int mode;
{
register int fd,oldfd;
register struct file *fp,*oldfp;
/*
Here we rely on the current file descriptor being still in
u.u_r.r_val1, where it has been put by openi() to be returned
to the user as the result of the open(2) call. Horrible kludge.
*/
/*
The current file descriptor must be valid.
*/
fd = u.u_r.r_reg.r_val1;
if (fd < 0 || fd >= NOFILE) /* something terrible has happened */
return EINVAL;
/*
The old file descriptor must be valid and different from the
current one.
*/
oldfd = minor(dev);
if (oldfd < 0 || oldfd >= NOFILE || fd == oldfd)
return EBADF;
/*
The old file descriptor must point to some file struct, and the
old open mode must be a superset of the current one.
*/
oldfp = u.u_ofile[oldfd];
if (oldfp == NULL)
return EBADF;
if ((mode & (oldfp->f_flag & (FREAD|FWRITE))) != (mode & (FREAD|FWRITE)))
return EACCES;
/*
The current file pointer can now be thrown away.
*/
fp = u.u_ofile[fd];
if (fp != NULL) /* otherwise something terrible has happened */
{
u.u_ofile[fd] = NULL;
if (fp->f_inode) iput(fp->f_inode);
fp->f_count = 0;
}
/*
The old file pointer becomes the current one as well.
*/
u.u_pofile[fd] = u.u_pofile[oldfd];
(u.u_ofile[fd] = oldfp)->f_count++;
return 0;
}