pcg@cs.aber.ac.uk (Piercarlo Grandi) (07/26/90)
It's really bonanza time for the audience of comp.unix.i386 :-). Here enclosed you will find the source for a System V/386 implementation of the driver (originated in Unix edition 8) that allows you to name stdin stdout and stderr (and any other file descriptor for the current process) as pseudo devices in /dev, thus enabling programs that only operate on path names to be used in a pipe too. Notice that this driver will have the effect of a dup(2), not of a second open on the given file descriptor's inode. I will put here my usual disclaimer that I have forgotten to write for the parallel port driver: This work is the result of personal research activity with the use of my time, facilities, funding and resources exclusively. In no way the University College of Wales has aided or supported this work, nor supplied any funding or resources for its performance, nor it is in any way related to research or other activities of the University College of Wales. I want however to thank them for providing network access, and therefore the ability to do this posting. ------------------------ cut here -------------------------------- #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 1 (of 1)." # Contents: MANIFEST Makefile Master Name Node README System dup.c # Wrapped by su@aware on Thu Jul 26 15:14:38 1990 PATH=/bin:/usr/bin:/usr/ucb ; export PATH echo ' Copyright 1990 Piercarlo Grandi. All rights reserved. This shar archive contains free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version. As a special case, the driver contained herein may be incorporated in any OS kernel, whether the GNU General Public License applies to it or not. This driver is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You may have received a copy of the GNU General Public License along with this driver; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ' echo 4 if test -f 'README' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'README'\" else echo shar: Extracting \"'README'\" \(585 characters\) sed "s/^X//" >'README' <<'END_OF_FILE' XThis driver is a System V adaptation of an equivalent driver for 4.2BSD. XThe original idea appeared in Version 8 Unix. X XWhen a process opens minor device N of this driver it get a file descriptor Xwhich is a duplicate of its own file descriptor N, as if a dup(2) call had Xbeen effected. X XThis is most useful to make it possible to redirect to the standard input Xoutput and error streams programs that require a named file as operand. For Xexample, something like X X cp /etc/passwd /dev/stdout | wc X Xwill work as intended (this particular example may not be very useful, but Xothers are). X END_OF_FILE if test 585 -ne `wc -c <'README'`; then echo shar: \"'README'\" unpacked with wrong size! fi # end of 'README' fi if test -f 'MANIFEST' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'MANIFEST'\" else echo shar: Extracting \"'MANIFEST'\" \(362 characters\) sed "s/^X//" >'MANIFEST' <<'END_OF_FILE' X File Name Archive # Description X----------------------------------------------------------- X MANIFEST 1 This shipping list X Makefile 1 X Master 1 X Name 1 X Node 1 X README 1 X System 1 X dup.c 1 END_OF_FILE if test 362 -ne `wc -c <'MANIFEST'`; then echo shar: \"'MANIFEST'\" unpacked with wrong size! fi # end of 'MANIFEST' fi if test -f 'Makefile' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Makefile'\" else echo shar: Extracting \"'Makefile'\" \(171 characters\) sed "s/^X//" >'Makefile' <<'END_OF_FILE' XCONF =/etc/conf/bin/ XCC =cc XCFLAGS =-O -DINKERNEL X XDriver.o: dup.o; ln $? $@ X Xinstall: Driver.o Master System Node Name X $(CONF)idinstall -keu dup X $(CONF)idmknod -s END_OF_FILE if test 171 -ne `wc -c <'Makefile'`; then echo shar: \"'Makefile'\" unpacked with wrong size! fi # end of 'Makefile' fi if test -f 'Master' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Master'\" else echo shar: Extracting \"'Master'\" \(26 characters\) sed "s/^X//" >'Master' <<'END_OF_FILE' Xdup o cio dup 0 55 1 1 -1 END_OF_FILE if test 26 -ne `wc -c <'Master'`; then echo shar: \"'Master'\" unpacked with wrong size! fi # end of 'Master' fi if test -f 'Name' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Name'\" else echo shar: Extracting \"'Name'\" \(40 characters\) sed "s/^X//" >'Name' <<'END_OF_FILE' Xdup File descriptor dup(2) clone driver END_OF_FILE if test 40 -ne `wc -c <'Name'`; then echo shar: \"'Name'\" unpacked with wrong size! fi # end of 'Name' fi if test -f 'Node' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Node'\" else echo shar: Extracting \"'Node'\" \(44 characters\) sed "s/^X//" >'Node' <<'END_OF_FILE' Xdup stdin c 0 Xdup stdout c 1 Xdup stderr c 2 END_OF_FILE if test 44 -ne `wc -c <'Node'`; then echo shar: \"'Node'\" unpacked with wrong size! fi # end of 'Node' fi if test -f 'System' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'System'\" else echo shar: Extracting \"'System'\" \(22 characters\) sed "s/^X//" >'System' <<'END_OF_FILE' Xdup Y 1 0 0 0 0 0 0 0 END_OF_FILE if test 22 -ne `wc -c <'System'`; then echo shar: \"'System'\" unpacked with wrong size! fi # end of 'System' fi if test -f 'dup.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'dup.c'\" else echo shar: Extracting \"'dup.c'\" \(3118 characters\) sed "s/^X//" >'dup.c' <<'END_OF_FILE' X/* X $Header: /aware0/src/dup/dup.c,v 1.2 90/07/26 12:55:44 sw Exp $ X*/ X X#include <sys/param.h> X#include <sys/types.h> X#include <sys/sysmacros.h> X#include <sys/dir.h> X#include <sys/file.h> X#include <sys/inode.h> X#include <sys/signal.h> X#include <sys/errno.h> X#include <sys/user.h> X X/* X 4.2 BSD pseudo-device driver for the "fd" device. An attempt to X open this device returns a file descriptor which is a "duplicate" X of the open file descriptor corresponding to the minor device X number of the particular filedesc device opened. For example, the X device /dev/stdin is a fd device with minor device 0. Opening X /dev/stdin returns a duplicate of file descriptor 0, equivalent to X fd(0). The open mode must be the same as the mode of the file X descriptor being duplicated, except that a read/write file X descriptor can be duped for just read or just write. X X The idea of "/dev/stdin" originated in Bell Labs UNIX 8th Edition X (research version 8) and was described by Rob Pike at the Summer X 1985 Usenix Conference in Portland. We use the names X "/dev/stdin", "/dev/stdout", and "/dev/stderr" for minor devices X 0,1, and 2, as well as the names "/dev/fdXX" for XX ranging from 0 X to NOFILE-1. The protection mode of the device inodes should be X 0666. X X "fd" driver written 16-Jun-85 by Darwyn Peachey, Computer Science X Research Lab, University of Saskatchewan, Saskatoon, Canada S7N X 0W0 Phone: (306) 966-4909 UUCP: ihnp4!sask!kimnovax!peachey X X Suitably adapted to System V/386 rel. 3.2 by Piercarlo Grandi, X July 1990. Name changed to "dup" to avoid conflict with the X floppy disc driver. X*/ X Xdupopen(dev,mode) X dev_t dev; X int mode; X{ X register int fd,oldfd; X register struct file *fp,*oldfp; X X /* X Here we rely on the current file descriptor being still in X u.u_r.r_val1, where it has been put by openi() to be returned X to the user as the result of the open(2) call. Horrible kludge. X */ X X /* X The current file descriptor must be valid. X */ X X fd = u.u_r.r_reg.r_val1; X if (fd < 0 || fd >= NOFILE) /* something terrible has happened */ X return EINVAL; X X /* X The old file descriptor must be valid and different from the X current one. X */ X X oldfd = minor(dev); X if (oldfd < 0 || oldfd >= NOFILE || fd == oldfd) X return EBADF; X X /* X The old file descriptor must point to some file struct, and the X old open mode must be a superset of the current one. X */ X X oldfp = u.u_ofile[oldfd]; X if (oldfp == NULL) X return EBADF; X X if ((mode & (oldfp->f_flag & (FREAD|FWRITE))) != (mode & (FREAD|FWRITE))) X return EACCES; X X /* X The current file pointer can now be thrown away. X */ X X fp = u.u_ofile[fd]; X if (fp != NULL) /* otherwise something terrible has happened */ X { X u.u_ofile[fd] = NULL; X if (fp->f_inode) iput(fp->f_inode); X fp->f_count = 0; X } X X /* X The old file pointer becomes the current one as well. X */ X X u.u_pofile[fd] = u.u_pofile[oldfd]; X (u.u_ofile[fd] = oldfp)->f_count++; X X return 0; X} END_OF_FILE if test 3118 -ne `wc -c <'dup.c'`; then echo shar: \"'dup.c'\" unpacked with wrong size! fi # end of 'dup.c' fi echo shar: End of archive 1 \(of 1\). cp /dev/null ark1isdone MISSING="" for I in 1 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have the archive. rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0 -- Piercarlo "Peter" Grandi | ARPA: pcg%cs.aber.ac.uk@nsfnet-relay.ac.uk Dept of CS, UCW Aberystwyth | UUCP: ...!mcsun!ukc!aber-cs!pcg Penglais, Aberystwyth SY23 3BZ, UK | INET: pcg@cs.aber.ac.uk