From: Angus Lees Date: Tue, 21 Apr 2015 01:04:33 +0000 (+1000) Subject: Take Daemon stdin/stdout/stderr args as file objects X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=274713450c4f4cc1f5c466e153b72c9764dd96c9;p=openstack-build%2Fneutron-build.git Take Daemon stdin/stdout/stderr args as file objects Previously Daemon constructor took stdin/stdout/stderr as paths (defaulting to '/dev/null') and opened them as regular files. This greatly limits the type of filehandles supported (no pipes, for example), and doesn't allow simple things like reusing existing fds. This change switches to accepting file objects rather than strings, and uses a sentinal value to represent the previous "open /dev/null" default behaviour. Change-Id: I51b36ce912194abd89ed46fad9943802f271444a --- diff --git a/neutron/agent/linux/daemon.py b/neutron/agent/linux/daemon.py index f9866445f..f180f5432 100644 --- a/neutron/agent/linux/daemon.py +++ b/neutron/agent/linux/daemon.py @@ -29,6 +29,8 @@ from neutron.i18n import _LE, _LI LOG = logging.getLogger(__name__) +DEVNULL = object() + def setuid(user_id_or_name): try: @@ -155,8 +157,8 @@ class Daemon(object): Usage: subclass the Daemon class and override the run() method """ - def __init__(self, pidfile, stdin='/dev/null', stdout='/dev/null', - stderr='/dev/null', procname='python', uuid=None, + def __init__(self, pidfile, stdin=DEVNULL, stdout=DEVNULL, + stderr=DEVNULL, procname='python', uuid=None, user=None, group=None, watch_log=True): self.stdin = stdin self.stdout = stdout @@ -192,9 +194,10 @@ class Daemon(object): # redirect standard file descriptors sys.stdout.flush() sys.stderr.flush() - stdin = open(self.stdin, 'r') - stdout = open(self.stdout, 'a+') - stderr = open(self.stderr, 'a+', 0) + devnull = open(os.devnull, 'w+') + stdin = devnull if self.stdin is DEVNULL else self.stdin + stdout = devnull if self.stdout is DEVNULL else self.stdout + stderr = devnull if self.stderr is DEVNULL else self.stderr os.dup2(stdin.fileno(), sys.stdin.fileno()) os.dup2(stdout.fileno(), sys.stdout.fileno()) os.dup2(stderr.fileno(), sys.stderr.fileno()) diff --git a/neutron/tests/unit/agent/linux/test_daemon.py b/neutron/tests/unit/agent/linux/test_daemon.py index 7293ae4b3..b4bb355e1 100644 --- a/neutron/tests/unit/agent/linux/test_daemon.py +++ b/neutron/tests/unit/agent/linux/test_daemon.py @@ -242,6 +242,8 @@ class TestDaemon(base.BaseTestCase): d._fork() def test_daemonize(self): + self.os.devnull = '/dev/null' + d = daemon.Daemon('pidfile') with mock.patch.object(d, '_fork') as fork: with mock.patch.object(daemon, 'atexit') as atexit: