kees has asked for the wisdom of the Perl Monks concerning the following question:

Can anyone explain why fileno in xfileno of the Open3.pm module returns undef in case if the following code is used, see below. This happens on Linux with perl 5.8.8 and Open3.pm 1.03. I also checked Open3.pm 1.09 and did not see any difference. I was not able to reproduce this with a own .pm file included. Background: I would like to write something that is able to launch a process in background (both Unix/Linux/Windows) and keep STDIN/STDOUT/STDERR connected AND allows to use select (on Windows, pipes cannot be used for select).
use strict; use IO::Socket; use IPC::Open3; my $childwriter; my $childreader; socketpair($childwriter, $childreader, AF_UNIX, SOCK_STREAM, PF_UNSPEC +) || die "socketpair: $!"; my $stderrchildwriter; my $stderrchildreader; socketpair($stderrchildwriter, $stderrchildreader, AF_UNIX, SOCK_STREA +M, PF_UNSPEC) || die "socketpair: $!"; my (@cmd) = "java -version 2>&1"; print "File handles:\n"; printf "out: $childwriter (%d), $childreader (%d)\n", fileno($childwri +ter), fileno($childreader); printf "err: $stderrchildwriter (%d), $stderrchildreader (%d)\n", file +no($stderrchildwriter), fileno($stderrchildreader); my $childpid = open3("<&$childreader", ">&$childreader", ">&$stderrchi +ldreader", @cmd);
BTW: IPC::Open3 does not take care for the fact that fileno(STDIN) == fileno(badhandle)also evaluates to true in case of fileno(STDIN) == 0 (which is often the case).

Replies are listed 'Best First'.
Re: fileno unexpectly returns undef (stringify)
by tye (Sage) on Feb 23, 2012 at 16:13 UTC

    When I call socketpair() as you did, each of the two undef'd variables I passed in get set to contain ref to a glob. Turning such into a string (as you do) just gives me something like "GLOB(0x8080814)", which is pretty useless to open3.

    - tye        

Re: fileno unexpectly returns undef
by Eliya (Vicar) on Feb 23, 2012 at 16:56 UTC

    To elaborate on what tye said:  due to the stringification problem, lexical file handles can't be used with the "<&" / ">&" feature.  Use "old-style" file handles instead:

    socketpair(STDERRCHILDWRITER, STDERRCHILDREADER, AF_UNIX, SOCK_STREAM, PF_UNSPEC) || die "socketpair: $ +!";

    and then specify them as ">&STDERRCHILDREADER", etc. to open3().

    (Can't say, though, whether this will eventually help with your stated cross-platform goal — but it should at least get rid of the immediate problem...)

      Thanks all for your reply. The main reason that I liked to use sockets was the drop of performance on Windows when using open3 to schedule a lot of processes (whith each having a pipe reader thread on stdout and stderr). The scheduler seems to hang on either launching new processes, or on the threaded-pipe-reader.

      The advantage of using sockets is that I can use select (also on Windows. select on pipes is not possible, and I did not like to work with Win32 WaitForMultipleObjects). I'm about finished with a prototype (not using open3 anymore), which seems to look promising (actually, I was able to get about 100% load on my dual six-core HT system).