Fugu
view release on metacpan or search on metacpan
lib/Fugu/Process.pod view on Meta::CPAN
The number of seconds to wait before the method stops the child. The
default is no limit.
=item C<stdin>
A string to feed to the child on its standard input.
=item C<cwd>
A directory to run the child in. The child calls chdir(2) after the
fork and before the execve(2), so the working directory of the caller
does not change. A chdir(2) in the caller would change the meaning of
every other relative path in the program, and a second call that ran
at the same time would race it.
A directory that the child cannot enter is a startup failure with the
reason in C<error>, not a silent run in the wrong place.
=item C<env>
The environment of the child, exactly as on C<spawn_command()>.
=item C<passthrough>
Let the child write straight to the caller's terminal. C<stdout> and
C<stderr> then come back empty.
=item C<new_session>
If this argument is true, the child calls setsid(2) before the
redirect. The default is false.
The child then leads a new session and a new process group, and its
group id equals its pid. On a timeout the method signals the whole
group, in the capture form and in the passthrough form alike. A
grandchild that holds a pipe open therefore dies with the child, and
the read of the pipes ends.
setsid(2) removes the controlling terminal. A child with
C<new_session> cannot read the terminal and cannot hold the
foreground. Do not combine C<new_session> with a command that prompts
on the terminal under C<passthrough>.
=back
The method reads standard output and standard error at the same time.
A reader that took them in sequence would deadlock: a child that fills
one pipe blocks until someone drains it.
=head2 exit_code
C<exit_code($status)> maps a raw waitpid(2) status, or the return
value of C<system>, to an exit code between 0 and 255. The low byte
holds the terminating signal. The high byte holds the exit code. A
value of -1 means the child never started.
A caller that gives a raw status to C<exit> turns a remote exit code
of 1 into C<exit(256)>, which the kernel truncates to 0. That silently
reports a failed command as a success.
=head2 is_alive
C<is_alive($pid)> reports if a process exists and is not a zombie. The
check reaps a zombie child as a side effect and then reports it as not
alive. A caller that needs the exit status uses C<run()>, or waits
itself.
=head2 terminate
C<terminate($pid, %args)> sends C<SIGTERM>, waits, and sends
C<SIGKILL> if the process continues to run.
These are the arguments:
=over 4
=item C<grace_period>
The number of seconds to wait between the two signals. The default is
5.
=item C<on_kill>
A code reference that the method calls when the process is gone.
=item C<group>
If this argument is true, each signal goes to the process group of
C<$pid>. The default is false.
C<$pid> must be the pid of a process-group leader. C<run()> with
C<new_session> and C<spawn_command()> with C<daemonize> each make
one. The method sends C<SIGTERM> to the group, waits for the grace
period, and sends C<SIGKILL> to the group when a member is still
alive.
The liveness test differs between the two forms. The default form
asks C<is_alive($pid)>, which reaps a zombie child. The group form
asks kill(2) with signal 0 on the group, and it reaps each child
member first. A group can outlive its leader, so the group form does
not return early on a dead leader.
=back
The wait polls with sub-second granularity. Thus a child that stops at
once does not cost a whole second.
=head2 wait_exit
C<wait_exit($pid, $timeout)> polls until the process exits or until
the timeout ends. The default for C<$timeout> is 30 seconds.
=head2 spawn_perl
C<spawn_perl(%args)> runs Perl code in a child process. It gives the
child the parent's C<-I> paths. The parent gets these paths from
C<-I>, C<use lib> or C<PERL5LIB>. Thus the child sees the same
modules.
C<code> is the program text. C<args> is an array reference of
arguments for the program. The method gives all other arguments to
C<spawn_command()>, so C<env> works here too.
The paths travel as C<-I> flags in the argument list, not in
C<PERL5LIB>. An C<env> argument that clears the environment
therefore costs the child no module.
=head1 RETURN VALUES
C<spawn_command()> and C<spawn_perl()> return a hash reference. On
success, the hash holds C<success> set to 1 and C<pid>. On failure,
C<success> is 0 and C<error> gives the cause.
C<run()> returns a hash reference that holds C<success>, C<stdout>,
C<stderr>, C<exit_code> and C<timed_out>. On a failure to start the
child, it also holds C<error>. C<success> is 1 only when the child
exited with code 0 and did not time out.
C<exit_code()> returns a number between 0 and 255.
C<is_alive()> returns 1 or 0.
C<terminate()> returns 1 if the process is gone. It returns 0 if the
process continues after C<SIGKILL>. In the group form, it returns 1
when no member of the group answers kill(2) with signal 0. It returns
0 when a member answers after C<SIGKILL>.
C<wait_exit()> returns 1 if the process exits in the timeout period.
If not, it returns 0.
=head1 EXAMPLES
This example runs a helper and then stops it:
my $r = Fugu::Process->spawn_command(
cmd => [ 'mdnsctl', 'publish', $name, '_hap', 'tcp', $port ],
);
Fugu::Process->terminate($r->{pid}, grace_period => 10)
if $r->{success};
=head1 ERRORS
No method dies. The methods report failures through the hash reference
or the boolean value that they return.
=head1 SEE ALSO
execve(2), kill(2), setsid(2), waitpid(2), L<Fugu::Log>,
L<Fugu::Pidfile>
=head1 AUTHORS
Dick Olsson E<lt>hi@senzilla.ioE<gt>
=head1 CAVEATS
C<run()> holds the whole output of the child in memory. Do not use it
for a command that writes without a bound.
C<is_alive()> calls waitpid(2). That call reaps only the children of
the caller. For all other processes, it uses kill(2) with signal 0.
This signal cannot show the difference between a live process and a
zombie.
The group form of C<terminate()> cannot wait for a member that is not
a child of the caller. A member that init(8) has yet to reap can
therefore still answer for a moment after the method returns.
The operating system uses process IDs again for new processes. The
module cannot show the difference between the initial process and a
later process with the same number.
=cut
( run in 1.169 second using v1.01-cache-2.11-cpan-14f38c9f855 )