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

IPC::Open3 does not auto-create an error handle #9372

Closed
p5pRT opened this issue Jun 10, 2008 · 13 comments
Closed

IPC::Open3 does not auto-create an error handle #9372

p5pRT opened this issue Jun 10, 2008 · 13 comments

Comments

@p5pRT
Copy link

p5pRT commented Jun 10, 2008

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

Searchable as RT55570$

@p5pRT
Copy link
Author

p5pRT commented Jun 10, 2008

From fiji@ayup.limey.net

Created by fiji@ayup.limey.net

The POD for IPC​::Open3 says​:
  my($wtr, $rdr, $err);
  $pid = open3($wtr, $rdr, $err, 'some cmd and args', 'optarg', ...);

However, that always results in an undef $err.

Looking at the source of the module I see (in the sub _open3)​:
  unless (eval {
  $dad_wtr = $_[1] = gensym unless defined $dad_wtr && length $dad_wtr;
  $dad_rdr = $_[2] = gensym unless defined $dad_rdr && length $dad_rdr;
  1; })

It clearly is not doing the magic to autogenerate the $err handle.

Either the POD or the code needs to be fixed... the current behavior
ends up with the STDERR being sent to STDOUT.

Perl Info

Flags:
    category=core
    severity=medium

This perlbug was built using Perl v5.8.8 in the Red Hat build system.
It is being executed now by Perl v5.8.8 - Mon Nov 26 14:23:46 EST 2007.

Site configuration information for perl v5.8.8:

Configured by Red Hat, Inc. at Mon Nov 26 14:23:46 EST 2007.

Summary of my perl5 (revision 5 version 8 subversion 8) configuration:
  Platform:
    osname=linux, osvers=2.6.20-1.3001.fc6xen, archname=i386-linux-thread-multi
    uname='linux xenbuilder4.fedora.phx.redhat.com 2.6.20-1.3001.fc6xen #1 smp thu aug 9 16:18:42 edt 2007 i686 i686 i386 gnulinux '
    config_args='-des -Doptimize=-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m32 -march=i386 -mtune=generic -fasynchronous-unwind-tables -Dversion=5.8.8 -Dmyhostname=localhost -Dperladmin=root@localhost -Dcc=gcc -Dcf_by=Red Hat, Inc. -Dinstallprefix=/usr -Dprefix=/usr -Darchname=i386-linux -Dvendorprefix=/usr -Dsiteprefix=/usr -Duseshrplib -Dusethreads -Duseithreads -Duselargefiles -Dd_dosuid -Dd_semctl_semun -Di_db -Ui_ndbm -Di_gdbm -Di_shadow -Di_syslog -Dman3ext=3pm -Duseperlio -Dinstallusrbinperl=n -Ubincompat5005 -Uversiononly -Dpager=/usr/bin/less -isr -Dd_gethostent_r_proto -Ud_endhostent_r_proto -Ud_sethostent_r_proto -Ud_endprotoent_r_proto -Ud_setprotoent_r_proto -Ud_endservent_r_proto -Ud_setservent_r_proto -Dinc_version_list=5.8.7 5.8.6 5.8.5 -Dscriptdir=/usr/bin'
    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='gcc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing -pipe -Wdeclaration-after-statement -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -I/usr/include/gdbm',
    optimize='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m32 -march=i386 -mtune=generic -fasynchronous-unwind-tables',
    cppflags='-D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing -pipe -Wdeclaration-after-statement -I/usr/local/include -I/usr/include/gdbm'
    ccversion='', gccversion='4.1.2 20070925 (Red Hat 4.1.2-27)', 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='gcc', ldflags =' -L/usr/local/lib'
    libpth=/usr/local/lib /lib /usr/lib
    libs=-lresolv -lnsl -lgdbm -ldb -ldl -lm -lcrypt -lutil -lpthread -lc
    perllibs=-lresolv -lnsl -ldl -lm -lcrypt -lutil -lpthread -lc
    libc=/lib/libc-2.6.so, so=so, useshrplib=true, libperl=libperl.so
    gnulibc_version='2.6'
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E -Wl,-rpath,/usr/lib/perl5/5.8.8/i386-linux-thread-multi/CORE'
    cccdlflags='-fPIC', lddlflags='-shared -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m32 -march=i386 -mtune=generic -fasynchronous-unwind-tables -L/usr/local/lib'

