Perl / perl5

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

eof() on write-only filehandle breaks it #11863

Open p5pRT opened 12 years ago

p5pRT commented 12 years ago

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

Searchable as RT108124$

p5pRT commented 12 years ago

From @Leont

Created by @Leont

Observe​:

perl -E 'say eof STDOUT\, 2'

This outputs a "1" without the "2" and without a newline.

Actually\, this is two bugs\, though they're rather linked​: eof() tries to read from the filehandle to determine if it's at EOF\, which sets the error flag if the handle is unreadable. print checks the error flag *after* every element is written\, and stops writing if it is set. Hence only the first element will be written.

To fix the first bug\, I suggest not trying to read from a write-only filehandle but always return true.

To fix the second bug (printing one element but not the rest)\, I suggest testing for errors before printing.

Perl Info ``` Flags: category=core severity=low Site configuration information for perl 5.14.2: Configured by leon at Sun Nov 27 14:38:29 CET 2011. Summary of my perl5 (revision 5 version 14 subversion 2) configuration: Platform: osname=linux, osvers=3.0.0-13-generic, archname=x86_64-linux uname='linux leon-laptop 3.0.0-13-generic #22-ubuntu smp wed nov 2 13:27:26 utc 2011 x86_64 x86_64 x86_64 gnulinux ' config_args='-de -Dprefix=/home/leon/perl5/perlbrew/perls/perl-5.14.2' hint=recommended, useposix=true, d_sigaction=define useithreads=undef, usemultiplicity=undef useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef use64bitint=define, use64bitall=define, uselongdouble=undef usemymalloc=n, bincompat5005=undef Compiler: cc='cc', ccflags ='-fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64', optimize='-O2', cppflags='-fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include' ccversion='', gccversion='4.6.1', gccosandvers='' intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678 d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16 ivtype='long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8 alignbytes=8, prototype=define Linker and Libraries: ld='cc', ldflags =' -fstack-protector -L/usr/local/lib' libpth=/usr/local/lib /lib/x86_64-linux-gnu /lib/../lib /usr/lib/x86_64-linux-gnu /usr/lib/../lib /lib /usr/lib libs=-lnsl -ldl -lm -lcrypt -lutil -lc perllibs=-lnsl -ldl -lm -lcrypt -lutil -lc libc=, so=so, useshrplib=false, libperl=libperl.a gnulibc_version='2.13' Dynamic Linking: dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E' cccdlflags='-fPIC', lddlflags='-shared -O2 -L/usr/local/lib -fstack-protector' Locally applied patches: @INC for perl 5.14.2: /home/leon/perl5/perlbrew/perls/perl-5.14.2/lib/site_perl/5.14.2/x86_64-linux /home/leon/perl5/perlbrew/perls/perl-5.14.2/lib/site_perl/5.14.2 /home/leon/perl5/perlbrew/perls/perl-5.14.2/lib/5.14.2/x86_64-linux /home/leon/perl5/perlbrew/perls/perl-5.14.2/lib/5.14.2 . Environment for perl 5.14.2: HOME=/home/leon LANG=en_US.utf8 LANGUAGE=en_US:en_GB:en LD_LIBRARY_PATH (unset) LOGDIR (unset) PATH=/home/leon/perl5/perlbrew/bin:/home/leon/perl5/perlbrew/perls/perl-5.14.2/bin:/home/leon/bin:/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games PERLBREW_HOME=/home/leon/.perlbrew PERLBREW_PATH=/home/leon/perl5/perlbrew/bin:/home/leon/perl5/perlbrew/perls/perl-5.14.2/bin PERLBREW_PERL=perl-5.14.2 PERLBREW_ROOT=/home/leon/perl5/perlbrew PERLBREW_VERSION=0.25 PERL_BADLANG (unset) SHELL=/bin/bash ```
p5pRT commented 12 years ago

From @cpansprout

On Thu Jan 12 17​:36​:22 2012\, LeonT wrote​:

This is a bug report for perl from fawaka@​gmail.com\, generated with the help of perlbug 1.39 running under perl 5.14.2.

----------------------------------------------------------------- [Please describe your issue here]

Observe​:

perl -E 'say eof STDOUT\, 2'

This outputs a "1" without the "2" and without a newline.

Actually\, this is two bugs\, though they're rather linked​: eof() tries to read from the filehandle to determine if it's at EOF\, which sets the error flag if the handle is unreadable. print checks the error flag *after* every element is written\, and stops writing if it is set. Hence only the first element will be written.

To fix the first bug\, I suggest not trying to read from a write-only filehandle but always return true.

To fix the second bug (printing one element but not the rest)\, I suggest testing for errors before printing.

What a coincidence! Just today I discovered a similar bug with -T STDOUT. It causes print("foo"\,"bar") only to print "foo"; "bar" and $\ are not printed.

--

Father Chrysostomos

p5pRT commented 12 years ago

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

p5pRT commented 12 years ago

From @Leont

On Fri\, Jan 13\, 2012 at 3​:10 AM\, Father Chrysostomos via RT \perlbug\-followup@​perl\.org wrote​:

What a coincidence!  Just today I discovered a similar bug with -T STDOUT.  It causes print("foo"\,"bar") only to print "foo"; "bar" and $\ are not printed.

And possibly there are more issues like that. We should either decide to avoid reading from write-only handles\, or not set the error flag when someone does that. Or probably both.

Leon

p5pRT commented 12 years ago

From @cpansprout

On Sun Jan 15 08​:05​:08 2012\, LeonT wrote​:

On Fri\, Jan 13\, 2012 at 3​:10 AM\, Father Chrysostomos via RT \perlbug\-followup@​perl\.org wrote​:

What a coincidence! �Just today I discovered a similar bug with -T STDOUT. �It causes print("foo"\,"bar") only to print "foo"; "bar" and $\ are not printed.

And possibly there are more issues like that. We should either decide to avoid reading from write-only handles\, or not set the error flag when someone does that. Or probably both.

I wonder why readline doesn’t do that​:

$ perl -le' \; print "a"\,"b"' ab

--

Father Chrysostomos

p5pRT commented 12 years ago

From @Leont

On Sun\, Jan 15\, 2012 at 8​:15 PM\, Father Chrysostomos via RT \perlbug\-followup@​perl\.org wrote​:

I wonder why readline doesn’t do that​:

$ perl -le' \; print "a"\,"b"' ab

Because readline for some reason I do not quite understand\, seems to clear the error flag. See pp_hot.c​:1671. Doing a read on it does show exactly this behavior though\, as one would expect​:

perl -le' read STDOUT\, my $foo\, 1; print "a"\,"b"'

It's a mess\, really.

Leon

p5pRT commented 12 years ago

From @cpansprout

On Sun Jan 15 11​:42​:34 2012\, LeonT wrote​:

On Sun\, Jan 15\, 2012 at 8​:15 PM\, Father Chrysostomos via RT \perlbug\-followup@​perl\.org wrote​:

I wonder why readline doesn’t do that​:

$ perl -le' \; print "a"\,"b"' ab

Because readline for some reason I do not quite understand\, seems to clear the error flag. See pp_hot.c​:1671. Doing a read on it does show exactly this behavior though\, as one would expect​:

perl -le' read STDOUT\, my $foo\, 1; print "a"\,"b"'

It's a mess\, really.

That suggests to me that print should just ignore the error flag and print anyway. After all\, the error could be for any number of reasons.

Or it could check the error status before printing (is the actual errno number stored with the filehandle?) and see whether it changes after that\, bailing out if it has changed.

--

Father Chrysostomos