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

open "-" doesn't use STDIN #15704

Open
p5pRT opened this issue Nov 11, 2016 · 5 comments
Open

open "-" doesn't use STDIN #15704

p5pRT opened this issue Nov 11, 2016 · 5 comments

Comments

@p5pRT
Copy link

p5pRT commented Nov 11, 2016

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

Searchable as RT130071$

@p5pRT
Copy link
Author

p5pRT commented Nov 11, 2016

From @mauke

Created by @mauke

% perl -we 'close STDIN; open my $fh, "-|", "echo", "foo\nbar"; open my $fh2, "<-"; print scalar readline $fh; print scalar readline STDIN; print scalar readline $fh2'
foo
readline() on closed filehandle STDIN at -e line 1.
Use of uninitialized value in print at -e line 1.
bar

This code
- closes STDIN
- opens a pipe from echo as $fh
- opens "-" as $fh2 (which is supposed to open STDIN, which is closed, so
  maybe should fail?)

Then it
- reads a line from $fh (which returns "foo\n" as expected)
- reads a line from STDIN (which returns undef and warns because STDIN is
  closed, as expected)
- reads a line from $fh2 (which returns "bar\n")

The last part is the bug​: $fh2 somehow ended up aliasing $fh. I would've
expected it to either be a closed handle (like STDIN) or magically recover
perl's original stdin. Instead it refers to some other handle opened later on.

Perl Info

Flags:
    category=core
    severity=low

Site configuration information for perl 5.24.0:

Configured by mauke at Mon May  9 21:21:33 CEST 2016.

Summary of my perl5 (revision 5 version 24 subversion 0) configuration:
   
  Platform:
    osname=linux, osvers=4.4.5-1-arch, archname=i686-linux
    uname='linux simplicio 4.4.5-1-arch #1 smp preempt thu mar 10 07:54:30 cet 2016 i686 gnulinux '
    config_args=''
    hint=previous, useposix=true, d_sigaction=define
    useithreads=undef, usemultiplicity=undef
    use64bitint=undef, use64bitall=undef, uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='cc', ccflags ='-fwrapv -fno-strict-aliasing -pipe -fstack-protector-strong -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
    optimize='-O2 -flto',
    cppflags='-fwrapv -fno-strict-aliasing -pipe -fstack-protector-strong -I/usr/local/include'
    ccversion='', gccversion='6.1.1 20160501', gccosandvers=''
    intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234, doublekind=3
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12, longdblkind=3
    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-strong -L/usr/local/lib -flto'
    libpth=/usr/local/lib /usr/lib/gcc/i686-pc-linux-gnu/6.1.1/include-fixed /usr/lib /lib /usr/local/lib /usr/lib/gcc/i686-pc-linux-gnu/6.1.1/include-fixed /usr/lib
    libs=-lpthread -lnsl -lgdbm -ldb -ldl -lm -lcrypt -lutil -lc -lgdbm_compat
    perllibs=-lpthread -lnsl -ldl -lm -lcrypt -lutil -lc
    libc=libc-2.23.so, so=so, useshrplib=false, libperl=libperl.a
    gnulibc_version='2.23'
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E'
    cccdlflags='-fPIC', lddlflags='-shared -O2 -flto -L/usr/local/lib -fstack-protector-strong'



@INC for perl 5.24.0:
    /home/mauke/usr/lib/perl5/site_perl/5.24.0/i686-linux
    /home/mauke/usr/lib/perl5/site_perl/5.24.0
    /home/mauke/usr/lib/perl5/5.24.0/i686-linux
    /home/mauke/usr/lib/perl5/5.24.0
    .


Environment for perl 5.24.0:
    HOME=/home/mauke
    LANG=en_US.UTF-8
    LANGUAGE=en_US
    LC_COLLATE=C
    LC_MONETARY=de_DE.UTF-8
    LC_TIME=de_DE.UTF-8
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=/home/mauke/perl5/perlbrew/bin:/home/mauke/bin:/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl
    PERLBREW_BASHRC_VERSION=0.73
    PERLBREW_HOME=/home/mauke/.perlbrew
    PERLBREW_ROOT=/home/mauke/perl5/perlbrew
    PERL_BADLANG (unset)
    PERL_UNICODE=SAL
    SHELL=/bin/bash

@p5pRT
Copy link
Author

p5pRT commented Nov 12, 2016

From @mauke

On Fri, 11 Nov 2016 04​:49​:38 -0800, mauke- wrote​:

% perl -we 'close STDIN; open my $fh, "-|", "echo", "foo\nbar"; open
my $fh2, "<-"; print scalar readline $fh; print scalar readline STDIN;
print scalar readline $fh2'
foo
readline() on closed filehandle STDIN at -e line 1.
Use of uninitialized value in print at -e line 1.
bar

AFAICS this is due to the internals using PerlIO_stdin() everywhere, which simply returns the first PerlIO object in the internal table, not necessarily STDIN. STDIN is the first object internally, but closing it frees that slot and then the next handle created will be placed in that slot and treated as "stdin" by the internals, no matter what you do with STDIN afterwards.

@p5pRT
Copy link
Author

p5pRT commented Dec 17, 2017

From zefram@fysh.org

After closing one of the standard I/O streams, it is normal that a
subsequent open will accidentally reuse the file descriptor. The kind
of aliasing seen here is to be expected from this sort of activity,
and is not a bug. This ticket should be closed.

-zefram

@p5pRT
Copy link
Author

p5pRT commented Dec 17, 2017

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

@p5pRT
Copy link
Author

p5pRT commented Dec 19, 2017

From @mauke

Am 17.12.2017 um 02​:19 schrieb Zefram via RT​:

After closing one of the standard I/O streams, it is normal that a
subsequent open will accidentally reuse the file descriptor. The kind
of aliasing seen here is to be expected from this sort of activity,
and is not a bug. This ticket should be closed.

This is unrelated to file descriptors​:

% perl -we 'close STDIN; open my $fh, q{<}, \qq{foo\nbar\n}; open my
$fh2, q{<-}; print scalar readline $fh; print scalar readline STDIN;
print scalar readline $fh2'
foo
readline() on closed filehandle STDIN at -e line 1.
Use of uninitialized value in print at -e line 1.
bar

I.e. you get the same output if $fh refers to a string and doesn't use a
file descriptor internally. $fh2 still somehow aliases the stream.

Worse​:

% perl -we 'close STDIN; open my $fh, q{<}, \qq{foo\nbar\n}; open STDIN,
q{echo hi |}; open my $fh2, q{<-}; print scalar readline $fh; print
scalar readline STDIN; print scalar readline $fh2; print fileno STDIN,
qq{\n}'
foo
hi
bar
0

Now we have a real STDIN handle, it's bound to file descriptor 0, and
still $fh2 refers to $fh, not STDIN.

--
Lukas Mai <l.mai@​web.de>

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