Reputation: 19037
I've got the following design in a perl script:
my $child_pid = fork;
if( ! $child_pid ){
# do some stuff...
exec( $user_specified_command );
else{
# wait for child to exit
waitpid( $child_pid, 0 );
}
# Continue with the script
I'm interested in getting an alert in the parent when the child execs, so that I can get some details about $user_specified_command
(specifically, to use lsof
to find out if stdout is redirected to a regular file). The result would be something like this:
my $child_pid = fork;
if( ! $child_pid ){
# do some stuff...
exec( $user_specified_command );
else{
# wait until the child exec's
wait_child_exec();
# do some stuff...
# wait for child to exit
waitpid( $child_pid, 0 );
}
# Continue with the script
I could loop and grep ps
output until the name changes, but it seems like exec is a serious enough event that there's a better way.
Upvotes: 1
Views: 220
Reputation: 58631
One general approach to this is to create a pipe in the parent which is inherited by the child, and have the parent block (or poll) the read end of the pipe.
Assuming the child has FD_CLOEXEC or, better, a suitable value of $^F
, the child's call to exec()
will close the pipe's write end and generate an EOF for the parent:
# Run a command in a child process, returning to the parent only after
# the child process has called exec'd or, failing that, terminated.
#
# WARNING - this code not rigorously tested
#
sub spawn_patiently {
my ($rd, $wr);
return unless pipe($rd, $wr);
# XXX This assumes $^F is less than fileno($wr)
# In practice, you'd want it to be less than fileno($rd), too
my $pid = fork();
return unless defined $pid;
if (! $pid) {
exec @_;
die "exec: $!";
}
# parent - wait for child to exec
close($wr);
read($rd, my $dummy, 1);
1;
}
Upvotes: 2