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

Non-native STDIO-replacing handles NOT closed nor marked as FD_CLOEXEC #14762

Open
p5pRT opened this issue Jun 16, 2015 · 3 comments
Open

Non-native STDIO-replacing handles NOT closed nor marked as FD_CLOEXEC #14762

p5pRT opened this issue Jun 16, 2015 · 3 comments

Comments

@p5pRT
Copy link

p5pRT commented Jun 16, 2015

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

Searchable as RT125424$

@p5pRT
Copy link
Author

p5pRT commented Jun 16, 2015

From @ribasushi

Consider this (procfs-specific) example​:

rabbit@​Ahasver​:~$ perl -e '
  close STDIN;
  close STDOUT;
  exec( $^X => -e => q(
  require Tie​::Hash;
  exec( $^X => -e => q(
  warn `ls -l /proc/$$/fd`
  ) )
  ) )
'
total 0
lr-x------ 1 rabbit rabbit 64 Jun 16 17​:57 0 -> /dev/null
lr-x------ 1 rabbit rabbit 64 Jun 16 17​:57 1 ->
/home/rabbit/perl5/perlbrew/perls/5.20.0/lib/5.20.0/Tie/Hash.pm
lrwx------ 1 rabbit rabbit 64 Jun 16 17​:57 2 -> /dev/pts/19
lr-x------ 1 rabbit rabbit 64 Jun 16 17​:57 3 -> pipe​:[2138010]

I would have expected that FD1 is closed after require() finishes. Yet
not only it stays open, but it is also inherited across exec().

Likely somewhere in the guts there is an over-eager check for "do not
touch anything with fileno <= 2", which ideally should be relaxed.

@p5pRT
Copy link
Author

p5pRT commented Jun 17, 2015

From @Leont

On Tue, Jun 16, 2015 at 5​:59 PM, Peter Rabbitson <perlbug-followup@​perl.org>
wrote​:

Consider this (procfs-specific) example​:

rabbit@​Ahasver​:~$ perl -e '
close STDIN;
close STDOUT;
exec( $^X => -e => q(
require Tie​::Hash;
exec( $^X => -e => q(
warn `ls -l /proc/$$/fd`
) )
) )
'
total 0
lr-x------ 1 rabbit rabbit 64 Jun 16 17​:57 0 -> /dev/null
lr-x------ 1 rabbit rabbit 64 Jun 16 17​:57 1 ->
/home/rabbit/perl5/perlbrew/perls/5.20.0/lib/5.20.0/Tie/Hash.pm
lrwx------ 1 rabbit rabbit 64 Jun 16 17​:57 2 -> /dev/pts/19
lr-x------ 1 rabbit rabbit 64 Jun 16 17​:57 3 -> pipe​:[2138010]

I would have expected that FD1 is closed after require() finishes. Yet

not only it stays open, but it is also inherited across exec().

Likely somewhere in the guts there is an over-eager check for "do not
touch anything with fileno <= 2", which ideally should be relaxed.

What's happening is something completely different, it's essentially a
refcounting issue. At startup, PerlIO does an fdopen to fd=0,1,2, assuming
they are open already(refcount=1). Then in runtime those descriptors are
opened for real (refcount=2) and then closed (refcount=1 again). The
inheriting across exec is $^F doing exactly what it's supposed to do.

I'm not sure what the solution is in this situation, TBH.

Leon

@p5pRT
Copy link
Author

p5pRT commented Jun 17, 2015

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

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