Explorar o código

Daemon: Redirect standard fds to /dev/null

Ask Solem %!s(int64=12) %!d(string=hai) anos
pai
achega
0ebbc5ff9e
Modificáronse 2 ficheiros con 20 adicións e 3 borrados
  1. 20 2
      celery/platforms.py
  2. 0 1
      celery/tests/app/test_log.py

+ 20 - 2
celery/platforms.py

@@ -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)

+ 0 - 1
celery/tests/app/test_log.py

@@ -219,7 +219,6 @@ class test_default_logger(AppCase):
             p.flush()
             p.close()
             self.assertFalse(p.isatty())
-            self.assertIsNone(p.fileno())
 
     def test_logging_proxy_recurse_protection(self):
         logger = self.setup_logger(loglevel=logging.ERROR, logfile=None,