Commit 79634555 authored by Iustin Pop's avatar Iustin Pop
Browse files

Abstract daemon file descriptor setup

This does some slight changes:

- Daemonize() doesn't explicitly close the file-descriptors anymore, but
  only implicitly via the usage of dup2
- StartDaemonChild uses separate devnull for stdin (rdonly) and
  stdout/stderr (wronly), or if using a log file, it uses it in append
Signed-off-by: default avatarIustin Pop <>
Reviewed-by: default avatarMichael Hanselmann <>
parent 0260032c
......@@ -252,6 +252,38 @@ def SetupDaemonEnv(cwd="/", umask=077):
def SetupDaemonFDs(output_file, output_fd):
"""Setups up a daemon's file descriptors.
@param output_file: if not None, the file to which to redirect
@param output_fd: if not None, the file descriptor for stdout/stderr
# check that at most one is defined
assert [output_file, output_fd].count(None) >= 1
# Open /dev/null (read-only, only for stdin)
devnull_fd =, os.O_RDONLY)
if output_fd is not None:
elif output_file is not None:
# Open output file
output_fd =,
os.O_WRONLY | os.O_CREAT | os.O_APPEND, 0600)
except EnvironmentError, err:
raise Exception("Opening output file failed: %s" % err)
output_fd =, os.O_WRONLY)
# Redirect standard I/O
os.dup2(devnull_fd, 0)
os.dup2(output_fd, 1)
os.dup2(output_fd, 2)
def StartDaemon(cmd, env=None, cwd="/", output=None, output_fd=None,
"""Start a daemon process after forking twice.
......@@ -398,27 +430,7 @@ def _StartDaemonChild(errpipe_read, errpipe_write,
fd_pidfile = None
# Open /dev/null
fd_devnull =, os.O_RDWR)
assert not output or (bool(output) ^ (fd_output is not None))
if fd_output is not None:
elif output:
# Open output file
# TODO: Implement flag to set append=yes/no
fd_output =, os.O_WRONLY | os.O_CREAT, 0600)
except EnvironmentError, err:
raise Exception("Opening output file failed: %s" % err)
fd_output = fd_devnull
# Redirect standard I/O
os.dup2(fd_devnull, 0)
os.dup2(fd_output, 1)
os.dup2(fd_output, 2)
SetupDaemonFDs(output, fd_output)
# Send daemon PID to parent
RetryOnSignal(os.write, pidpipe_write, str(os.getpid()))
......@@ -2162,14 +2174,7 @@ def Daemonize(logfile):
os._exit(0) # Exit parent of the first child.
for fd in range(3):
i ="/dev/null", os.O_RDONLY) # stdin
assert i == 0, "Can't close/reopen stdin"
i =, os.O_WRONLY|os.O_CREAT|os.O_APPEND, 0600) # stdout
assert i == 1, "Can't close/reopen stdout"
# Duplicate standard output to standard error.
os.dup2(1, 2)
SetupDaemonFDs(logfile, None)
return 0
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment