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

PerlIO::via calls the CLOSE callback too late #10443

Open
p5pRT opened this issue Jun 15, 2010 · 5 comments
Open

PerlIO::via calls the CLOSE callback too late #10443

p5pRT opened this issue Jun 15, 2010 · 5 comments

Comments

@p5pRT
Copy link

p5pRT commented Jun 15, 2010

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

Searchable as RT75780$

@p5pRT
Copy link
Author

p5pRT commented Jun 15, 2010

From @ikegami

Created by @ikegami

PerlIO​::via calls the CLOSE callback too late.

Say you have a handle with the following PerlIO layers​:

  - utf8
  - encoding(UTF-8)
  - via(Mine)
  - perlio
  - unix

The close callbacks are called in this order​:

  1 utf8
  2 encoding(UTF-8)
  3 via
  4 perlio
  5 unix
  6 Mine <-- !!

This limits what PerlIO​::via​::Mine​::CLOSE can do. For example,
PerlIO-via-EscStatus wants to write something to the handle as it is being
closed, but can't.

The close functions should be called in this order​:

  1 utf8
  2 encoding(UTF-8)
  3 via
  4 Mine <--
  5 perlio
  6 unix

There are 32 PerlIO​::via modules on CPAN. 27 don't define a CLOSE handler.
What follows is a breakdown of the others​:

PerlIO-via-SeqIO has a buggy CLOSE, no matter when it's called. (Calls
close() on the handle being closed.)
PerlIO-via-gzip has a buggy CLOSE, no matter when it's called. (Calls
close() on the handle being closed.)

PerlIO-via-ToFirePHP doesn't care when its CLOSE is called.
PerlIO-via-symlink doesn't care when its CLOSE is called.

PerlIO-via-EscStatus wants to write to the handle when it's being closed,
but it can't with the current behaviour.

IV
PerlIOVia_close(pTHX_ PerlIO * f)
{
  PerlIOVia *s = PerlIOSelf(f, PerlIOVia);
- IV code = PerlIOBase_close(aTHX_ f);
  SV *result =
  PerlIOVia_method(aTHX_ f, MYMethod(CLOSE), G_SCALAR, Nullsv);
+ IV code = PerlIOBase_close(aTHX_ f);
  if (result && SvIV(result) != 0)
  code = SvIV(result);
  PerlIOBase(f)->flags &= ~(PERLIO_F_RDBUF | PERLIO_F_WRBUF);
  return code;
}

Perl Info

Flags:
    category=library
    severity=low
    module=PerlIO::via

Site configuration information for perl 5.12.0:

Configured by eric at Tue May  4 17:51:08 EDT 2010.

Summary of my perl5 (revision 5 version 12 subversion 0) configuration:

  Platform:
    osname=linux, osvers=2.6.26-2-686, archname=i686-linux
    uname='linux fmdev10 2.6.26-2-686 #1 smp tue mar 9 17:35:51 utc 2010
i686 gnulinux '
    config_args='-de -Dprefix=/home/eric/usr/perlbrew/perls/perl-5.12.0'
    hint=recommended, useposix=true, d_sigaction=define
    useithreads=undef, usemultiplicity=undef
    useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef
    use64bitint=undef, use64bitall=undef, 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.3.2', gccosandvers=''
    intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12
    ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t',
lseeksize=8
    alignbytes=4, prototype=define
  Linker and Libraries:
    ld='cc', ldflags =' -fstack-protector -L/usr/local/lib'
    libpth=/usr/local/lib /lib /usr/lib
    libs=-lnsl -ldl -lm -lcrypt -lutil -lc
    perllibs=-lnsl -ldl -lm -lcrypt -lutil -lc
    libc=/lib/libc-2.7.so, so=so, useshrplib=false, libperl=libperl.a
    gnulibc_version='2.7'
  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.12.0:

/home/eric/usr/perlbrew/perls/perl-5.12.0/lib/site_perl/5.12.0/i686-linux
    /home/eric/usr/perlbrew/perls/perl-5.12.0/lib/site_perl/5.12.0
    /home/eric/usr/perlbrew/perls/perl-5.12.0/lib/5.12.0/i686-linux
    /home/eric/usr/perlbrew/perls/perl-5.12.0/lib/5.12.0
    .


