Perl / perl5

🐪 The Perl programming language
https://dev.perl.org/perl5/
Other
1.91k stars 542 forks source link

POSIX::read returns 0 but true at EOF #13384

Open p5pRT opened 10 years ago

p5pRT commented 10 years ago

Migrated from rt.perl.org#120409 (status was 'open')

Searchable as RT120409$

p5pRT commented 10 years ago

From graf@cpan.org

The expected results in an endless loop​:

perl -MPOSIX -wE 'my $buf = ""; my $f = POSIX​::open("/etc/passwd"); my $r; do { $r = POSIX​::read($f\, $buf\, 4096) } while $r;'

This works - and tells you why​:

perl -MPOSIX -wE 'my $buf = ""; my $f = POSIX​::open("/etc/passwd"); my $r; do { $r = POSIX​::read($f\, $buf\, 4096) } until $r == 0; say $r;'

This is *not documented* and behaves differently from CORE​::read().

-- Bernhard Graf

p5pRT commented 10 years ago

The RT System itself - Status changed from 'new' to 'open'

p5pRT commented 10 years ago

From victor@vsespb.ru

seems POSIX​::2008 author noticed that earlier​:

https://metacpan.org/pod/POSIX::2008

Like POSIX​::read() but returns 0 at EOF instead of "0 but true".

On Tue Oct 29 06​:18​:47 2013\, augensalat wrote​:

The expected results in an endless loop​:

perl -MPOSIX -wE 'my $buf = ""; my $f = POSIX​::open("/etc/passwd"); my $r; do { $r = POSIX​::read($f\, $buf\, 4096) } while $r;'

This works - and tells you why​:

perl -MPOSIX -wE 'my $buf = ""; my $f = POSIX​::open("/etc/passwd"); my $r; do { $r = POSIX​::read($f\, $buf\, 4096) } until $r == 0; say $r;'

This is *not documented* and behaves differently from CORE​::read().

p5pRT commented 10 years ago

From Mark@Overmeer.net

* Victor Efimov via RT (perlbug-followup@​perl.org) [131029 14​:23]​:

seems POSIX​::2008 author noticed that earlier​:

https://metacpan.org/pod/POSIX::2008

Like POSIX​::read() but returns 0 at EOF instead of "0 but true".

One way or the other\, you have to encode the difference between "0 bytes" and "error". As error==-1\, that would be a true value. It is a common trick for POSIX.pm functions to return "0 but true"\, used 35 times.

Even

  perl -we '$x = "0 but TRUE"; print $x + 4' --> isn't numeric   perl -we '$x = "0 but true"; print $x + 4' --> silent  

On Tue Oct 29 06​:18​:47 2013\, augensalat wrote​:

This is *not documented* and behaves differently from CORE​::read().

POSIX​::read compares to CORE​::sysread (not CORE​::read)\, which uses "0" and "undef" as encodings. A bit saner\, though many people will forget handling errors that way. -- Regards\,

  MarkOv


  Mark Overmeer MSc MARKOV Solutions   Mark@​Overmeer.net solutions@​overmeer.net http​://Mark.Overmeer.net http​://solutions.overmeer.net

p5pRT commented 10 years ago

From @Leont

On Tue\, Oct 29\, 2013 at 2​:18 PM\, Bernhard Graf \perlbug\-followup@​perl\.orgwrote​:

The expected results in an endless loop​:

perl -MPOSIX -wE 'my $buf = ""; my $f = POSIX​::open("/etc/passwd"); my $r; do { $r = POSIX​::read($f\, $buf\, 4096) } while $r;'

This works - and tells you why​:

perl -MPOSIX -wE 'my $buf = ""; my $f = POSIX​::open("/etc/passwd"); my $r; do { $r = POSIX​::read($f\, $buf\, 4096) } until $r == 0; say $r;'

That's what all SysRet functions do. -1 becomes undef\, 0 becomes "0 but true"\, any other number is returned as-is. It only returns false on error.

This is *not documented* and behaves differently from CORE​::read().

It's consistent with the rest of POSIX. I think that's a good thing. I agree it could be documented more clearly though.

Leon