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>