Locally applied patches:
    


@INC for perl v5.8.8:
    /usr/lib/perl5/site_perl/5.8.8/i386-linux-thread-multi
    /usr/lib/perl5/site_perl/5.8.8/i386-linux-thread-multi
    /usr/lib/perl5/site_perl/5.8.8
    /usr/lib/perl5/vendor_perl/5.8.8/i386-linux-thread-multi
    /usr/lib/perl5/vendor_perl/5.8.8/i386-linux-thread-multi
    /usr/lib/perl5/vendor_perl/5.8.8
    /usr/lib/perl5/site_perl/5.8.8/i386-linux-thread-multi
    /usr/lib/perl5/site_perl/5.8.7/i386-linux-thread-multi
    /usr/lib/perl5/site_perl/5.8.6/i386-linux-thread-multi
    /usr/lib/perl5/site_perl/5.8.5/i386-linux-thread-multi
    /usr/lib/perl5/site_perl/5.8.8
    /usr/lib/perl5/site_perl/5.8.7
    /usr/lib/perl5/site_perl/5.8.6
    /usr/lib/perl5/site_perl/5.8.5
    /usr/lib/perl5/site_perl
    /usr/lib/perl5/vendor_perl/5.8.8/i386-linux-thread-multi
    /usr/lib/perl5/vendor_perl/5.8.7/i386-linux-thread-multi
    /usr/lib/perl5/vendor_perl/5.8.6/i386-linux-thread-multi
    /usr/lib/perl5/vendor_perl/5.8.5/i386-linux-thread-multi
    /usr/lib/perl5/vendor_perl/5.8.8
    /usr/lib/perl5/vendor_perl/5.8.7
    /usr/lib/perl5/vendor_perl/5.8.6
    /usr/lib/perl5/vendor_perl/5.8.5
    /usr/lib/perl5/vendor_perl
    /usr/lib/perl5/5.8.8/i386-linux-thread-multi
    /usr/lib/perl5/5.8.8
    .


Environment for perl v5.8.8:
    HOME=/home/fiji
    LANG=en_US
    LANGUAGE (unset)
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=/usr/lib/qt-3.3/bin:/usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin:/usr/lib/jre/bin:/sbin:/usr/sbin/:/usr/local/sbin:.:/home/fiji/bin
    PERL5LIB=/usr/lib/perl5/site_perl/5.8.8/i386-linux-thread-multi:/usr/lib/perl5/site_perl/5.8.8:/usr/lib/perl5/vendor_perl/5.8.8/i386-linux-thread-multi:/usr/lib/perl5/vendor_perl/5.8.8
    PERL_BADLANG (unset)
    SHELL=/bin/bash

@p5pRT
Copy link
Author

p5pRT commented Jun 11, 2008

From renee.baecker@smart-websolutions.de

This is a small patch that solves the problem​:

rbaecker@​www-devel-rbaecker ~/perl510/perl-5.10.0 $ ./perl -Ilib
../bugs/open.pl
test at /home/rbaecker/perl510/bugs/test.pl line 6.
rbaecker@​www-devel-rbaecker ~/perl510/perl-5.10.0 $ cd ../test/perl-5.10.0
rbaecker@​www-devel-rbaecker ~/perl510/test/perl-5.10.0 $ ./perl -Ilib
../../bugs/open.pl
Use of uninitialized value $err in <HANDLE> at ../../bugs/open.pl line 11.
readline() on unopened filehandle at ../../bugs/open.pl line 11.
rbaecker@​www-devel-rbaecker ~/perl510/perl-5.10.0 $ cat ../bugs/open.pl
#!/usr/bin/perl

use strict;
use warnings;
use IPC​::Open3;