Environment for perl 5.12.0:
    HOME=/home/eric
    LANG=en_US.UTF-8
    LANGUAGE (unset)
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)

PATH=/home/eric/usr/perlbrew/bin:/home/eric/usr/perlbrew/perls/current/bin:.:/home/eric/bin:/usr/local/bin:/usr/bin:/bin:/usr/games
    PERLBREW_ROOT=/home/eric/usr/perlbrew
    PERL_BADLANG (unset)
    SHELL=/bin/bash

@p5pRT
Copy link
Author

p5pRT commented Mar 28, 2012

From @nwc10

On Tue Jun 15 15​:01​:13 2010, ikegami@​adaelis.com wrote​:

PerlIO​::via calls the CLOSE callback too late.

There are 32 PerlIO​::via modules on CPAN. 27 don't define a CLOSE
handler.

would any break (or break more badly) with this change?

IV
PerlIOVia_close(pTHX_ PerlIO * f)
{
PerlIOVia *s = PerlIOSelf(f, PerlIOVia);
- IV code = PerlIOBase_close(aTHX_ f);
SV *result =
PerlIOVia_method(aTHX_ f, MYMethod(CLOSE), G_SCALAR, Nullsv);
+ IV code = PerlIOBase_close(aTHX_ f);
if (result && SvIV(result) != 0)
code = SvIV(result);
PerlIOBase(f)->flags &= ~(PERLIO_F_RDBUF | PERLIO_F_WRBUF);
return code;
}

I'm wondering whether *instead*, the change should be to decree
that the CLOSE handler (if present) is responsible for closing the
file handle.

Design-wise is that cleaner? Or does it break more assumptions?

Nicholas Clark

@p5pRT
Copy link
Author

p5pRT commented Mar 28, 2012

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

@p5pRT
Copy link
Author

p5pRT commented Mar 28, 2012

From @nwc10

[and again, as I forgot to cc perl5-porters]

On Tue Jun 15 15​:01​:13 2010, ikegami@​adaelis.com wrote​:

PerlIO​::via calls the CLOSE callback too late.

There are 32 PerlIO​::via modules on CPAN. 27 don't define a CLOSE
handler.

would any break (or break more badly) with this change?

IV
PerlIOVia_close(pTHX_ PerlIO * f)
{
PerlIOVia *s = PerlIOSelf(f, PerlIOVia);
- IV code = PerlIOBase_close(aTHX_ f);
SV *result =
PerlIOVia_method(aTHX_ f, MYMethod(CLOSE), G_SCALAR, Nullsv);
+ IV code = PerlIOBase_close(aTHX_ f);
if (result && SvIV(result) != 0)
code = SvIV(result);
PerlIOBase(f)->flags &= ~(PERLIO_F_RDBUF | PERLIO_F_WRBUF);
return code;
}

I'm wondering whether *instead*, the change should be to decree
that the CLOSE handler (if present) is responsible for closing the
file handle.

Design-wise is that cleaner? Or does it break more assumptions?

Nicholas Clark

@p5pRT
Copy link
Author

p5pRT commented Mar 28, 2012

From [Unknown Contact. See original ticket]

[and again, as I forgot to cc perl5-porters]

On Tue Jun 15 15​:01​:13 2010, ikegami@​adaelis.com wrote​:

PerlIO​::via calls the CLOSE callback too late.

There are 32 PerlIO​::via modules on CPAN. 27 don't define a CLOSE
handler.

would any break (or break more badly) with this change?

IV
PerlIOVia_close(pTHX_ PerlIO * f)
{
PerlIOVia *s = PerlIOSelf(f, PerlIOVia);
- IV code = PerlIOBase_close(aTHX_ f);
SV *result =
PerlIOVia_method(aTHX_ f, MYMethod(CLOSE), G_SCALAR, Nullsv);
+ IV code = PerlIOBase_close(aTHX_ f);
if (result && SvIV(result) != 0)
code = SvIV(result);
PerlIOBase(f)->flags &= ~(PERLIO_F_RDBUF | PERLIO_F_WRBUF);
return code;
}

I'm wondering whether *instead*, the change should be to decree
that the CLOSE handler (if present) is responsible for closing the
file handle.

Design-wise is that cleaner? Or does it break more assumptions?

Nicholas Clark

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

No branches or pull requests

2 participants