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