(I understand there are some existing questions on SO about the same topic and I have read top answers. Those answers are good but I still have something unclear.) Recently I came across a piece of Python for creating daemon process in Unix system: sample code And the piece I want to talk about:
def daemonize(self):
"""
do the UNIX double-fork magic, see Stevens' "Advanced
Programming in the UNIX Environment" for details (ISBN 0201563177)
http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC16
"""
try:
pid = os.fork()
if pid > 0:
# exit first parent
sys.exit(0)
except OSError, e:
sys.stderr.write("fork #1 failed: %d (%s)\n" % (e.errno, e.strerror))
sys.exit(1)
# decouple from parent environment
os.chdir("/")
os.setsid()
os.umask(0)
# do second fork
try:
pid = os.fork()
if pid > 0:
# exit from second parent
sys.exit(0)
except OSError, e:
sys.stderr.write("fork #2 failed: %d (%s)\n" % (e.errno, e.strerror))
sys.exit(1)
# redirect standard file descriptors
sys.stdout.flush()
sys.stderr.flush()
si = file(self.stdin, 'r')
so = file(self.stdout, 'a+')
se = file(self.stderr, 'a+', 0)
os.dup2(si.fileno(), sys.stdin.fileno())
os.dup2(so.fileno(), sys.stdout.fileno())
os.dup2(se.fileno(), sys.stderr.fileno())
# write pidfile
atexit.register(self.delpid)
pid = str(os.getpid())
file(self.pidfile,'w+').write("%s\n" % pid)
So the process is:
- Create a fork of current process and kill parent process. So in this case forked process 1 is an orphan now.
- decouple from parent environment--why do we do this? does that mean by setting sid of forked process 1, we can isolate the forked process? at this point, forked process 1 has its own process group and session(equals to its pid), which means it is an session leader, which means it is possible to acquire a new control terminal.
- fork again and kill forked process 1. forked process 2 now is also an orphan. and it is definitely not a session leader(forked process 1 was). and it does not share anything with the original parent process environment.
- do in/out/err redirection.
So is my understanding correct about the process of creating a daemon process? Also some people mentioned "this can prevent zombie processes" in SO question, why is this piece of code even related to zombie process? Parent will be killed so that the process is monitored by init, is not that what "daemon" means?
Some people also mention that forking once should give us a good daemon process already. Any example for this? Any example(system) under which fork once may not just work as a good daemon?