| 1 | #!/usr/bin/python2.3
|
|---|
| 2 |
|
|---|
| 3 | import os
|
|---|
| 4 | import sys
|
|---|
| 5 |
|
|---|
| 6 | if os.name == 'posix':
|
|---|
| 7 |
|
|---|
| 8 | def become_daemon(ourHomeDir='.',outLog='/dev/null',errLog='/dev/null'):
|
|---|
| 9 | """
|
|---|
| 10 | Robustly turn us into a UNIX daemon, running in ourHomeDir.
|
|---|
| 11 | Modelled after the original code of this module and some
|
|---|
| 12 | sample code from the net.
|
|---|
| 13 | """
|
|---|
| 14 |
|
|---|
| 15 | # first fork
|
|---|
| 16 | try:
|
|---|
| 17 | if os.fork() > 0:
|
|---|
| 18 | sys.exit(0) # kill off parent
|
|---|
| 19 | except OSError, e:
|
|---|
| 20 | sys.stderr.write("fork #1 failed: (%d) %s\n" % (e.errno, e.strerror))
|
|---|
| 21 | sys.exit(1)
|
|---|
| 22 | os.setsid()
|
|---|
| 23 | os.chdir(ourHomeDir)
|
|---|
| 24 | os.umask(0)
|
|---|
| 25 | # second fork
|
|---|
| 26 | try:
|
|---|
| 27 | if os.fork() > 0:
|
|---|
| 28 | sys.exit(0)
|
|---|
| 29 | except OSError, e:
|
|---|
| 30 | sys.stderr.write("fork #2 failed: (%d) %s\n" % (e.errno, e.strerror))
|
|---|
| 31 | sys.exit(1)
|
|---|
| 32 |
|
|---|
| 33 | si = open('/dev/null', 'r')
|
|---|
| 34 | so = open(outLog, 'a+', 0)
|
|---|
| 35 | se = open(errLog, 'a+', 0)
|
|---|
| 36 | os.dup2(si.fileno(), sys.stdin.fileno())
|
|---|
| 37 | os.dup2(so.fileno(), sys.stdout.fileno())
|
|---|
| 38 | os.dup2(se.fileno(), sys.stderr.fileno())
|
|---|
| 39 |
|
|---|
| 40 | else:
|
|---|
| 41 |
|
|---|
| 42 | def become_daemon(ourHomeDir='.',outLog=None,errLog=None):
|
|---|
| 43 | """
|
|---|
| 44 | If we are not running under a POSIX system, just simulate
|
|---|
| 45 | the daemon mode by doing redirections and directory changeing
|
|---|
| 46 | """
|
|---|
| 47 |
|
|---|
| 48 | os.chdir(ourHomeDir)
|
|---|
| 49 | os.umask(0)
|
|---|
| 50 | sys.stdin.close()
|
|---|
| 51 | sys.stdout.close()
|
|---|
| 52 | sys.stderr.close()
|
|---|
| 53 | if errLog and outLog:
|
|---|
| 54 | sys.stderr=open (errLog, 'a', 0)
|
|---|
| 55 | sys.stdout=open (outLog, 'a', 0)
|
|---|
| 56 | elif errLog:
|
|---|
| 57 | sys.stderr=open (errLog, 'a', 0)
|
|---|
| 58 | sys.stdout=NullDevice ()
|
|---|
| 59 | elif outLog:
|
|---|
| 60 | sys.stdout=open (outLog, 'a', 0)
|
|---|
| 61 | sys.stderr=NullDevice ()
|
|---|
| 62 | else:
|
|---|
| 63 | sys.stdout = NullDevice()
|
|---|
| 64 | sys.stderr = NullDevice()
|
|---|
| 65 |
|
|---|
| 66 | class NullDevice:
|
|---|
| 67 | """
|
|---|
| 68 | A substitute for stdout and stderr that writes to nowhere.
|
|---|
| 69 | This is a substitute for /dev/null
|
|---|
| 70 | """
|
|---|
| 71 |
|
|---|
| 72 | def write(self, s):
|
|---|
| 73 | pass
|
|---|
| 74 |
|
|---|
| 75 | def main():
|
|---|
| 76 | from flup.server.fcgi_fork import WSGIServer
|
|---|
| 77 | from django.core.handlers.wsgi import WSGIHandler
|
|---|
| 78 |
|
|---|
| 79 | import getopt
|
|---|
| 80 |
|
|---|
| 81 | (opts, args) = getopt.getopt(sys.argv[1:], 'f:s:h:p:',
|
|---|
| 82 | ['settings=','socket=','host=','port=',
|
|---|
| 83 | 'minspare=', 'maxspare=', 'maxchildren=',
|
|---|
| 84 | 'daemon', 'etclog=', 'errorlog=', 'workdir='])
|
|---|
| 85 |
|
|---|
| 86 | socket = None
|
|---|
| 87 | host = None
|
|---|
| 88 | port = None
|
|---|
| 89 |
|
|---|
| 90 | minspare = 1
|
|---|
| 91 | maxspare = 5
|
|---|
| 92 | maxchildren = 50
|
|---|
| 93 |
|
|---|
| 94 | daemon = None
|
|---|
| 95 | workdir = '.'
|
|---|
| 96 | etclog = '/dev/null'
|
|---|
| 97 | errorlog = '/dev/null'
|
|---|
| 98 |
|
|---|
| 99 | for (o, v) in opts:
|
|---|
| 100 | if o in ('-s', '--socket'):
|
|---|
| 101 | socket = v
|
|---|
| 102 | elif o in ('-h', '--host'):
|
|---|
| 103 | host = v
|
|---|
| 104 | elif o in ('-p', '--port'):
|
|---|
| 105 | port = int(v)
|
|---|
| 106 | elif o in ('-f', '--settings'):
|
|---|
| 107 | os.environ['DJANGO_SETTINGS_MODULE'] = v
|
|---|
| 108 | elif o in ('--minspare',):
|
|---|
| 109 | minspare = int(v)
|
|---|
| 110 | elif o in ('--maxspare',):
|
|---|
| 111 | maxspare = int(v)
|
|---|
| 112 | elif o in ('--maxchildren',):
|
|---|
| 113 | maxchildren = int(v)
|
|---|
| 114 | elif o in ('--daemon',):
|
|---|
| 115 | daemon = 1
|
|---|
| 116 | elif o in ('--errorlog',):
|
|---|
| 117 | errorlog = v
|
|---|
| 118 | elif o in ('--etclog',):
|
|---|
| 119 | etclog = v
|
|---|
| 120 | elif o in ('--workdir',):
|
|---|
| 121 | workdir = v
|
|---|
| 122 |
|
|---|
| 123 | # if we should run as a daemon, use the above function to turn us
|
|---|
| 124 | # into one reliably. This should correctly detach from the tty.
|
|---|
| 125 | if daemon:
|
|---|
| 126 | become_daemon(ourHomeDir=workdir,
|
|---|
| 127 | outLog=etclog, errLog=errorlog)
|
|---|
| 128 |
|
|---|
| 129 | if socket and not host and not port:
|
|---|
| 130 | WSGIServer(WSGIHandler(), minSpare=minspare, maxSpare=maxspare, maxChildren=maxchildren, bindAddress=socket).run()
|
|---|
| 131 | elif not socket and host and port:
|
|---|
| 132 | WSGIServer(WSGIHandler(), minSpare=minspare, maxSpare=maxspare, maxChildren=maxchildren, bindAddress=(host, port)).run()
|
|---|
| 133 | else:
|
|---|
| 134 | print "usage: django-fcgi.py [--settings=<settingsmodule>] --socket=<socketname>"
|
|---|
| 135 | print " or: django-fcgi.py [--settings=<settingsmodule>] --host==<hostname> --port=<portnumber>"
|
|---|
| 136 | print
|
|---|
| 137 | print " additional options are:"
|
|---|
| 138 | print " --minspare=<minimum number of spare processes, default 1>"
|
|---|
| 139 | print " --maxspare=<maximum number of spare processes, default 5>"
|
|---|
| 140 | print " --maxchildren=<maximum number of child processes, default 50>"
|
|---|
| 141 | print
|
|---|
| 142 | print " --daemon"
|
|---|
| 143 | print " --etclog=<path for stdout log, default /dev/null>"
|
|---|
| 144 | print " --errorlog=<path for stderr log, default /dev/null>"
|
|---|
| 145 | print " --workdir=<path for working directory, default .>"
|
|---|
| 146 |
|
|---|
| 147 | if __name__ == '__main__':
|
|---|
| 148 |
|
|---|
| 149 | # first patch our own version of socketpair into the sockets module
|
|---|
| 150 | # if we don't have it already (comes with Python 2.4)
|
|---|
| 151 |
|
|---|
| 152 | import socket
|
|---|
| 153 | if not hasattr(socket, 'socketpair'):
|
|---|
| 154 | import eunuchs.socketpair
|
|---|
| 155 |
|
|---|
| 156 | def socketpair():
|
|---|
| 157 | (p,c) = eunuchs.socketpair.socketpair()
|
|---|
| 158 | return (socket.fromfd(p,1,1), socket.fromfd(c,1,1))
|
|---|
| 159 |
|
|---|
| 160 | socket.socketpair = socketpair
|
|---|
| 161 |
|
|---|
| 162 | main()
|
|---|
| 163 |
|
|---|