IPC::Open2 - Bad File Descriptor

B

Bernard Chan

Dear All,

I am pretty new to the area of pipes and IPC in general. I'm currently
experimenting with it in different ways trying to understand how it works.

I tried the following simple command:

$ LANG=C perl -MIPC::Open2 -e 'open2(">&1", "<&0", "ls", "-l",
"/dev/shm")'
total 4
-rw-rw-r-- 1 bernardchan bernardchan 3204 Mar 6 16:00 test.txt
open2: close(0) failed: Bad file descriptor at -e line 1


As you can see, what I would like to do is simple: to run an "ls -l" and
pipe the output directly to STDOUT and have any input (of course none for
this case of "ls") read from STDIN. I can get back the desired output, but
I also receive the error that open2() cannot close the read filehandle.

This is actually a simplified version - my original version used a socket
(IO::Socket::INET6) in place of STDIN and STDOUT. The problem was similar.

Anyone has some insights about what I am doing wrong?

TIA.

Regards,
Bernard Chan.
 
B

Ben Morrow

Quoth Bernard Chan said:
Dear All,

I am pretty new to the area of pipes and IPC in general. I'm currently
experimenting with it in different ways trying to understand how it works.

I tried the following simple command:

$ LANG=C perl -MIPC::Open2 -e 'open2(">&1", "<&0", "ls", "-l",
"/dev/shm")'
total 4
-rw-rw-r-- 1 bernardchan bernardchan 3204 Mar 6 16:00 test.txt
open2: close(0) failed: Bad file descriptor at -e line 1


As you can see, what I would like to do is simple: to run an "ls -l" and
pipe the output directly to STDOUT and have any input (of course none for
this case of "ls") read from STDIN. I can get back the desired output, but
I also receive the error that open2() cannot close the read filehandle.

This is actually a simplified version - my original version used a socket
(IO::Socket::INET6) in place of STDIN and STDOUT. The problem was similar.

Anyone has some insights about what I am doing wrong?

The correct syntax is

open2('>&STDOUT', '<&STDIN', 'ls', '-l', '/dev/shm');

You are getting that error because open2 is attempting to use the
filehandle called '0' (as opposed to fd 0): as this filehandle isn't
open, you get 'bad file descriptor'. The redirection happens to work
because open2 uses the '<&FILEHANDLE' open syntax internally, which
treats numbers as fds rather than filehandles.

You may find IPC::Run easier to work with, not least because open2 seems
to require you to use bareword filehandles, which are not considered
good practice nowadays. (Is it even possible to create a bareword
filehandle to a socket, except by using the raw socket function?)

Ben
 
C

comp.llang.perl.moderated

Dear All,

I am pretty new to the area of pipes and IPC in general. I'm currently
experimenting with it in different ways trying to understand how it works.

I tried the following simple command:

$ LANG=C perl -MIPC::Open2 -e 'open2(">&1", "<&0", "ls", "-l",
"/dev/shm")'
total 4
-rw-rw-r-- 1 bernardchan bernardchan 3204 Mar 6 16:00 test.txt
open2: close(0) failed: Bad file descriptor at -e line 1
...

You were close...

open2('>&=0', '<&=0', ... )
From 'perldoc -f open' :

If you specify '<&=X', where "X" is a file
descriptor number or a filehandle, then Perl
will do an equivalent of C's "fdopen" of that
file
 
U

Uri Guttman

BM> You may find IPC::Run easier to work with, not least because open2 seems
BM> to require you to use bareword filehandles, which are not considered
BM> good practice nowadays. (Is it even possible to create a bareword
BM> filehandle to a socket, except by using the raw socket function?)

you could always store in a lexical a Symbol::gensym for any handle
thing for ages, even open2. and recent versions of perl will autovivify
the handles in open2 (and open3) if you use lexicals. for some reason in
open3, the stderr handle still needs to be passed in but again, you can
use gensym in a lexical and never go near bareword handles.

uri
 
B

Ben Morrow

Quoth "comp.llang.perl.moderated said:
You were close...

open2('>&=0', '<&=0', ... )

Did you try it?

~% perl -MIPC::Open2 -e 'open2(">&=1", "<&=0", "ls", "-l", "/dev/shm")'
total 0
open2: close(=0) failed: Bad file descriptor at -e line 1

