home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.sources.unix
- From: xenitec!golem!davidf@uunet.ca (David J. Fiander)
- Subject: v26i087: dup - a /dev/fd driver for Xenix/386 2.3+, Part01/01
- Sender: unix-sources-moderator@pa.dec.com
- Approved: vixie@pa.dec.com
-
- Submitted-By: xenitec!golem!davidf@uunet.ca (David J. Fiander)
- Posting-Number: Volume 26, Issue 87
- Archive-Name: dup/part01
-
- [ This source is particular to SCO Xenix/386 2.3+. If you don't have that,
- you probably don't want this. I don't have it, so I didn't test this.
- --vix ]
-
- The /dev/fd driver effectively allows you to specify an already-open file
- descriptor number where a path name is normally required. This allows a
- program that demands a path name to be used to process standard input or
- standard output by specifying /dev/fd/0 or /dev/fd/1, respectively.
-
- xenitec!golem!davidf@uunet.ca (David J. Fiander)
-
- #! /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: Install MANIFEST Makefile README dup.c
- # Wrapped by vixie@cognition.pa.dec.com on Sat Jan 30 17:03:06 1993
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'Install' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'Install'\"
- else
- echo shar: Extracting \"'Install'\" \(931 characters\)
- sed "s/^X//" >'Install' <<'END_OF_FILE'
- MODULE=dup
- make ${MODULE}.o || exit # Don't bother with anything if we can't make.
- X
- NOFILE=20 # Do we really need more?
- X
- set -e
- X
- cd /usr/sys/conf
- X
- X[ -d /dev/fd ] && [ -c /dev/stdin ] ||
- X{
- X echo 'Making files in /dev'
- X major=`./configure -j NEXTMAJOR`
- X
- X echo 'The major device number for the /dev/fd driver is' $major
- X
- X echo 'Adding "../io/dup/dup.o" to link_xenix'
- X ed - ./link_xenix <<\SCRIPT
- X/uts.o/a
- X ../io/dup/dup.o \
- X.
- w
- q
- SCRIPT
- X
- X echo 'Updating master and xenixconf files'
- X ./configure -c -m $major -a dupopen
- X
- X rm -rf /dev/fd /dev/stdin /dev/stdout /dev/stderr
- X mkdir /dev/fd
- X chmod 755 /dev/fd
- X minor=0
- X while [ $minor -lt $NOFILE ]
- X do
- X mknod /dev/fd/$minor c $major $minor
- X chmod 666 /dev/fd/$minor
- X minor=`expr $minor + 1`
- X done
- X ln -f /dev/fd/0 /dev/stdin
- X ln -f /dev/fd/1 /dev/stdout
- X ln -f /dev/fd/2 /dev/stderr
- X}
- X
- echo 'Building new xenix'
- X./link_xenix
- X
- echo 'You must now install the new xenix in / and reboot'
- END_OF_FILE
- if test 931 -ne `wc -c <'Install'`; then
- echo shar: \"'Install'\" unpacked with wrong size!
- fi
- # end of 'Install'
- fi
- if test -f 'MANIFEST' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'MANIFEST'\"
- else
- echo shar: Extracting \"'MANIFEST'\" \(251 characters\)
- sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
- X File Name Archive # Description
- X-----------------------------------------------------------
- X Install 1
- X MANIFEST 1
- X Makefile 1
- X README 1
- X dup.c 1
- END_OF_FILE
- if test 251 -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'\" \(93 characters\)
- sed "s/^X//" >'Makefile' <<'END_OF_FILE'
- CFLAGS= -O -DXENIX -DM_KERNEL -M3e -Zp4 -I/usr/sys/h
- X
- dup.o: dup.c
- X $(CC) $(CFLAGS) -c dup.c
- END_OF_FILE
- if test 93 -ne `wc -c <'Makefile'`; then
- echo shar: \"'Makefile'\" unpacked with wrong size!
- fi
- # end of 'Makefile'
- fi
- if test -f 'README' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'README'\"
- else
- echo shar: Extracting \"'README'\" \(1777 characters\)
- sed "s/^X//" >'README' <<'END_OF_FILE'
- The Source
- X----------
- X
- This /dev/fd driver is loosely based on one written by Mike
- X"Ford" Ditto for the AT&T UNIX pc. This version runs on SCO
- XXENIX 386, version 2.3+. The install script included will
- configure the kernel, edit /usr/sys/conf/link_xenix, and build
- the new kernel and device files in /dev/fd.
- X
- Building the driver
- X-------------------
- X
- To properly build everything, move the Makefile, dup.c and
- Install script into a new directory called /usr/sys/io/dup, and
- run make in that directory. Then run Install.
- X
- What /dev/fd is
- X---------------
- The /dev/fd driver effectively allows you to specify an already-open
- file descriptor number where a path name is normally required. This
- allows a program that demands a path name to be used to process
- standard input or standard output by specifying /dev/fd/0 or /dev/fd/1,
- respectively.
- X
- X/dev/stdin and /dev/sdtout are links to the respective entries in
- X/dev/fd/.
- X
- This is primarily useful when running a poorly-written program that
- has no provision for using stdin/stdout. For example:
- X
- X find . -cpio /dev/stdout | compress > /dev/rfp021
- X
- X(The "-cpio" option of the "find" command demands a file name and
- normally can not write to standard output. This example gives it
- the name "/dev/stdout" allowing it to be piped directly to compress
- rather than writing to a temporary file.)
- X
- Note that some programs which demand a file name do so because
- they must lseek(2) on the file, and thus will not work if told
- to process stdin and stdin is a pipe.
- X
- The most common use for the /dev/fd driver that I have found is
- for "process substitution" under the shell rc, and those
- versions of the Korn shell that support it. For example, to
- use jove's "parse-error-file" function, you could say
- X
- X ; jove -p <{egrep -n funcName *.c}
- END_OF_FILE
- if test 1777 -ne `wc -c <'README'`; then
- echo shar: \"'README'\" unpacked with wrong size!
- fi
- # end of 'README'
- 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'\" \(2750 characters\)
- sed "s/^X//" >'dup.c' <<'END_OF_FILE'
- X/*
- X * dup.c - /dev/fd driver
- X *
- X * open("/dev/fd/N") is (theoretically) equivalent to dup(N).
- X *
- X *
- X * The Ditto version of this driver was ported to SCO XENIX by
- X * David J. Fiander, with several enhancements added on the way.
- X * This version is _not_ in the public domain. The following
- X * copyright notice now applies.
- X *
- X * Copyright 1992, David J. Fiander. Free distribution of
- X * unmodified versions of this source is permitted.
- X *
- X * Redistribution and use in source and binary forms are permitted
- X * provided that the above copyright notice is duplicated in all
- X * such forms and that any documentation related to such
- X * distribution and use acknowlege that the software was
- X * developed by David J. Fiander.
- X *
- X * THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
- X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- X * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
- X * PURPOSE.
- X *
- X * (Hey, it worked for Mark Colburn, didn't it?)
- X *
- X * This program was written by me, Mike "Ford" Ditto, and
- X * I hereby release it into the public domain in the interest
- X * of promoting the development of free, quality software
- X * for the hackers and users of the world.
- X *
- X * Feel free to use, copy, modify, improve, and redistribute
- X * this program, but please keep in mind the spirit of this
- X * contribution; always provide source, and always allow
- X * free redistribution (shareware is fine with me).
- X *
- X * -=] Ford [=-
- X */
- X
- X#define KERNEL 1
- X
- X#include "sys/types.h"
- X#include "sys/param.h"
- X#include "sys/sysmacros.h"
- X#include "sys/dir.h"
- X#include "sys/signal.h"
- X#include "sys/page.h"
- X#include "sys/seg.h"
- X#include "sys/user.h"
- X#include "sys/file.h"
- X#include "sys/systm.h"
- X#include "sys/errno.h"
- X
- void dupopen(dev, flag, id)
- register dev_t dev;
- int flag;
- int id;
- X{
- X register struct file *fp;
- X register int fd;
- X
- X /* First, validate the existing fd to be duped */
- X if (!(fp = getf(minor(dev))))
- X return;
- X
- X /* Make sure we are not about to return the same fd that was requested */
- X fd = u.u_rval1;
- X if (minor(dev) == fd)
- X {
- X u.u_error = EBADF;
- X return;
- X }
- X
- X /*
- X * Make sure that the flags requested are a subset of the
- X * flags already open. That is make sure that the
- X * intersection of the requested flags and the existing flags
- X * == the requested flags
- X */
- X if (((fp->f_flag & (FREAD|FWRITE)) & flag) != (flag & (FREAD|FWRITE)))
- X {
- X u.u_error = EBADF;
- X return;
- X }
- X
- X /* Next, find (and undo) the half-open new fd */
- X if (fp = getf(fd))
- X {
- X plock(fp->f_inode);
- X iput(fp->f_inode);
- X if (--fp->f_count <= 0)
- X {
- X fp->f_inode = NULL;
- X }
- X }
- X
- X /* Finally, dup the existing fd */
- X ++(u.u_ofile[fd] = u.u_ofile[minor(dev)])->f_count;
- X}
- END_OF_FILE
- if test 2750 -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
-