From 274713450c4f4cc1f5c466e153b72c9764dd96c9 Mon Sep 17 00:00:00 2001 From: Angus Lees Date: Tue, 21 Apr 2015 11:04:33 +1000 Subject: [PATCH] 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 --- neutron/agent/linux/daemon.py | 13 ++++++++----- neutron/tests/unit/agent/linux/test_daemon.py | 2 ++ 2 files changed, 10 insertions(+), 5 deletions(-) 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: -- 2.45.2