Still get the warning, for the same reason: open2 is explicitly trying
to close \*{"=0"}, which isn't open.
If you specify '<&=X', where "X" is a file
descriptor number or a filehandle, then Perl
will do an equivalent of C's "fdopen" of that
file

open2 ne open.

Ben
 
B

Ben Morrow

Quoth Uri Guttman said:
BM> You may find IPC::Run easier to work with, not least because open2 seems
BM> to require you to use bareword filehandles, which are not considered
BM> good practice nowadays. (Is it even possible to create a bareword
BM> filehandle to a socket, except by using the raw socket function?)

you could always store in a lexical a Symbol::gensym for any handle
thing for ages,

Of course.
even open2.

Perhaps I wasn't clear: I was specifically talking about the '>&FOO'
syntax for open2 which performs a dup instead of a pipe. In this case I
can't see any way to use a lexical FH, as open2 (well,
IPC::Open3::_open3) explicitly refers to \*{$dad_rdr}, where $dad_rdr is
">&FOO" =~ s/^[<>]&// .

Ben
 
U

Uri Guttman

BM> Perhaps I wasn't clear: I was specifically talking about the '>&FOO'
BM> syntax for open2 which performs a dup instead of a pipe. In this case I
BM> can't see any way to use a lexical FH, as open2 (well,
BM> IPC::Open3::_open3) explicitly refers to \*{$dad_rdr}, where $dad_rdr is
BM> ">&FOO" =~ s/^[<>]&// .

perhaps you can first call open to dup the handle and have it autovivify
it and pass that to open2/3? i haven't followed this thread closely so i
don't know what the dup is being used for, etc. i am sure there are ways
to keep it all lexical as those still have the handle name as a string
in their globs. the only diff is that there is no global name for the
handle. Symbol::gensym does the same thing - it actually creates a new
unique handle name (with magic ++) in its namespace, gets a ref to it
and then deletes the symbol itself so it becomes private.

uri
 
C

comp.llang.perl.moderated

Quoth "comp.llang.perl.moderated" <[email protected]>:






Did you try it?

~% perl -MIPC::Open2 -e 'open2(">&=1", "<&=0", "ls", "-l", "/dev/shm")'
total 0
open2: close(=0) failed: Bad file descriptor at -e line 1

Still get the warning, for the same reason: open2 is explicitly trying
to close \*{"=0"}, which isn't open.



open2 ne open.

Thanks, I did try it but lost the error. It is interesting though
that IPC::Open3 (but not IPC::Open2) says:

...
The filehandles may also be integers, in which case they are
understood as file descriptors.

which, for reasons I didn't follow in the code, avoids the error:

$ perl -MIPC::Open2 -e 'open2(">&=1", ">&=0" , "ls", "-l", "/dev/
null")'
lrwxrwxrwx 1 root other 27 Oct 9 2001 /dev/null ->
../devices/pseudo/mm@0:null
open2: close(=0) failed: Bad file number at -e line 1

vs.

$ perl -MIPC::Open2 -e 'open2(">&=1", 0 , "ls", "-l", "/dev/null")'
lrwxrwxrwx 1 root other 27 Oct 9 2001 /dev/null ->
../devices/pseudo/mm@0:null
 
A

anno4000

Ben Morrow said:
Quoth Bernard Chan <[email protected]>:
[...]

You may find IPC::Run easier to work with, not least because open2 seems
to require you to use bareword filehandles, which are not considered
good practice nowadays.

That's no problem:

use IPC::Open2;

my $pid = open2( my( $read, $write), 'sort');
print $write "$_\n" for qw( ccc bbb aaa);
close $write;
print while <$read>;

Anno
 
B

Ben Morrow

Quoth (e-mail address removed)-berlin.de:
Ben Morrow said:
Quoth Bernard Chan <[email protected]>:
[...]

You may find IPC::Run easier to work with, not least because open2 seems
to require you to use bareword filehandles, which are not considered
good practice nowadays.

That's no problem:

use IPC::Open2;

my $pid = open2( my( $read, $write), 'sort');
print $write "$_\n" for qw( ccc bbb aaa);
close $write;
print while <$read>;

Yes, but the OP's case was more like

use IPC::Open2;

open FOO, '>', 'foo';
open BAR, '<', 'bar';

my $pid = open2 '>&FOO', '<&BAR', 'sort';

which requires bareword FHs to dup.

Ben
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,819
Latest member
masterdaster

Latest Threads

Top