[net.sources] 2dpipe - implement 2 dimensional sh

rossc@metro.oz (Ross Cartlidge) (10/23/86)

#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create:
#	README
#	2dpipe.1
#	2dpipe.mk
#	2dpipe.sh
# This archive created: Thu Oct 23 11:12:53 1986
export PATH; PATH=/bin:/usr/bin:$PATH
if test -f 'README'
then
	echo shar: "will not over-write existing file 'README'"
else
cat << \SHAR_EOF > 'README'
This archive contains three files:-
	- this README
	- the shell script 2dpipe.sh
	- the manual entry 2dpipe.1
	- the makefile 2dpipe.mk

They describe and implement a method
for constructing two-dimensional pipelines
of commands. See the manual entry for a more
detailed explanation.

To install the command and the manual entries
modify 2dpipe.mk to your local environment
and type
	make -f 2dpipe.mk
SHAR_EOF
fi
if test -f '2dpipe.1'
then
	echo shar: "will not over-write existing file '2dpipe.1'"
else
cat << \SHAR_EOF > '2dpipe.1'
.TH 2DPIPE 1
.SH NAME
0, 1, 2 \- create two-dimensional pipelines.
.SH SYNOPSIS
.B 0
pipeline
.br
.B 1
pipeline
.br
.B 2
pipeline
.SH DESCRIPTION
Each of these commands
executes the
.I pipeline
asynchronously,
redirecting the file descriptor
of the same name to a named pipe.
The output of the command is the name of the pipe created.
The pipe is removed on termination.
.P
The commands can be used to implement
a two-dimensional pipeline of commands
composed from the one-dimensional pipelines
possible in
.IR sh (1).
Pipelines are joined
by commands
which have
input files as arguments
and split
by commands
which have
output files as arguments.
This is done by 
replacing the
file argument by the grave accented execution(see 
command substitution in
.IR sh (1))
of the required pipeline by
.B 0
for splitting and
.B 1
for joining.
.SH EXAMPLES
To print the common lines between two unsorted files, 
.IR f1 " and " f2
.P
.RS
comm -12 \(ga1 sort f1\(ga \(ga1 sort f2\(ga
.RE
.P
To view a full directory listing
of a directory
.I dir
.P
.RS
vi \(ga1 ls -lR dir\(ga
.RE
.P
To view the compilation errors of
.I t.c
.P
.RS
vi \(ga2 cc -S t.c\(ga
.RE
.P
Write out the
list of all group name and gid pairs
which have a corresponding user name and uid pair
sorted by name and then by number into
.I name_order
and 
.I number_order
respectively.
.P
.RS
comm -12 \(ga1 \(aacut -f1,3 -d: /etc/passwd | sort\(aa\(ga \e
.br
\(ga1 \(aacut -f1,3 -d: /etc/group | sort\(aa\(ga |
.br
tee \(ga0 \(aasort +0 -t: > name_order\(aa\(ga | sort +1n -t: > number_order
.RE
.SH FILES
/tmp/fifo$$
.SH WARNING
If the pipeline to be executed has
characters special to the shell these
must be escaped.
If
.IR lseek (2)
is attempted on the pipe the process will fail.
It is quite heavy on processes so one may reach
a user process limit on complex pipes.
If the named pipe is not read or written
in 20 seconds the pipe is removed.
This is to avoid pipes from hanging around
indefinitely if a command never accesses
its file argument.
.SH SEE ALSO
sh(1), tee(1), lseek(2).
SHAR_EOF
fi
if test -f '2dpipe.mk'
then
	echo shar: "will not over-write existing file '2dpipe.mk'"
else
cat << \SHAR_EOF > '2dpipe.mk'
INSDIR=/usr/local
MANDIR=/usr/man/l_man/man1
CATDIR=/usr/catman/l_man/man1

install: cmd man
cmd: 
	cp 2dpipe.sh $(INSDIR)/0
	-ln $(INSDIR)/0 $(INSDIR)/1
	-ln $(INSDIR)/0 $(INSDIR)/2
	chmod 755 $(INSDIR)/[012]
	chown bin $(INSDIR)/[012]
	chgrp bin $(INSDIR)/[012]

man:
	cp 2dpipe.1 $(MANDIR)
	chmod 644 $(MANDIR)/2dpipe.1
	chown bin $(MANDIR)/2dpipe.1
	chgrp bin $(MANDIR)/2dpipe.1
	nroff -man -Tlp 2dpipe.1 > /tmp/2dpipe.1
	-rm /tmp/2dpipe.1.z
	pack /tmp/2dpipe.1
	mv /tmp/2dpipe.1.z $(CATDIR)
	chmod 644 $(CATDIR)/2dpipe.1.z
	chown bin $(CATDIR)/2dpipe.1.z
	chgrp bin $(CATDIR)/2dpipe.1.z
SHAR_EOF
fi
if test -f '2dpipe.sh'
then
	echo shar: "will not over-write existing file '2dpipe.sh'"
else
cat << \SHAR_EOF > '2dpipe.sh'
trap '' 1 2 3
dead_timeout=20
case $0
in
	0)	r1="$0>";r2="$0<";;
	1|2)	r1="$0<";r2="$0>";;
esac
fifo=/tmp/fifo$$
mknod $fifo p 
echo $fifo
exec >&-
(
	trap 'reader_end=1' 15
	reader_end=
	sleep $dead_timeout&
	wait
	trap '' 15
	kill $!
	if [ -z "$reader_end" ]
	then
		eval : $r1 $fifo
	fi
	rm -f $fifo
) 2> /dev/null &
cleanup=$!
(
	(eval "$@" $r2 $fifo; exit 0) || eval : $r2 $fifo
	kill $cleanup 2> /dev/null
) &
SHAR_EOF
chmod +x '2dpipe.sh'
fi
exit 0
#	End of shell archive