Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

print returns error when succeed #14221

Open
p5pRT opened this issue Nov 8, 2014 · 5 comments
Open

print returns error when succeed #14221

p5pRT opened this issue Nov 8, 2014 · 5 comments

Comments

@p5pRT
Copy link

p5pRT commented Nov 8, 2014

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

Searchable as RT123158$

@p5pRT
Copy link
Author

p5pRT commented Nov 8, 2014

From efimov@reg.ru

Running the following script

use strict;
use warnings;
open my $f, ">", "/mnt/tmp/log.log" or die;
while() {
  print $f "Hey\n" or print $f "Error [$!]\n";
}

It prints to the file​:

Hey
Hey
Hey
Hey
Hey
Hey
Hey

Then I run out of disk space. It stop printing. Then I free some disk
space, it starts printing​:

===
Hey
Error [No space left on device]
Hey
Error [No space left on device]
Hey
Error [No space left on device]
Hey
Error [No space left on device]
Hey
Error [No space left on device]

I think something is wrong here​: It should not return error if data is
fully written.
We ran into this when used log4perl
https://metacpan.org/source/MSCHILLI/Log-Log4perl-1.46/lib/Log/Log4perl/Appender/File.pm#L267

Tested in 5.14 and 5.21.2 under Linux. I've used loop device to
simulate low disk space http​://unix.stackexchange.com/a/43915

Summary of my perl5 (revision 5 version 21 subversion 2) configuration​:

  Platform​:
  osname=linux, osvers=3.13.0-35-generic, archname=x86_64-linux
  uname='linux green-u 3.13.0-35-generic #62~precise1-ubuntu smp mon
aug 18 14​:52​:04 utc 2014 x86_64 x86_64 x86_64 gnulinux '
  config_args='-de -Dprefix=/home/perlbrew/perls/perl-5.21.2
-Dusedevel -Aeval​:scriptdir=/home/perlbrew/perls/perl-5.21.2/bin'
  hint=recommended, useposix=true, d_sigaction=define
  useithreads=undef, usemultiplicity=undef
  use64bitint=define, use64bitall=define, uselongdouble=undef
  usemymalloc=n, bincompat5005=undef
  Compiler​:
  cc='cc', ccflags ='-fwrapv -fno-strict-aliasing -pipe
-fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE
-D_FILE_OFFSET_BITS=64',
  optimize='-O2',
  cppflags='-fwrapv -fno-strict-aliasing -pipe -fstack-protector
-I/usr/local/include'
  ccversion='', gccversion='4.6.3', 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
/usr/lib/gcc/x86_64-linux-gnu/4.6/include-fixed
/usr/include/x86_64-linux-gnu /usr/lib /lib/x86_64-linux-gnu
/lib/../lib /usr/lib/x86_64-linux-gnu /usr/lib/../lib /lib
  libs=-lnsl -lgdbm -ldl -lm -lcrypt -lutil -lc -lgdbm_compat
  perllibs=-lnsl -ldl -lm -lcrypt -lutil -lc
  libc=, so=so, useshrplib=false, libperl=libperl.a
  gnulibc_version='2.15'
  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'

Characteristics of this binary (from libperl)​:
  Compile-time options​: HAS_TIMES PERLIO_LAYERS PERL_DONT_CREATE_GVSV
  PERL_HASH_FUNC_ONE_AT_A_TIME_HARD PERL_MALLOC_WRAP
  PERL_NEW_COPY_ON_WRITE PERL_PRESERVE_IVUV
  PERL_USE_DEVEL USE_64_BIT_ALL USE_64_BIT_INT
  USE_LARGE_FILES USE_LOCALE USE_LOCALE_COLLATE
  USE_LOCALE_CTYPE USE_LOCALE_NUMERIC USE_LOCALE_TIME
  USE_PERLIO USE_PERL_ATOF
  Built under linux
  Compiled at Aug 31 2014 01​:05​:45
  %ENV​:
  PERL5LIB=""
  PERLBREW_BASHRC_VERSION="0.69"
  PERLBREW_HOME="/home/vse/.perlbrew"
  PERLBREW_MANPATH="/home/perlbrew/perls/perl-5.21.2/man"
  PERLBREW_PATH="/home/perlbrew/bin​:/home/perlbrew/perls/perl-5.21.2/bin"
  PERLBREW_PERL="perl-5.21.2"
  PERLBREW_ROOT="/home/perlbrew"
  PERLBREW_VERSION="0.69"
  @​INC​:
  /home/perlbrew/perls/perl-5.21.2/lib/site_perl/5.21.2/x86_64-linux
  /home/perlbrew/perls/perl-5.21.2/lib/site_perl/5.21.2
  /home/perlbrew/perls/perl-5.21.2/lib/5.21.2/x86_64-linux
  /home/perlbrew/perls/perl-5.21.2/lib/5.21.2
  .

@p5pRT
Copy link
Author

p5pRT commented Nov 8, 2014

From @cpansprout

Probably related to #116082.

--

Father Chrysostomos

@p5pRT
Copy link
Author

p5pRT commented Nov 8, 2014

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

@p5pRT
Copy link
Author

p5pRT commented Nov 9, 2014

From efimov@reg.ru

2014-11-08 22​:54 GMT+03​:00 Father Chrysostomos via RT
<perlbug-followup@​perl.org>​:

Probably related to #116082.

I can neither confirm nor deny this.
But I want to make a note that this bug is related to work with plain
files, without signals/interrupts involved.

And other similar bugs I've seen with perlio are usually related to
pipes/sockets/interrupts.

--

Father Chrysostomos

---
via perlbug​: queue​: perl5 status​: new
https://rt-archive.perl.org/perl5/Ticket/Display.html?id=123158

@p5pRT
Copy link
Author

p5pRT commented Nov 13, 2014

From @tonycoz

On Sat Nov 08 11​:13​:33 2014, efimov@​reg.ru wrote​:

Then I run out of disk space. It stop printing. Then I free some disk
space, it starts printing​:

===
Hey
Error [No space left on device]
Hey
Error [No space left on device]

This happens because Perl_do_print()'s return value is based on the error state of the stream, not on the success or failure of the current operation.

This has been the case since at least 1994 (before PerlIO).

If you want to work with the current behaviour, you can clear the error state on each write failure, eg​:

  unless (print $f "Hey\n") {
  print STDERR "Error [$!]\n";
  $f->clearerr;
  }

There is a bug in that the documentation says that print returns true if the current operation succeeds, but that's incorrect.

I can see two possible fixes here​:

1) update the documentation to print() to say it returns false if the stream is in an error state, or

2) modify Perl_do_print() to return false iff the current operation failed.

Tony

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants