stuart@amc.com (Stuart Poulin) (05/24/91)
Warning: I'm new to perl. My question is how do you get perl to stop and read from /dev/tty when you have a forked process sub function that is taking its' input from STDIN. For example, say under sh I decide write a "Pager" function that prints a screen full of lines then prompts the user to hit return to get to the next screen of lines. (I'm not interested in a "Pager", I'm just using it here as an example.) I might write is as such: #!/bin/sh Pager () { PageSize=24 LineCount=1 while read i do if [ $LineCount -gt $PageSize ] if [ $LineCount -gt $PageSize ] LineCount=1 echo -n "Hit return to continue: " ( exec < /dev/tty read X ) fi echo $i LineCount=`expr $LineCount + 1 ` done } cat data | Pager #-------------------------------------------- I can then use "Pager" anywhere in the rest of the script to pump output through so it doesn't roll off the screen. Thinking along these lines I tried this perl program: #!/usr/local/bin/perl sub pager { local($pagesize,$linecount) = (24,1); open(TTYIN,"</dev/tty") || die "can't open /dev/tty: $!"; while (<>) { if ( $linecount >= $pagesize ) { print "Hit return to continue: "; $ans = <TTYIN>; print "\n" ; $linecount = 1; } print ; $linecount++ ; } close(TTYIN); } $pid = open (OUT,"|-"); if (!$pid) { &pager; exit; } else { open(INPUT,"data") || die "Cannot open data "; while(<INPUT>) { print OUT $_; } } This prints out the "Hit return to continue" messages but it doesn't wait for the return, it keeps on going. Most likely my problem is I'm not thinking in perl yet, but I'm tryin'. Thanks, Stuart Stuart Poulin DNS: stuart@amc.com Applied Microsystems Corporation UUCP: amc-gw!stuart Redmond, Washington 98073 Dial: 800-ASK-4AMC,206-882-2000
lwall@jpl-devvax.jpl.nasa.gov (Larry Wall) (05/25/91)
In article <1991May24.163027.12281@amc.com> stuart@anabol.amc.com () writes:
: Warning: I'm new to perl.
:
: My question is how do you get perl to stop and read from /dev/tty when
: you have a forked process sub function that is taking its' input from
: STDIN.
:
: For example, say under sh I decide write a "Pager" function that prints
: a screen full of lines then prompts the user to hit return to get to
: the next screen of lines.
: ...
: Thinking along these lines I tried this perl program:
:
: #!/usr/local/bin/perl
:
: sub pager {
: local($pagesize,$linecount) = (24,1);
: open(TTYIN,"</dev/tty") || die "can't open /dev/tty: $!";
: while (<>) {
: if ( $linecount >= $pagesize ) {
: print "Hit return to continue: ";
: $ans = <TTYIN>;
: print "\n" ;
: $linecount = 1;
: }
: print ;
: $linecount++ ;
: }
: close(TTYIN);
: }
:
:
: $pid = open (OUT,"|-");
: if (!$pid) {
: &pager;
: exit;
: } else {
: open(INPUT,"data") || die "Cannot open data ";
: while(<INPUT>) {
: print OUT $_;
: }
: }
:
: This prints out the "Hit return to continue" messages but it doesn't
: wait for the return, it keeps on going.
Oddly enough, it stops for me. It only needs two things to work right
here. First, $| = 1 so that the prompt comes out before it stops, and
a close OUT after the final loop so that the input process waits for
the pager process to finish.
As to why yours isn't stopping, I couldn't say. P'raps your stdio thinks
TTYIN is always at EOF for some reason. Try sysread(TTYIN, $ans, 1) and
see if it helps.
: Most likely my problem is I'm not thinking in perl yet, but I'm
: tryin'.
Looks to me like you're doin' a durn good job of thinking in Perl.
(At least, for someone from the north end of the lake...) ;-)
Larry