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

open2 acts very strange when STDOUT is redirected. #12748

Open
p5pRT opened this issue Jan 30, 2013 · 3 comments
Open

open2 acts very strange when STDOUT is redirected. #12748

p5pRT opened this issue Jan 30, 2013 · 3 comments

Comments

@p5pRT
Copy link

p5pRT commented Jan 30, 2013

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

Searchable as RT116589$

@p5pRT
Copy link
Author

p5pRT commented Jan 30, 2013

From xungeng@gmail.com

Created by xungeng@gmail.com

see this example​:
xungeng@​debian​:~/work/test/test$ cat foo
#!/usr/bin/perl
use FileHandle;
use IPC​::Open2;
use IO​::Handle;

#*STDOUT = IO​::Handle->new;

for (1..3) {
  print STDERR "Loop​: $_\n";
  $pid = open2( \*Reader, \*Writer, "cat" );
  Writer->autoflush(); # default here, actually
  print Writer "stuff\n";
  $got = <Reader>;
  print STDERR $got;
}
xungeng@​debian​:~/work/test/test$ cat bar
#!/usr/bin/perl
use FileHandle;
use IPC​::Open2;
use IO​::Handle;

*STDOUT = IO​::Handle->new;

for (1..3) {
  print STDERR "Loop​: $_\n";
  $pid = open2( \*Reader, \*Writer, "cat" );
  Writer->autoflush(); # default here, actually
  print Writer "stuff\n";
  $got = <Reader>;
  print STDERR $got;
}
xungeng@​debian​:~/work/test/test$ ./foo > /dev/null
Loop​: 1
stuff
Loop​: 2
stuff
Loop​: 3
stuff
xungeng@​debian​:~/work/test/test$ ./bar > /dev/null
Loop​: 1
Loop​: 2
Loop​: 3

the difference between foo and bar is only that STDOUT redirected or not.

when STDOUT is redirected, open2 make the child process write to the old
STDOUT,
not the child_out handler (\*Reader in this example).

Perl Info

Flags:
    category=library
    severity=high
    module=IPC::Open2

Site configuration information for perl 5.14.2:

Configured by Debian Project at Mon Dec 10 13:17:22 UTC 2012.

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

  Platform:
    osname=linux, osvers=3.2.0-4-686-pae,
archname=i486-linux-gnu-thread-multi-64int
    uname='linux callisto 3.2.0-4-686-pae #1 smp debian 3.2.32-1 i686
gnulinux '
    config_args='-Dusethreads -Duselargefiles -Dccflags=-DDEBIAN
-D_FORTIFY_SOURCE=2 -g -O2 -fstack-protector --param=ssp-buffer-size=4
-Wformat -Werror=format-security -Dldflags= -Wl,-z,relro
-Dlddlflags=-shared -Wl,-z,relro -Dcccdlflags=-fPIC
-Darchname=i486-linux-gnu -Dprefix=/usr -Dprivlib=/usr/share/perl/5.14
-Darchlib=/usr/lib/perl/5.14 -Dvendorprefix=/usr
-Dvendorlib=/usr/share/perl5 -Dvendorarch=/usr/lib/perl5
-Dsiteprefix=/usr/local -Dsitelib=/usr/local/share/perl/5.14.2
-Dsitearch=/usr/local/lib/perl/5.14.2 -Dman1dir=/usr/share/man/man1
-Dman3dir=/usr/share/man/man3 -Dsiteman1dir=/usr/local/man/man1
-Dsiteman3dir=/usr/local/man/man3 -Duse64bitint -Dman1ext=1 -Dman3ext=3perl
-Dpager=/usr/bin/sensible-pager -Uafs -Ud_csh -Ud_ualarm -Uusesfio -Uusenm
-Ui_libutil -DDEBUGGING=-g -Doptimize=-O2 -Duseshrplib
-Dlibperl=libperl.so.5.14.2 -des'
    hint=recommended, useposix=true, d_sigaction=define
    useithreads=define, usemultiplicity=define
    useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef
    use64bitint=define, use64bitall=undef, uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='cc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -DDEBIAN
