use POSIX qw{ setsid getcwd close sysconf _SC_OPEN_MAX }; ... foreach my $i (0 .. openmax()) { POSIX::close($i); } open(STDIN, "+>/dev/null"); open(STDOUT, "+>&STDIN"); open(STDERR, "+>&STDIN"); # ignore these signals for (qw(TSTP TTIN TTOU PIPE POLL STOP CONT CHLD)) { $SIG{$_} = 'IGNORE' if (exists $SIG{$_}); } # handle these signals for (qw(INT HUP ABRT QUIT TRAP TERM)) { $SIG{$_} = 'interrupt' if (exists $SIG{$_}); } unless (my $pid = fork()) { exit if $pid; POSIX::setsid; # set session id chdir '/'; # change to root directory umask 0; # clear the file creation mask while(1) { # do whatever your daemon needs to do ... } } sub interrupt { # do whatever to gracefully shutdown ... die "$0 terminated successfully.\n"; }