List Info

Thread: readline on non-blocking file handles




readline on non-blocking file handles
user name
2007-09-21 16:03:57
I mentioned this on IRC today with little response.

I was pretty surprised by the way readline behaves for
non-blocking file handles. All I'd like to know is if this
behaviour is by design (and documented somewhere) or if
it's rather a bug.

Here's the code:

  use feature ':5.10';
  use IO::File;
  use IO::Select;

  my $prog = qq/ $^X -e '$|++; while (1) { print
"x"; sleep 2 }' /;

  my $fh = IO::File->new("$prog |") or die
"$prog: $!n";
  $fh->blocking(0);

  my $io = IO::Select->new([$fh]);

  while (1) {
    if ($io->can_read(1)) {
      my $read = <$fh> // 'undef';
      say "$. = $. : read '$read'";
    }
    else { say "nope..." }
  }

  __END__

  mhxr2d2 ~ $ bleadperl test.pl
  $. = 1 : read 'x'
  nope...
  nope...
  $. = 2 : read 'x'
  nope...
  nope...
  $. = 3 : read 'x'
  nope...
  $. = 4 : read 'x'
  nope...

I would have expected readline to return 'undef' for as
long
as it doesn't see $/ in the input stream. (In the above
case,
that would be forever.) After all, this is called
read*line*,
but it's only returning characters.

Even more strange is the behaviour of $., which simply
increments
with each character that is read (or, to be exact, with
each
successful call readline).

Looking at the code, all this makes perfect sense.
sv_gets()
calls PerlIO_getc() until $/ or EOF is found. In case of a
non-blocking file handle, PerlIO_getc() returns EOF if it
can't read a byte. Thus sv_gets() assumes the last line has
been read, and do_readline() happily increments $..

Marcus

-- 
If I'd known computer science was going to be like this, I'd
never have
given up being a rock 'n' roll star.
		-- G. Hirst
[1]

about | contact  Other archives ( Real Estate discussion Medical topics )