diff --git a/gunicorn/arbiter.py b/gunicorn/arbiter.py index 26baeedc..d799c7f0 100644 --- a/gunicorn/arbiter.py +++ b/gunicorn/arbiter.py @@ -80,7 +80,7 @@ class Arbiter(object): """ Really initialize the arbiter. Strat to listen and set pidfile if needed.""" self.pid = os.getpid() self.init_signals() - self.LISTENER = create_socket(self.address) + self.LISTENER = create_socket(self.conf) self.pidfile = self.opts.get("pidfile") self.log.info("Booted Arbiter: %s" % os.getpid()) self.log.info("Listening on socket: %s" % self.LISTENER) diff --git a/gunicorn/main.py b/gunicorn/main.py index 93316987..739c5f4b 100644 --- a/gunicorn/main.py +++ b/gunicorn/main.py @@ -70,7 +70,7 @@ def configure_logging(opts): h.setFormatter(logging.Formatter("%(asctime)s - %(levelname)s %(message)s")) logger.addHandler(h) -def daemonize(umask): +def daemonize(): """ if daemon option is set, this function will daemonize the master. It's based on this activestate recipe : http://code.activestate.com/recipes/278731/ @@ -78,8 +78,8 @@ def daemonize(umask): if not 'GUNICORN_FD' in os.environ: if os.fork() == 0: os.setsid() - if os.fork() == 0: - os.umask(umask) + if os.fork() != 0: + os.umask(0) else: os._exit(0) else: @@ -113,9 +113,8 @@ def main(usage, get_app): arbiter = Arbiter(conf.address, conf.workers, app, config=conf, debug=conf['debug'], pidfile=conf['pidfile']) if conf['daemon']: - daemonize(conf['umask']) + daemonize() else: - os.umask(conf['umask']) os.setpgrp() configure_logging(conf) arbiter.run() @@ -150,9 +149,8 @@ def paste_server(app, global_conf=None, host="127.0.0.1", port=None, arbiter = Arbiter(conf.address, conf.workers, app, debug=conf["debug"], pidfile=conf["pidfile"], config=conf) if conf["daemon"] : - daemonize(conf["umask"]) + daemonize() else: - os.umask(conf['umask']) os.setpgrp() configure_logging(conf) arbiter.run() diff --git a/gunicorn/management/commands/run_gunicorn.py b/gunicorn/management/commands/run_gunicorn.py index c30cfd73..27419f29 100644 --- a/gunicorn/management/commands/run_gunicorn.py +++ b/gunicorn/management/commands/run_gunicorn.py @@ -74,9 +74,8 @@ class Command(BaseCommand): arbiter = Arbiter(conf.address, conf.workers, handler, pidfile=conf['pidfile'], config=conf) if conf['daemon']: - daemonize(conf['umask']) + daemonize() else: - os.umask(conf['umask']) os.setpgrp() configure_logging(conf) arbiter.run() diff --git a/gunicorn/sock.py b/gunicorn/sock.py index 97c9d0f2..003d1690 100644 --- a/gunicorn/sock.py +++ b/gunicorn/sock.py @@ -10,12 +10,15 @@ import socket import sys import time +from gunicorn import util + log = logging.getLogger(__name__) class BaseSocket(object): - def __init__(self, addr, fd=None): - self.address = addr + def __init__(self, conf, fd=None): + self.conf = conf + self.address = conf.address if fd is None: sock = socket.socket(self.FAMILY, socket.SOCK_STREAM) else: @@ -31,10 +34,13 @@ class BaseSocket(object): def set_options(self, sock, bound=False): sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) if not bound: - sock.bind(self.address) + self.bind(sock) sock.setblocking(0) sock.listen(2048) return sock + + def bind(self, sock): + sock.bind(sock) class TCPSocket(BaseSocket): @@ -55,24 +61,33 @@ class UnixSocket(BaseSocket): FAMILY = socket.AF_UNIX - def __init__(self, addr, fd=None): + def __init__(self, conf, fd=None): if fd is None: try: - os.remove(addr) + os.remove(conf.address) except OSError: pass - super(UnixSocket, self).__init__(addr, fd=fd) + super(UnixSocket, self).__init__(conf, fd=fd) def __str__(self): return "unix:%s" % self.address + + def bind(self, sock): + old_umask = os.umask(self.conf['umask']) + sock.bind(self.address) + util.chown(self.address, self.conf.uid, self.conf.gid) + os.umask(old_umask) -def create_socket(addr): +def create_socket(conf): """ Create a new socket for the given address. If the address is a tuple, a TCP socket is created. If it is a string, a Unix socket is created. Otherwise a TypeError is raised. """ + # get it only once + addr = conf.address + if isinstance(addr, tuple): sock_type = TCPSocket elif isinstance(addr, basestring): @@ -83,7 +98,7 @@ def create_socket(addr): if 'GUNICORN_FD' in os.environ: fd = int(os.environ.pop('GUNICORN_FD')) try: - return sock_type(addr, fd=fd) + return sock_type(conf, fd=fd) except socket.error, e: if e[0] == errno.ENOTCONN: log.error("GUNICORN_FD should refer to an open socket.") @@ -96,7 +111,7 @@ def create_socket(addr): for i in range(5): try: - return sock_type(addr) + return sock_type(conf) except socket.error, e: if e[0] == errno.EADDRINUSE: log.error("Connection in use: %s" % str(addr))