Greetings ... I am writing a daemon utility which forks off a child, that may execute fairly arbitrary code (defined by a series of external files which get eval'd in), which given the nature of the daemon to initate build requests, will most likely include many calls to system(), thus creating dubious sub-children, whose output I'd like to catch using the same pipe, ideally ... but the problem is that their output doesn't get caught by my pipe call.
So ... the execute subroutine goes something like so:
# ... in another init subroutine, the external files get eval'd in,
# defining code references and data structures, in preparation
# for this task_exec subroutine ...
sub task_exec {
# ... perform pre-init ...
if($pid = fork){
# ... parent: save $pid in a hash record ...
} else {
# first child, set up pipes:
pipe(CHILD_RDR, PARENT_WTR);
CHILD_RDR->autoflush(1);
PARENT_WTR->autoflush(1);
if($fpid = fork()){
select(PARENT_WTR);
open(STDERR, ">&PARENT_WTR"); # merge STDOUT with STDERR
# execute a list of code references, defined in a global structure:
foreach $step (@{$TasksByName{$p{task}{steps}}}){
chdir($p{sandbox});
# execute the actual step code, some sequences might
# go something like system("./configure") or "make"
if(&$step( ... pass some stuff ... ) != 0){
print STDERR "something bad happened!\n";
exit(1);
}
}
kill 'INT' => $fpid; # sent interrupt to child reader
waitpid($fpid, 0);
exit(0);
} else {
# child reader, essentially acts like the "tee" program
$fdout = new IO::File("> $p{sandbox}/task.out");
if(!$fdout){
die "can't open output file: $!";
}
$SIG{INT} = sub {
print STDERR "caught SIGINT, exiting!\n";
close(CHILD_RDR);
$fdout->close();
exit(0);
};
while(defined($l=<CHILD_RDR>)){
print $fdout $l;
}
exit(0);
}
exit(0); # first child
}
}
So, what's happening is that the contents of &$step(...) subroutines in turn call various commands via system(...), the output of which I would like to catch in my pipe call, which is currently not happening. The contents of &$step is defined in a series of external files that get eval'd in at init time, which also define pretty sophisticated structured data to be communicated to the server, which is why I chose this eval-centric approach in the first place (as opposed to doing something like system("task-script.pl > task.out").
What does your wisdom dictate that I should do? (And hopefully I'm explaining my predicament clearly enough.)
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |