(a.k.a. filehandle/STDIN/STDOUT/STDERR weirdness)
The Perl Standard Library IPC::Open2 (and it's counterpart Open3) are functions much like the built-in function, open(), except that give simultaneous access to the STDIN,
print [[PROC_STDIN]] "do something\n";<br /> $ret=<PROC_STDOUT>;<br /> print "Got $ret back from binary\n";7
...and so perform reasonably sequential operations in your code. The well documented caveat is Unix buffering is likely to mess you up. Most Unix binaries aren't designed to be operated from Pipes, so don't work very well with Open2(). If you control the source code to the binary however, you can arrange that for each line of input, you output exactly one line (and ensure that input/output buffering is switched off).
Update: Use Proc::Daemon (from CPAN) to daemonise your process - it (correctly) opens /dev/null for filehandles 0,1 and 2.
There is another (seemingly undocumented) problem with Open2() (and possibly other functions). It's in a fairly obscure case when you're trying to daemonise your Perl program.
Usually, when becoming a daemon, you would perform a fork(), lose the process group, the controlling TTY, perform another fork() and close all your filehandles (here's an example bit of Perl). The trouble comes in when that (now daemonised) process tries to Open2() another process. For some reason (and I haven't fully worked this out), the other process misunderstands the filehandles it opens.
In my application, the daemon runs an indexing process. The indexer's job is to read it's config, then read a filename from STDIN, process it and return results on how it got on (to it's STDOUT). This all works fine, except if started by a daemon. Having played about with "strace" ("truss", if you're a Solaris user), I found that the index process would start-up (loading libraries and the like), then open it's config file. The system allocates it filehandle 0 for this, which it subsequently seems to use as it's
It is possible that my indexer process is at fault here. However, the indexer's "confusion" about what is
Another workaround is to write a wrapper around your daemon process. First, remove the daemonise code from the daemon, and move it to the wrapper. Now, the wrapper starts up, half-daemonises, starts your program via an ordinary open() call, closes STDIN,