Apologies in advance that this post has got a bit longer than I expected when I started ...
I'm using Wheel::Run to run a program in a child process and catch stdout and stderr. This works fine when the program is run in a terminal, but when I daemonize it using Proc::Daemon, something strange happens -- the stdout and stderr from the child "disappears". I've searched the archives and the effect is the same as that described by Matthew Hicks in a thread of similar name back in Sept 2005, and I've found that his solution also works for me (edit Proc::Daemon to change it to stop it re-opening STDIN to /dev/null. I also found I had to stop it reopening STDERR as well). I also see it's in the bug list as #16691 (from Chris Fedde, with a different work around). This prompted me to try a third course of action: change Proc::Daemon so it only runs POSIX::close for file descriptors 3 and up and not for 0, 1, 2. Change: foreach $i (0 .. OpenMax) { POSIX::close($i); } to foreach $i (3 .. OpenMax) { POSIX::close($i); } This also fixes the problem, so I'm guessing that there's some interaction between POSIX::close and a subsequent perl open that causes the problem. (The perl FAQ makes no mention of POSIX::close in its section on daemonization). Not sure if this is a Linux thing or what? (I'm using RHEL3, perl 5.8.0, POE 0.33). However, in the course of investigating this, I've found a simple illustration of the problem. I started with the "Child Processes 2" example from the cookbook (http://poe.perl.org/?POE_Cookbook/Child_Processes_2). This example runs "ls -1 /" as the child. I added the following 6 lines before the POE::Session->create: use Proc::Daemon; # Proc::Daemon::init(); open STDOUT, ">$ENV{HOME}/xx.stdout" or die "! $ENV{HOME}/xx.stdout : $!"; open STDERR, ">$ENV{HOME}/xx.stderr" or die "! $ENV{HOME}/xx.stderr : $!"; open O, ">$ENV{HOME}/xx.log" or die "! $ENV{HOME}/xx.log : $!"; select O; $| = 1; I also added another argument to the program that's run to make it give an error message on stderr, so it now reads: ( Program => [ "/bin/ls", "-1", "/", "/non-exist" ], # Program to run. When I run it, it produces the listing of / in xx.log. The lines are prefixed by "STDOUT: ", showing that they were written by the got_child_stdout() event handler and the error line for /non-exist is prefixed "STDERR: ". xx.stdout is an empty file and xx.stderr contains a line "Child process PID:xxx reaped:". If I uncomment the Proc::Daemon::init() line and run again, the effect is different. This time, xx.log just contains the line "child closed." (from the got_child_close() event handler). xx.stdout contains the ls of /. And xx.stderr contains a whole load of lines saying "Child process PID:0 reaped:" (over 88000 of them in one case, over 1400 on another machine). The error line for /non-exist is buried in the middle somewhere and the file ends with the reaped message for the real child pid. This seems to imply that somehow the child gets the original pre-daemonization stdout and stderr, although I'm not sure how, after they've been POSIX::closed and re-opened in Proc::Daemon and then piped by Wheel::Run. And it seems that waitpid() keeps returning 0 (instead of -1?) in Resources/Signals.pm, l.156. Anyway, applying any of the 3 changes above, fixes the problem. best regards, John Escott.