Date: Mon, 17 Apr 1995 09:03:52 +0200 (MET DST) From: J Wunsch <j@uriah.heep.sax.de> To: freebsd-hackers@FreeBSD.org (FreeBSD hackers), andreas@knobel.gun.de (Andreas Klemm) Subject: rewindstdin Message-ID: <199504170703.JAA04291@uriah.heep.sax.de>
next in thread | raw e-mail | index | archive | help
I think the following should demonstrate a possible trick. It's something like a ``limited tee'', in that it reads a first buffer that is supposed to be sufficient for file(1) (yes, it's heuristic, you never know how many bytes file(1) will need :), forks a subprocess just feeding those bytes to file(1) (with its FD 1 dup'ed to FD 2, so the message will be distinguishable from regular data on FD 1), and continues to act like cat(1) in the parent process. j@uriah 153% cat mbox.j | ./foo | dd of=/dev/null standard input: mail text 358+1 records in 358+1 records out 183770 bytes transferred in 1 secs (183770 bytes/sec) j@uriah 154% cat /kernel | ./foo | dd of=/dev/null standard input: demand paged executable 1750+1 records in 1750+1 records out 896446 bytes transferred in 1 secs (896446 bytes/sec) I wrote it in Perl since this was easier for experimenting, but i think the idea is clear enough and as easy to implement in C, too. #!/usr/bin/perl read(STDIN, $buf, 4096) || die "Can't even read a single byte from stdin\n"; if(fork) { # XXX should handle -1 as "cannot fork" $SIG{'PIPE'} = 'exit'; # exit cleanly if file(1) closes the pipe open(STDOUT, ">&STDERR"); # a dup(2) looks a bit strange in perl, eh' :) open(FILE, "|file -"); print(FILE $buf); exit(0); } else { do { print $buf; } while(read(STDIN, $buf, 4096)); } exit(0); sub exit {exit(0);} -- cheers, J"org joerg_wunsch@uriah.heep.sax.de -- http://www.sax.de/~joerg/ Never trust an operating system you don't have sources for. ;-)
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199504170703.JAA04291>