my $pid = open(my $FROM_KID, "-|"); die("Failed fork: $!") unless defined($pid); if ($pid) # parent { chomp(my $output = do { local $/; <$FROM_KID> }); waitpid($pid, 0); printf <<'RESULT', $output, $? >> 8; Child output: %s Exit: %d RESULT } else { daemonize_self("", undef); # leave stdout alone exec "date" or die("Failed exec: $!"); } #### use Cwd (); use POSIX (); use File::Spec; sub daemonize_self { my ($stdout_log, $stderr_log) = @_; # new session & process group leader, and no controlling tty die("daemonize_self: Cannot detach from controlling tty") if POSIX::setsid() < 0; # ignore signals for my $s (qw(INT HUP TTIN TTOU TSTP)) { $SIG{$s} = sub { }; # not "IGNORE", not inherited } $SIG{CHLD} = "IGNORE"; # inherited default to reap kids $SIG{TERM} = "DEFAULT"; # be lenient: redirect stdin, stdout, stderr my $DEVNULL = File::Spec->devnull(); open(*STDIN, "<", $DEVNULL) or die("daemonize_self: Cannot silence STDIN", "\n ", $!); unless (defined($stdout_log) && $stdout_log eq "") { open(*STDOUT, ">>", defined($stdout_log) ? $stdout_log : $DEVNULL) or die("daemonize_self: Cannot redirect STDOUT", "\n ", $!); } unless (defined($stderr_log) && $stderr_log eq "") { open(*STDERR, ">>", defined($stderr_log) ? $stderr_log : $DEVNULL) or die("daemonize_self: Cannot redirect STDERR", "\n ", $!); } # close all other file descriptors POSIX::close($_) for 3 .. 1024; # reset file creation mask umask 0; # change current working dir to root chdir(File::Spec->rootdir()); }