Skip to content

Instantly share code, notes, and snippets.

@jaggzh
Created June 18, 2024 14:00
Show Gist options
  • Save jaggzh/5997433a18bfc2ecfff168889b647510 to your computer and use it in GitHub Desktop.
Save jaggzh/5997433a18bfc2ecfff168889b647510 to your computer and use it in GitHub Desktop.
package Proc::Knife;
use strict;
use warnings;
use v5.36;
use Exporter 'import';
use POSIX ":sys_wait_h";
our @EXPORT_OK = qw(knife);
sub knife {
my @cmd = @{shift()};
my %opts = @_;
my $pid = fork // die "A: Can't fork child: $!";
if ($pid == 0) {
$pid = fork // die "B: Can't fork grandchild: $!";
if ($pid == 0) {
exec @cmd;
die "C: Can't exec \@cmd: $!";
}
exit;
}
waitpid $pid, 0;
}
1;
=head1 NAME
Proc::Knife - Spawn and free child processes by double-forking
=head1 SYNOPSIS
use Proc::Knife;
knife(["somecommand", "somearg"]);
=head1 DESCRIPTION
The C<knife> function double forks and cleans up (waitpid) the first child, so the grandchild is free
(severed at its umbilical cord) from the parent. This allows the grandchild process to run independently
without becoming a zombie. This module does not manage stdin/out/err.
See L<Proc::Daemon> if you require more control over the process handling.
=head1 FUNCTIONS
=head2 knife
knife($command_array_ref);
Executes the commands specified in C<$command_array_ref>. This function will double fork to ensure that
the grandchild process is entirely detached from the parent process.
=head1 SEE ALSO
L<Proc::Daemon>
=head1 AUTHOR
Jaggz H. <jaggz.h {over at} gmail.com>
=cut
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment