|
@@ -253,6 +253,13 @@ def _create_pidlock(pidfile):
|
|
|
return pidlock
|
|
|
|
|
|
|
|
|
+def fileno(f):
|
|
|
+ try:
|
|
|
+ return f.fileno()
|
|
|
+ except AttributeError:
|
|
|
+ pass
|
|
|
+
|
|
|
+
|
|
|
class DaemonContext(object):
|
|
|
_is_open = False
|
|
|
workdir = DAEMON_WORKDIR
|
|
@@ -263,6 +270,12 @@ class DaemonContext(object):
|
|
|
self.workdir = workdir or self.workdir
|
|
|
self.umask = self.umask if umask is None else umask
|
|
|
self.fake = fake
|
|
|
+ self.stdfds = (sys.stdin, sys.stdout, sys.stderr)
|
|
|
+
|
|
|
+ def redirect_to_null(self, fd):
|
|
|
+ if fd:
|
|
|
+ dest = os.open(os.devnull, os.O_RDWR)
|
|
|
+ os.dup2(dest, fd)
|
|
|
|
|
|
def open(self):
|
|
|
if not self._is_open:
|
|
@@ -272,9 +285,14 @@ class DaemonContext(object):
|
|
|
os.chdir(self.workdir)
|
|
|
os.umask(self.umask)
|
|
|
|
|
|
+ preserve = [fileno(f) for f in self.stdfds if fileno(f)]
|
|
|
for fd in reversed(range(get_fdmax(default=2048))):
|
|
|
- with ignore_EBADF():
|
|
|
- os.close(fd)
|
|
|
+ if fd not in preserve:
|
|
|
+ with ignore_EBADF():
|
|
|
+ os.close(fd)
|
|
|
+
|
|
|
+ for fd in self.stdfds:
|
|
|
+ self.redirect_to_null(fileno(fd))
|
|
|
|
|
|
os.open(DAEMON_REDIRECT_TO, os.O_RDWR)
|
|
|
os.dup2(0, 1)
|