[comp.lang.perl] select/stdio interaction and $| = 2 -- a suggestion

kjpires@sting.Berkeley.EDU (Kurt J. Pires) (08/16/90)

I have a bunch of network client programs that need to use select to
do input and output.  Things work OK except when input from a terminal
is too fast (like an X cut and paste).  What happens is that stdio
grabs all the characters it can get when I do a read(STDIN, $input, 1),
which would be fine if I wasn't using select on that emptied descriptor.

So, either perl's select should know that there is outstanding data
in its internal buffers, or there needs to be a way to setbuf(fp, NULL).

The most efficient solution would be the first, because buffering
could still be done, but it might be hard to do.  For the latter
solution, you could generalize the $| as I/O flags and use $| = 2
to mean setbuf(fp, NULL) (and $| = 3 mean both use IOF_FLUSH
and setbuf(fp, NULL)).

Included below is a stripped example of the type of I/O I do on STDIN.
Try cutting and pasting about 2 or 3 characters of a single line (no \n's).

Kurt

#!/usr/local/bin/perl

select(STDIN); $| = 1; select(STDOUT); $| = 1;

$SIG{'INT'} = 'quit';
system '/bin/stty', '-echo', 'cbreak';

# Setup the Input Select Mask
$input_mask = '';
vec($input_mask, fileno(STDIN), 1) = 1;

print "Hit Control-C to exit>";

while (1) {
	$nfound = select($read_mask = $input_mask, undef, undef, undef);

	if (vec($read_mask, fileno(STDIN), 1)) {
		read(STDIN, $input, 1) == 1 || do quit();
		print $input;
	}
}

sub quit {
	system '/bin/stty', 'echo', 'cooked';
	exit;
}