my ($wtr,$rdr,$err);

my $pid = open3($wtr,$rdr,$err,'perl /home/rbaecker/perl510/bugs/test.pl');

print <$err>;

rbaecker@​www-devel-rbaecker ~/perl510/perl-5.10.0 $ cat ../bugs/test.pl
#!/usr/bin/perl

use strict;
use warnings;

warn "test";

rbaecker@​www-devel-rbaecker ~/perl510/perl-5.10.0 $

Another related bug report is #31738
(http​://rt.perl.org/rt3/Ticket/Display.html?id=31738)

--
Renée Bäcker
renee.baecker@​smart-websolutions.de

XING​: http​://www.xing.com/profile/Renee_Baecker
Foo-Magazin​: http​://foo-magazin.de

@p5pRT
Copy link
Author

p5pRT commented Jun 11, 2008

From renee.baecker@smart-websolutions.de

open3.patch
--- ../test/perl-5.10.0/lib/IPC/Open3.pm	2007-12-18 11:47:07.000000000 +0100
+++ lib/IPC/Open3.pm	2008-06-11 12:20:30.000000000 +0200
@@ -194,7 +194,7 @@
     unless (eval  {
 	$dad_wtr = $_[1] = gensym unless defined $dad_wtr && length $dad_wtr;
 	$dad_rdr = $_[2] = gensym unless defined $dad_rdr && length $dad_rdr;
-	1; }) 
+	$dad_err = $_[3] = gensym unless defined $dad_err && length $dad_err; }) 
     {
 	# must strip crud for croak to add back, or looks ugly
 	$@ =~ s/(?<=value attempted) at .*//s;

@p5pRT
Copy link
Author

p5pRT commented Jun 11, 2008

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

@p5pRT
Copy link
Author

p5pRT commented Jun 11, 2008

From p5p@perl.wizbit.be

Citeren "fiji@​ayup.limey.net (via RT)" <perlbug-followup@​perl.org>​:

-----------------------------------------------------------------
[Please enter your report here]

The POD for IPC​::Open3 says​:
my($wtr, $rdr, $err);
$pid = open3($wtr, $rdr, $err, 'some cmd and args', 'optarg', ...);

However, that always results in an undef $err.

[...]

It clearly is not doing the magic to autogenerate the $err handle.

Either the POD or the code needs to be fixed... the current behavior
ends up with the STDERR being sent to STDOUT.

-----------------------------------------------------------------

If you read further in the POD it says​:

'If either reader or writer is the null string, this will be replaced
by an autogenerated filehandle.'

Which doesn't talk about $err.

But what has to change?

Changing the code might break a program that relies on $err being the
same as $wtr when undef is passed...

Kind regards,

Bram

@p5pRT
Copy link
Author

p5pRT commented Jun 11, 2008

From renee.baecker@smart-websolutions.de

Sorry, the doc says​:

"If CHLD_ERR is false, or the same file descriptor as CHLD_OUT, then
STDOUT and STDERR of the child are on the same filehandle."

So the behaviour is documented. But it is really confusing to define a
variable for the error filehandle and then it is never used...

Renée Bäcker wrote​:

This is a small patch that solves the problem​:
...

--

Renée Bäcker
renee.baecker@​smart-websolutions.de

XING​: http​://www.xing.com/profile/Renee_Baecker
Foo-Magazin​: http​://foo-magazin.de

@p5pRT
Copy link
Author

p5pRT commented Jun 11, 2008

From ben@morrow.me.uk

Quoth p5p@​perl.wizbit.be (Bram)​:

Citeren "fiji@​ayup.limey.net (via RT)" <perlbug-followup@​perl.org>​:

The POD for IPC​::Open3 says​:
my($wtr, $rdr, $err);
$pid = open3($wtr, $rdr, $err, 'some cmd and args', 'optarg', ...);

However, that always results in an undef $err.

[...]

It clearly is not doing the magic to autogenerate the $err handle.

Either the POD or the code needs to be fixed... the current behavior
ends up with the STDERR being sent to STDOUT.

-----------------------------------------------------------------

If you read further in the POD it says​:

'If either reader or writer is the null string, this will be replaced
by an autogenerated filehandle.'

Which doesn't talk about $err.

But what has to change?

The pod. Something like

  use Symbol qw/gensym/;
  my ($rdr, $wtr, $err);
  open3($rdr, $wtr, $err = gensym, ...);

Changing the code might break a program that relies on $err being the
same as $wtr when undef is passed...

Yes. This (unfortunate) API decision is why Open3 couldn't be updated to
auto-viv filehandles when that idea was invented.

Ben

--
  The cosmos, at best, is like a rubbish heap scattered at random.
  Heraclitus
  ben@​morrow.me.uk

@p5pRT
Copy link
Author

p5pRT commented Jun 11, 2008

From @ikegami

--- ../test/perl-5.10.0/lib/IPC/Open3.pm 2007-12-18
11​:47​:07.000000000 +0100
+++ lib/IPC/Open3.pm 2008-06-11 12​:20​:30.000000000 +0200
@​@​ -194,7 +194,7 @​@​
unless (eval {
$dad_wtr = $_[1] = gensym unless defined $dad_wtr && length $dad_wtr;
$dad_rdr = $_[2] = gensym unless defined $dad_rdr && length $dad_rdr;
- 1; })
+ $dad_err = $_[3] = gensym unless defined $dad_err && length
$dad_err; })
{
# must strip crud for croak to add back, or looks ugly
$@​ =~ s/(?<=value attempted) at .*//s;

That patch would break compatibility with the documented behaviour.
One solution is to use gensym.

use IPC​::Open3 qw( open3 );
use Symbol qw( gensym );

my $pid = open3(
  my $to_chld = gensym(),
  my $fr_chld = gensym(),
  my $fr_chld_err = gensym(),
  'command', 'with', 'args'
);

@p5pRT
Copy link
Author

p5pRT commented Jun 13, 2008

From @rgs

2008/6/11 Ben Morrow <ben@​morrow.me.uk>​:

If you read further in the POD it says​:

'If either reader or writer is the null string, this will be replaced
by an autogenerated filehandle.'

Which doesn't talk about $err.

But what has to change?

The pod. Something like

use Symbol qw/gensym/;
my ($rdr, $wtr, $err);
open3($rdr, $wtr, $err = gensym, ...);

Changing the code might break a program that relies on $err being the
same as $wtr when undef is passed...

Yes. This (unfortunate) API decision is why Open3 couldn't be updated to
auto-viv filehandles when that idea was invented.

I tend to agree with that. But such an API modification would go with
a dual-lifing.

@p5pRT
Copy link
Author

p5pRT commented Jan 7, 2009

From mark.zealey@pipex.net

Hi all, could we get a doc change for this as was suggested​:

use Symbol qw/gensym/;
my ($rdr, $wtr, $err);
open3($rdr, $wtr, $err = gensym, ...);

It's misleading at the moment as the example given in the docs doesn't
do what you expect.

Thanks,

Mark

@p5pRT
Copy link
Author

p5pRT commented Jan 12, 2009

From module@renee-baecker.de

On Mi. 07. Jan. 2009, 08​:06​:40, mzealey wrote​:

Hi all, could we get a doc change for this as was suggested​:

use Symbol qw/gensym/;
my ($rdr, $wtr, $err);
open3($rdr, $wtr, $err = gensym, ...);

It's misleading at the moment as the example given in the docs doesn't
do what you expect.

Thanks,

Mark

Hi Mark,

can you provide a small patch and send it to Perl 5 Porters
(perl5-porters@​perl.org)?

Cheers,
Renee

@p5pRT
Copy link
Author

p5pRT commented Sep 14, 2012

From bitcard@profvince.com

Thanks for your report. Looks like this issue was a duplicate of RT
#31738, which has been fixed in december 2011.

Vincent

@p5pRT
Copy link
Author

p5pRT commented Sep 14, 2012

bitcard@profvince.com - Status changed from 'open' to 'resolved'

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

1 participant