Subject: Re: cat(1) question: multiple "-"s
To: None <netbsd-users@netbsd.org>
From: Andrew Smallshaw <andrews@sdf.lonestar.org>
List: netbsd-users
Date: 04/18/2006 23:10:50
On Tue, Apr 18, 2006 at 03:17:11PM -0400, matthew sporleder wrote:
> 
> I think The Right Thing should be that cat will interpret many -'s as
> "output stdin where - appears"
> 
> I think the right thing is:
> 
> (file1 contains 111 and file2 contains 222)
> cat - file1 - <file2
> 
> Should print:
> 111
> 222
> 111

(I think you got your 1's and 2's crossed there, but I understand what you
mean)

This is _not_ what is supposed to happen. A - in the command line means to
get some new standard input for each occurance.  A straight 'cat - -' will
get two files from the terminal - you have to press ^D twice, and further
data can appear after the first.  An explanation of this in more depth 
really does require at least a basic knowledge of C - as an example I am
referring to some code I wrote a while back which you may find at:

http://andrews.freeshell.org/urldec.tar

We're specifically interested in the readc() function in urldec/urlenc.c.

As you can see we read from the file pointer given as a parameter until
getc() returns EOF - this indicates either an end-of-file or an error
condition which robust code really needs to distinguish between - this is
what the call to feof() achieves.  What follows is a test to see if we're
dealing with the standard input - if not, close the file as normal.  If
we are we call clearerr() to clear the EOF condition.  Note that we
_don't_ close it. 

What happens on a subsequent read of stdin depends on whether it is a
terminal or not.  A regular file will return EOF straight away, but a
terminal will be ready to receive more input until a second EOF
(simulated by pressing ^D) is entered.  So:

cat - somefile -

will spit out the first lot of input at the terminal, followed by the
contents of somefile, followed by a second lot of data from the terminal.
However:

cat - somefile - <someotherfile

will perform equivalently to 'cat someotherfile somefile'.  Since stdin
is no longer a terminal, the second attempt to read someotherfile will
immediately return EOF - ie the second "-" appears to be an empty file.

What if we wanted to programmatically (rather than interactively) have
two standard inputs?  To be honest I've never really considered it.  I
imagine something could be done with pttys, but I would guess this is
a none-trivial job.

-- 
Andrew Smallshaw
andrews@sdf.lonestar.org