From owner-freebsd-hackers Mon Apr 17 00:11:58 1995 Return-Path: hackers-owner Received: (from majordom@localhost) by freefall.cdrom.com (8.6.10/8.6.6) id AAA09164 for hackers-outgoing; Mon, 17 Apr 1995 00:11:58 -0700 Received: from irz301.inf.tu-dresden.de (irz301.inf.tu-dresden.de [141.76.1.11]) by freefall.cdrom.com (8.6.10/8.6.6) with SMTP id AAA09145 for ; Mon, 17 Apr 1995 00:11:44 -0700 Received: from sax.sax.de by irz301.inf.tu-dresden.de with SMTP (5.67b+/DEC-Ultrix/4.3) id AA26743; Mon, 17 Apr 1995 09:10:41 +0200 Received: by sax.sax.de (8.6.12/8.6.12-s1) with UUCP id JAA19037; Mon, 17 Apr 1995 09:10:41 +0200 Received: (from j@localhost) by uriah.heep.sax.de (8.6.11/8.6.9) id JAA04291; Mon, 17 Apr 1995 09:03:52 +0200 From: J Wunsch Message-Id: <199504170703.JAA04291@uriah.heep.sax.de> Subject: rewindstdin To: freebsd-hackers@FreeBSD.org (FreeBSD hackers), andreas@knobel.gun.de (Andreas Klemm) Date: Mon, 17 Apr 1995 09:03:52 +0200 (MET DST) Reply-To: joerg_wunsch@uriah.heep.sax.de (Joerg Wunsch) X-Phone: +49-351-2012 669 X-Mailer: ELM [version 2.4 PL23] Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 8bit Content-Length: 1570 Sender: hackers-owner@FreeBSD.org Precedence: bulk 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. ;-)