-fstack-protector -fno-strict-aliasing -pipe -I/usr/local/include
-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
    optimize='-O2 -g',
    cppflags='-D_REENTRANT -D_GNU_SOURCE -DDEBIAN -fstack-protector
-fno-strict-aliasing -pipe -I/usr/local/include'
    ccversion='', gccversion='4.7.2', gccosandvers=''
    intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=12345678
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12
    ivtype='long long', ivsize=8, 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/i386-linux-gnu /lib/../lib
/usr/lib/i386-linux-gnu /usr/lib/../lib /lib /usr/lib
    libs=-lgdbm -lgdbm_compat -ldb -ldl -lm -lpthread -lc -lcrypt
    perllibs=-ldl -lm -lpthread -lc -lcrypt
    libc=, so=so, useshrplib=true, libperl=libperl.so.5.14.2
    gnulibc_version='2.13'
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E'
    cccdlflags='-fPIC', lddlflags='-shared -L/usr/local/lib
-fstack-protector'

Locally applied patches:



@INC for perl 5.14.2:
    /etc/perl
    /usr/local/lib/perl/5.14.2
    /usr/local/share/perl/5.14.2
    /usr/lib/perl5
    /usr/share/perl5
    /usr/lib/perl/5.14
    /usr/share/perl/5.14
    /usr/local/lib/site_perl
    .


Environment for perl 5.14.2:
    HOME=/home/xungeng
    LANG=en_US.UTF-8
    LANGUAGE=en_US:en
    LD_LIBRARY_PATH=/usr/local/lib/
    LOGDIR (unset)

PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games:/home/xungeng/bin:/usr/local/go/bin
    PERL_BADLANG (unset)
    SHELL=/bin/bash

@p5pRT
Copy link
Author

p5pRT commented Jan 30, 2013

From @iabyn

On Tue, Jan 29, 2013 at 10​:38​:14PM -0800, Xungeng Lee wrote​:

see this example​:
xungeng@​debian​:~/work/test/test$ cat foo
#!/usr/bin/perl
use FileHandle;
use IPC​::Open2;
use IO​::Handle;

#*STDOUT = IO​::Handle->new;

for (1..3) {
print STDERR "Loop​: $_\n";
$pid = open2( \*Reader, \*Writer, "cat" );
Writer->autoflush(); # default here, actually
print Writer "stuff\n";
$got = <Reader>;
print STDERR $got;
}
xungeng@​debian​:~/work/test/test$ cat bar
#!/usr/bin/perl
use FileHandle;
use IPC​::Open2;
use IO​::Handle;

*STDOUT = IO​::Handle->new;

for (1..3) {
print STDERR "Loop​: $_\n";
$pid = open2( \*Reader, \*Writer, "cat" );
Writer->autoflush(); # default here, actually
print Writer "stuff\n";
$got = <Reader>;
print STDERR $got;
}
xungeng@​debian​:~/work/test/test$ ./foo > /dev/null
Loop​: 1
stuff
Loop​: 2
stuff
Loop​: 3
stuff
xungeng@​debian​:~/work/test/test$ ./bar > /dev/null
Loop​: 1
Loop​: 2
Loop​: 3

the difference between foo and bar is only that STDOUT redirected or not.

when STDOUT is redirected, open2 make the child process write to the old
STDOUT,
not the child_out handler (\*Reader in this example).

Well for stdout, IPC​::Open3 (which IPC​::Open2 calls out to) does
essentially​:

  pipe(\*Reader, \*FOO);
  fork();
  if (child) {
  close(Writer);
  open(STDOUT, ">&=" . fileno(FOO));
  exec($cmd);
  }

i.e. it dups the file handle of the pipe to whatever file handle STDOUT
maps to. If STDOUT doesn't point to file handle 1, then it won't work.

I don't understand Open3.pm enough to decide whether it's unreasonable for
it to handle a non-1 STDOUT (etc) or not.

--
Any [programming] language that doesn't occasionally surprise the
novice will pay for it by continually surprising the expert.
  -- Larry Wall

@p5pRT
Copy link
Author

p5pRT commented Jan 30, 2013

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