DZone Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

Snippets has posted 5883 posts at DZone. View Full User Profile

Properly Daemonize A Process

  • submit to reddit
use File::Basename;
use Fcntl qw(LOCK_EX LOCK_NB);
use strict;

my $ProgramName = basename($0);

open(SELFLOCK, "<$0") or die("Couldn't open $0: $!\n");
flock(SELFLOCK, LOCK_EX | LOCK_NB) or die("Aborting: another $ProgramName is already running\n");

# Do any necessary preliminary checks (e.g. check a config file)

# Get ready to daemonize by redirecting our output to syslog, requesting that logger prefix the lines with our program name:
open(STDOUT, "|-", "logger -t $ProgramName") or die("Couldn't open logger output stream: $!\n");
open(STDERR, ">&STDOUT") or die("Couldn't redirect STDERR to STDOUT: $!\n");
$| = 1; # Make output line-buffered so it will be flushed to syslog faster

chdir('/'); # Avoid the possibility of our working directory resulting in keeping an otherwise unused filesystem in use

# Double-fork to avoid leaving a zombie process behind:
exit if (fork());
exit if (fork());
sleep 1 until getppid() == 1;

print "$ProgramName $$ successfully daemonized\n";

# do something useful


Snippets Manager replied on Mon, 2006/06/05 - 5:28am

This didn't work for me on linux (2.6.8 kernel; perl 5.8.4). Instead, my program got stuck in the sleep 1 loop. What did work was this snippet from 'man perlipc': use POSIX 'setsid'; sub daemonize { chdir '/' or die "Can't chdir to /: $!"; open STDIN, '/dev/null' or die "Can't read /dev/null: $!"; open STDOUT, '>/dev/null' or die "Can't write to /dev/null: $!"; defined(my $pid = fork) or die "Can't fork: $!"; exit if $pid; setsid or die "Can't start a new session: $!"; open STDERR, '>&STDOUT' or die "Can't dup stdout: $!"; }