Perl / perl5

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

Docs for close don't mention effect of stream error status #8539

Closed p5pRT closed 16 years ago

p5pRT commented 18 years ago

Migrated from rt.perl.org#39902 (status was 'resolved')

Searchable as RT39902$

p5pRT commented 18 years ago

From timbo@ppp-117.la.vclk.net

Created by timbo@ppp-117.la.vclk.net

The perl docs for close don't mention that the return status is affected by previous errors on the filehandle.

For example\, in doio.c Perl_do_print returns the status using​:

  return !PerlIO_error(fp);

Perl_do_close calls Perl_io_close which does​:

  bool prev_err = PerlIO_error(IoIFP(io));   retval = (PerlIO_close(IoIFP(io)) != EOF && !prev_err);

So close only returns success if the close worked _and_ there was no previous error on the stream.

(Doesn't apply to pipes though\, but if the write to a pipe failed then it's hard to imagine circumstances where the pclose wouldn't return an error.)

This behaviour of close is a good thing. It means that the return status of close can be used to check for complete success​: not just success in closing the handle\, but also that nothing went wrong while using the handle.

Perl Info ``` Flags: category=docs severity=low Site configuration information for perl v5.8.6: Configured by timbo at Thu May 25 17:26:37 IST 2006. Summary of my perl5 (revision 5 version 8 subversion 6) configuration: Platform: osname=darwin, osvers=8.5.2, archname=darwin-thread-multi-2level uname='darwin ppp-117.la.vclk.net 8.5.2 darwin kernel version 8.5.2: mon feb 13 16:31:48 pst 2006; root:xnu-792.8.37.obj~1release_i386 i386 i386 ' config_args='-des -Dprefix=/usr/local/perl58-i -Doptimize=-g -Duseithreads -Dusemultiplicity' hint=recommended, useposix=true, d_sigaction=define usethreads=define use5005threads=undef useithreads=define usemultiplicity=define useperlio=define d_sfio=undef uselargefiles=define usesocks=undef use64bitint=undef use64bitall=undef uselongdouble=undef usemymalloc=n, bincompat5005=undef Compiler: cc='cc', ccflags ='-fno-common -DPERL_DARWIN -no-cpp-precomp -DDEBUGGING -fno-strict-aliasing -pipe -I/usr/local/include -I/opt/local/include', optimize='-g', cppflags='-no-cpp-precomp -fno-common -DPERL_DARWIN -no-cpp-precomp -DDEBUGGING -fno-strict-aliasing -pipe -I/usr/local/include -I/opt/local/include' ccversion='', gccversion='4.0.1 (Apple Computer, Inc. build 5250)', gccosandvers='' intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234 d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16 ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8 alignbytes=8, prototype=define Linker and Libraries: ld='env MACOSX_DEPLOYMENT_TARGET=10.3 cc', ldflags =' -L/usr/local/lib -L/opt/local/lib' libpth=/usr/local/lib /opt/local/lib /usr/lib libs=-lgdbm -ldbm -ldl -lm -lc perllibs=-ldl -lm -lc libc=/usr/lib/libc.dylib, so=dylib, useshrplib=false, libperl=libperl.a gnulibc_version='' Dynamic Linking: dlsrc=dl_dyld.xs, dlext=bundle, d_dlsymun=undef, ccdlflags=' ' cccdlflags=' ', lddlflags=' -bundle -undefined dynamic_lookup -L/usr/local/lib -L/opt/local/lib' Locally applied patches: @INC for perl v5.8.6: /home/value/perl /home/value/apps/site_perl/darwin-thread-multi-2level /home/value/apps/site_perl /home/value/sandbox/tbunce2/adnetwork/vcm/lib/perl /home/value/sandbox/tbunce2/adnetwork/vcm/lib/site_perl/darwin-thread-multi-2level /home/value/sandbox/tbunce2/adnetwork/vcm/lib/site_perl /usr/local/perl58-i/lib/5.8.6/darwin-thread-multi-2level /usr/local/perl58-i/lib/5.8.6 /usr/local/perl58-i/lib/site_perl/5.8.6/darwin-thread-multi-2level /usr/local/perl58-i/lib/site_perl/5.8.6 /usr/local/perl58-i/lib/site_perl . Environment for perl v5.8.6: DYLD_LIBRARY_PATH=/Users/timbo/Library/Oracle/InstantClient-10-1-0-3:/opt/local/lib/mysql5/mysql HOME=/Users/timbo LANG (unset) LANGUAGE (unset) LD_LIBRARY_PATH (unset) LOGDIR (unset) PATH=/home/value/apps:/home/value/bin/utils:/home/value/sandbox/tbunce2/adnetwork/vcm/bin/utils:/Users/timbo/bin:/usr/local/perl58-i/bin:/usr/local/mysql/bin:/usr/local/bin:/opt/local/bin:/bin:/sbin:/usr/bin:/usr/sbin:/home/value/sandbox/tbunce2/adnetwork/vcm/bin/cpan:/home/value/sandbox/tbunce2/adnetwork/vcm/component/devel/bin PERL5LIB=/home/value/perl:/home/value/apps/site_perl:/home/value/sandbox/tbunce2/adnetwork/vcm/lib/perl:/home/value/sandbox/tbunce2/adnetwork/vcm/lib/site_perl PERLCRITIC=/home/value/sandbox/tbunce2/adnetwork/vcm/component/devel/perlcriticrc PERLTIDY=/home/value/sandbox/tbunce2/adnetwork/vcm/component/devel/perltidyrc PERL_BADLANG (unset) PERL_PMD_DB=/home/value/sandbox/tbunce2/adnetwork/vcm/var/user/tbunce/pmd_index.dat SHELL=/bin/bash ```
p5pRT commented 17 years ago

From Peter.Dintelmann@dresdner-bank.com

The perl docs for close don't mention that the return status is affected by previous errors on the filehandle.

  [snip]

So close only returns success if the close worked _and_ there was no previous error on the stream.

(Doesn't apply to pipes though\, but if the write to a pipe failed then it's hard to imagine circumstances where the pclose wouldn't return an error.)

  The return value of close() is affected by the state of the handle   and the state reported by the IO layers. The simple layer

  $ cat PerlIO/via/error.pm   package PerlIO​::via​::error;   use strict;

  sub PUSHED { bless {}\, __PACKAGE__ }   sub ERROR { 1 }

  1;

  always reports an error and thus close() will always "fail"   when it is in effect​:

  $ perl -MPerlIO​::via​::error -e 'open $f\, "\<​:via(error)"\, \   > "/dev/null" or die $!; close $f or warn $!'   Warning​: something's wrong at -e line 1.

  Here is an attempt to mention this behaviour in the docs​:

  $ diff -urd blead/lib/perl5/5.9.5/pod/perlfunc.pod /var/tmp/perlfunc.pod   --- blead/lib/perl5/5.9.5/pod/perlfunc.pod 2006-11-15 17​:45​:23.000000000 +0100   +++ /var/tmp/perlfunc.pod 2006-11-16 10​:33​:33.000000000 +0100   @​@​ -870\,10 +870\,10 @​@​

  =item close

  -Closes the file or pipe associated with the file handle\, returning   -true only if IO buffers are successfully flushed and closes the system   -file descriptor. Closes the currently selected filehandle if the   -argument is omitted.   +Closes the file or pipe associated with the file handle\, flushes the   +IO buffers\, and closes the system file descriptor. The return value   +takes into account the state of the handle and its IO layers (if any).   +Closes the currently selected filehandle if the argument is omitted.

  You don't have to close FILEHANDLE if you are immediately going to do   another C\ on it\, because C\ will close it for you. (See

p5pRT commented 17 years ago

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

p5pRT commented 17 years ago

From @rgarcia

On 16/11/06\, Dintelmann\, Peter \Peter\.Dintelmann@&#8203;dresdner\-bank\.com wrote​:

Here is an attempt to mention this behaviour in the docs&#8203;:

I reworked it a bit\, and applied it :

==== //depot/perl/pod/perlfunc.pod#548 (text) ====

@​@​ -870\,10 +870\,11 @​@​

=item close

-Closes the file or pipe associated with the file handle\, returning -true only if IO buffers are successfully flushed and closes the system -file descriptor. Closes the currently selected filehandle if the -argument is omitted. +Closes the file or pipe associated with the file handle\, flushes the IO +buffers\, and closes the system file descriptor. Returns true if those +operations have succeeded and if no error was reported by any PerlIO +layer. Closes the currently selected filehandle if the argument is +omitted.

You don't have to close FILEHANDLE if you are immediately going to do another C\ on it\, because C\ will close it for you. (See

p5pRT commented 16 years ago

p5p@spam.wizbit.be - Status changed from 'open' to 'resolved'