From cc7f595adc014635cc50279a81816b504262732a Mon Sep 17 00:00:00 2001 From: benoitc Date: Mon, 22 Apr 2013 21:43:59 +0200 Subject: [PATCH] Enable stdio inheritance. Enable inheritance for stdio file descriptors in daemon mode. It allows you in daemon mode to redirect the output to a file if needed. By default in daemon mode gunicorn will close all file handle except if you pass the "-R" options. In this cases STDIO will be preserved. fix #309 --- gunicorn/app/base.py | 3 ++- gunicorn/config.py | 14 ++++++++++++++ gunicorn/util.py | 34 ++++++++++++++++++++++++++++------ 3 files changed, 44 insertions(+), 7 deletions(-) diff --git a/gunicorn/app/base.py b/gunicorn/app/base.py index 832abff0..4a708de9 100644 --- a/gunicorn/app/base.py +++ b/gunicorn/app/base.py @@ -119,8 +119,9 @@ class Application(object): if self.cfg.spew: debug.spew() + if self.cfg.daemon: - util.daemonize() + util.daemonize(self.cfg.enable_stdio_inheritance) # set python paths if self.cfg.pythonpath and self.cfg.pythonpath is not None: diff --git a/gunicorn/config.py b/gunicorn/config.py index 18630f37..b4cca552 100644 --- a/gunicorn/config.py +++ b/gunicorn/config.py @@ -1292,3 +1292,17 @@ class SyslogFacility(Setting): desc = """\ Syslog facility name """ + + +class EnableStdioInheritance(Setting): + name = "enable_stdio_inheritance" + section = "Logging" + cli = ["-R", "--enable-stdio-inheritance"] + validator = validate_bool + default = False + action = "store_true" + desc = """\ + Enable stdio inheritance + + Enable inheritance for stdio file descriptors in daemon mode. + """ diff --git a/gunicorn/util.py b/gunicorn/util.py index 697d934c..262b9604 100644 --- a/gunicorn/util.py +++ b/gunicorn/util.py @@ -403,7 +403,15 @@ def is_hoppish(header): return header.lower().strip() in hop_headers -def daemonize(): +def disable_stdout_buffering(): + _old_write = sys.stdout.write + def _write(*args, **kwargs): + _old_write(*args, **kwargs) + sys.stdout.flush() + + sys.stdout.write = _write + +def daemonize(enable_stdio_inheritance=False): """\ Standard daemonization of a process. http://www.svbug.com/documentation/comp.unix.programmer-FAQ/faq_2.html#SEC16 @@ -417,13 +425,27 @@ def daemonize(): os._exit(0) os.umask(0) + maxfd = get_maxfd() - closerange(0, maxfd) - - os.open(REDIRECT_TO, os.O_RDWR) - os.dup2(0, 1) - os.dup2(0, 2) + if not enable_stdio_inheritance: + closerange(0, maxfd) + os.open(REDIRECT_TO, os.O_RDWR) + os.dup2(0, 1) + os.dup2(0, 2) + else: + closerange(3, maxfd) + os.open(REDIRECT_TO, os.O_RDWR) + for stream in (sys.stdin, sys.stdout, sys.stderr): + fd = stream.fileno() + try: + if stream.isatty(): + os.close(fd) + if fd in (1, 2): + os.dup2(0, fd) + except AttributeError: + pass + disable_stdout_buffering() def seed(): try: