Interesting open3 redirection problem

U

usenet

Consider this little complete perl program, intended to imitate a
shell's
gcc -v -E -x c - </dev/null >/dev/null
command:

#!/usr/bin/env perl

use warnings;
use strict;
use File::Spec;
use IPC::Open3;

# WORKS: shell$ gcc -v -E -x c - </dev/null >/dev/null
# WORKS: my @cmd = ('gcc', '-v', '-E', '-x', 'c', '/dev/null');

# This one never gets out of the while loop.
my @cmd = ('gcc', '-v', '-E', '-x', 'c', '-');

if (open (my $NULLOUT, ">", File::Spec->devnull)) {
if (open (my $NULLIN, "<", File::Spec->devnull)) {
my $pid = open3 ($NULLIN, $NULLOUT, \*CMD, @cmd);
while (<CMD>) {
print;
}
print "left while(<CMD>)\n";
waitpid ($pid, 0);
close CMD;
close $NULLIN;
}
close $NULLOUT;
}

I wonder why it never gets out of the "while" loop, but apparently
hangs somewhere waiting to read input that never arrives (after
printing gcc's stderr correctly). ps(1) says its wait channel it
piperd,
$ ps -o wchan,args|grep perl
piperd perl ./o3.pl (perl5.8.8)

I'm stumped. Does any perl guru know what's going on and how to
correct the situation?

Regards, Jens
 
X

Xho Jingleheimerschmidt

#!/usr/bin/env perl

use warnings;
use strict;
use File::Spec;
use IPC::Open3;


# This one never gets out of the while loop.
my @cmd = ('gcc', '-v', '-E', '-x', 'c', '-');

if (open (my $NULLOUT, ">", File::Spec->devnull)) {
if (open (my $NULLIN, "<", File::Spec->devnull)) {
my $pid = open3 ($NULLIN, $NULLOUT, \*CMD, @cmd);

First you open $NULLOUT to be a handle hooked up to write to null.
Then you close it, and reopen it to be a handle hooked up to write to
gcc (which means gcc is hooked up to read, as its stdin, what you write
to $NULLOUT). Since you neither write to nor close $NULLOUT, gcc blocks
waiting for you to do one of those.
I'm stumped. Does any perl guru know what's going on and how to
correct the situation?

If you want gcc to read directly from the handle, (rather than read what
Perl writes *to* that handle) then the docs to open3 say you specify the
first argument to open3 to start with "<&" (which means you probably
can't use a lexical filehandle, at least not easily)

Of course, to do that, you should open the handle $NULLIN to be read
from, not written to, or else gcc will complain that its stdin is not
open for reading.

But if you want @cmd to inherit a close file stdin, why not just specify
a first argument of undef to open3?

Xho
 

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,968
Messages
2,570,154
Members
46,702
Latest member
LukasConde

Latest Threads

Top