Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!usc!elroy.jpl.nasa.gov!jpl-devvax!lwall From: lwall@jpl-devvax.jpl.nasa.gov (Larry Wall) Newsgroups: comp.lang.perl Subject: Re: pager pipes Message-ID: <1991May10.164705.24432@jpl-devvax.jpl.nasa.gov> Date: 10 May 91 16:47:05 GMT References: <1991Feb16.210445.7760@convex.com> Reply-To: lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) Organization: Jet Propulsion Laboratory, Pasadena, CA Lines: 36 In article <1991Feb16.210445.7760@convex.com> tchrist@convex.COM (Tom Christiansen) writes: : I was trying to set up an automatic pager for STDOUT, and : it doesn't seem to work. If I choose a different handle, : it's fine. Any clues? : : $pager = $ENV{'PAGER'} || 'more'; : open(STDOUT, "| $pager") || die "can't reopen STDOUT to $pager: $!"; : open(STDERR, ">&PIPE") || die "dup failed: $!"; : system 'ps t'; : system 'grep nada nonesuch'; : while (<>) { print; } : close(STDOUT) || die "close failed: $!"; : : Notice that I never die of a bad dup even though there is no : PIPE handle. If you %s/STDOUT/PIPE/g and add an appropriate : select, it all works fine. This is under both 3.044 and 4.0beta. The problem is that open(STDOUT, "| $pager") implicitly closes STDOUT before calling mypopen() to run $pager, so the pager has no standard output. It's not exactly a bug, nor is it exactly a misfeature, but it's enough of a violation of expectations that I think it's worth special casing, along with the corresponding STDIN behavior. Basically it comes down to this: you have to call pipe() before you fork(), so the only two ways to make sure the pipe is attached to the right fd are 1) close the fd first, or 2) close the fd later and dup2 the pipe onto it. A similar situation holds with open(STDERR, ">&PIPE") || die "dup failed: $!"; in which STDERR is closed before the dup is attempted, so the die dies without a whimper. I s'pose that needs some TLC too. Larry