glenn@wacsvax.uwa.oz (Glenn Huxtable) (08/23/90)
While modifying a csh script (hey, I dont write them, I just fix them) I came across the following odd behaviour in csh. Can anyone expalin why it does this? More to the point, is it correct and standard? (I have only tried this on a SunOS 4.0.3 host). I wanted to look a the first line of a file (on stdin) and decide which filter to pass it to, depending on the first few characters. I thought this would be quite straight forward, use $< to read the first line, decide which filter to use then echo the line just read and cat the remaining file to the filter. Something like ... set line=$< # decide which filter (echo $line ; cat) | $FILTER this resulted in two copies of the first line. now, the csh manual says that $< can be used to read values from the keyboard, it doesnt say anything about reading from a file, however you would expect ... a simpler test is the following set first=$< set second=$< echo $first echo $second cat running this with stdin taken from the keyboard (ie. no redirect) does what you would expect, reads two lines, echos them then cats the rest back at you. running this with input redirected from a file prints the first two lines of the file, then the entire file INCLUDING the first two line. Just to make life more interesting, taking input from a pipe does the expected (ie no duplication of lines). It looks very much like csh is looking to see if stdin is a file and maintaining duplicate file pointers for itself and subsequent commands. As it turns out, this is exactly what I want, since I thought that having read the first line (in my example above) that I would have to mess around with the (echo $line; cat) subshell to get the line back intothe subsequent input stream of the filter. The question is, can I trust this is normal? If it is, someone should probably be shot! glenn ACSnet - glenn@wacsvax.uwa.oz glenn huxtable Internet - glenn@wacsvax.cs.uwa.oz.au dept of computer science phone - +61 09 380 2878 university of western australia fax - +61 09 382 1688
maart@cs.vu.nl (Maarten Litmaath) (08/23/90)
In article <glenn.651406891@bilby>, glenn@wacsvax.uwa.oz (Glenn Huxtable) writes: )... )[SunOS 4.0.3] ) ) set line=$< ) # decide which filter ) (echo $line ; cat) | $FILTER ) )this resulted in two copies of the first line. 1) The bug is in `cat': it reads the file using mmap(2), blindly assuming you want to start reading at byte offset 0. :-( Probably fixed in SunOS 4.1. You can't mmap() a pipe, so things work correctly if stdin is a pipe, as cat must use read(2) in that case. 2) Your scheme depends on csh reading the line 1 byte at a time (normally file IO is _block-buffered_); though your implicit assumption appears to be correct indeed, the manual doesn't guarantee it. :-( -- "[Your C code] seems about as portable as the Rock of Gibraltar." (Wayne Throop)