]>
Commit | Line | Data |
---|---|---|
c6a6bfc9 | 1 | diff -Nru php-5.2.6.vanilla/configure php-5.2.6.fpm/configure |
e327cc0e ER |
2 | diff -Nru php-5.2.6.vanilla/configure.in php-5.2.6.fpm/configure.in |
3 | --- php-5.2.6.vanilla/configure.in 2008-04-30 22:27:55.000000000 +0400 | |
4 | +++ php-5.2.6.fpm/configure.in 2008-05-01 20:42:05.000000000 +0400 | |
5 | @@ -267,6 +267,12 @@ | |
6 | PTHREADS_FLAGS | |
fd1be940 ER |
7 | fi |
8 | ||
e327cc0e ER |
9 | +if test "$PHP_FASTCGI" = "yes" -a "$PHP_FPM" = "yes"; then |
10 | + PHP_CONFIGURE_PART(Running FastCGI Process Manager checks) | |
8c0dac15 ER |
11 | + sinclude(sapi/cgi/fpm/acinclude.m4) |
12 | + sinclude(sapi/cgi/fpm/config.m4) | |
fd1be940 ER |
13 | +fi |
14 | + | |
e327cc0e | 15 | divert(3) |
fd1be940 | 16 | |
e327cc0e ER |
17 | dnl ## In diversion 3 we check for compile-time options to the PHP |
18 | @@ -476,6 +482,7 @@ | |
19 | alphasort \ | |
20 | asctime_r \ | |
21 | chroot \ | |
22 | +clearenv \ | |
23 | ctime_r \ | |
24 | cuserid \ | |
25 | crypt \ | |
26 | @@ -1197,6 +1204,8 @@ | |
27 | PHP_SUBST_OLD(EXTRA_LDFLAGS) | |
28 | PHP_SUBST_OLD(EXTRA_LDFLAGS_PROGRAM) | |
29 | PHP_SUBST_OLD(EXTRA_LIBS) | |
30 | +PHP_SUBST_OLD(SAPI_EXTRA_LIBS) | |
31 | +PHP_SUBST_OLD(SAPI_EXTRA_DEPS) | |
32 | PHP_SUBST_OLD(ZEND_EXTRA_LIBS) | |
33 | PHP_SUBST_OLD(INCLUDES) | |
34 | PHP_SUBST_OLD(EXTRA_INCLUDES) | |
35 | @@ -1285,7 +1294,7 @@ | |
36 | install_targets="$PHP_INSTALL_CLI_TARGET $install_targets" | |
37 | ;; | |
38 | *) | |
39 | - install_targets="install-sapi $PHP_INSTALL_CLI_TARGET $install_targets" | |
40 | + install_targets="install-sapi $install_fpm $PHP_INSTALL_CLI_TARGET $install_targets" | |
41 | ;; | |
42 | esac | |
fd1be940 | 43 | |
e327cc0e ER |
44 | diff -Nru php-5.2.6.vanilla/libevent/aclocal.m4 php-5.2.6.fpm/libevent/aclocal.m4 |
45 | diff -Nru php-5.2.6.vanilla/libevent/autogen.sh php-5.2.6.fpm/libevent/autogen.sh | |
46 | diff -Nru php-5.2.6.vanilla/libevent/ChangeLog php-5.2.6.fpm/libevent/ChangeLog | |
47 | diff -Nru php-5.2.6.vanilla/libevent/compat/sys/queue.h php-5.2.6.fpm/libevent/compat/sys/queue.h | |
48 | diff -Nru php-5.2.6.vanilla/libevent/compat/sys/_time.h php-5.2.6.fpm/libevent/compat/sys/_time.h | |
49 | diff -Nru php-5.2.6.vanilla/libevent/config.guess php-5.2.6.fpm/libevent/config.guess | |
50 | diff -Nru php-5.2.6.vanilla/libevent/config.h.in php-5.2.6.fpm/libevent/config.h.in | |
51 | diff -Nru php-5.2.6.vanilla/libevent/config.sub php-5.2.6.fpm/libevent/config.sub | |
52 | diff -Nru php-5.2.6.vanilla/libevent/configure php-5.2.6.fpm/libevent/configure | |
53 | diff -Nru php-5.2.6.vanilla/libevent/configure.in php-5.2.6.fpm/libevent/configure.in | |
54 | diff -Nru php-5.2.6.vanilla/libevent/depcomp php-5.2.6.fpm/libevent/depcomp | |
55 | diff -Nru php-5.2.6.vanilla/libevent/devpoll.c php-5.2.6.fpm/libevent/devpoll.c | |
56 | diff -Nru php-5.2.6.vanilla/libevent/epoll.c php-5.2.6.fpm/libevent/epoll.c | |
57 | diff -Nru php-5.2.6.vanilla/libevent/epoll_sub.c php-5.2.6.fpm/libevent/epoll_sub.c | |
58 | diff -Nru php-5.2.6.vanilla/libevent/event.3 php-5.2.6.fpm/libevent/event.3 | |
59 | diff -Nru php-5.2.6.vanilla/libevent/event.c php-5.2.6.fpm/libevent/event.c | |
60 | diff -Nru php-5.2.6.vanilla/libevent/event-config.h php-5.2.6.fpm/libevent/event-config.h | |
61 | diff -Nru php-5.2.6.vanilla/libevent/event-fpm.h php-5.2.6.fpm/libevent/event-fpm.h | |
62 | diff -Nru php-5.2.6.vanilla/libevent/event.h php-5.2.6.fpm/libevent/event.h | |
63 | diff -Nru php-5.2.6.vanilla/libevent/event-internal.h php-5.2.6.fpm/libevent/event-internal.h | |
64 | diff -Nru php-5.2.6.vanilla/libevent/evport.c php-5.2.6.fpm/libevent/evport.c | |
65 | diff -Nru php-5.2.6.vanilla/libevent/evsignal.h php-5.2.6.fpm/libevent/evsignal.h | |
66 | diff -Nru php-5.2.6.vanilla/libevent/evutil.c php-5.2.6.fpm/libevent/evutil.c | |
67 | diff -Nru php-5.2.6.vanilla/libevent/evutil.h php-5.2.6.fpm/libevent/evutil.h | |
68 | diff -Nru php-5.2.6.vanilla/libevent/install-sh php-5.2.6.fpm/libevent/install-sh | |
69 | diff -Nru php-5.2.6.vanilla/libevent/kqueue.c php-5.2.6.fpm/libevent/kqueue.c | |
70 | diff -Nru php-5.2.6.vanilla/libevent/log.c php-5.2.6.fpm/libevent/log.c | |
71 | diff -Nru php-5.2.6.vanilla/libevent/log.h php-5.2.6.fpm/libevent/log.h | |
72 | diff -Nru php-5.2.6.vanilla/libevent/Makefile.am php-5.2.6.fpm/libevent/Makefile.am | |
73 | diff -Nru php-5.2.6.vanilla/libevent/Makefile.in php-5.2.6.fpm/libevent/Makefile.in | |
c6a6bfc9 | 74 | diff -Nru php-5.2.6.vanilla/libevent/min_heap.h php-5.2.6.fpm/libevent/min_heap.h |
c6a6bfc9 | 75 | diff -Nru php-5.2.6.vanilla/libevent/missing php-5.2.6.fpm/libevent/missing |
c6a6bfc9 | 76 | diff -Nru php-5.2.6.vanilla/libevent/mkinstalldirs php-5.2.6.fpm/libevent/mkinstalldirs |
c6a6bfc9 | 77 | diff -Nru php-5.2.6.vanilla/libevent/poll.c php-5.2.6.fpm/libevent/poll.c |
c6a6bfc9 | 78 | diff -Nru php-5.2.6.vanilla/libevent/README php-5.2.6.fpm/libevent/README |
c6a6bfc9 | 79 | diff -Nru php-5.2.6.vanilla/libevent/select.c php-5.2.6.fpm/libevent/select.c |
c6a6bfc9 | 80 | diff -Nru php-5.2.6.vanilla/libevent/signal.c php-5.2.6.fpm/libevent/signal.c |
c6a6bfc9 ER |
81 | diff -Nru php-5.2.6.vanilla/main/php_config.h.in php-5.2.6.fpm/main/php_config.h.in |
82 | --- php-5.2.6.vanilla/main/php_config.h.in 2008-04-30 22:37:39.000000000 +0400 | |
83 | +++ php-5.2.6.fpm/main/php_config.h.in 2008-09-21 17:37:45.000000000 +0400 | |
fd1be940 ER |
84 | @@ -170,6 +170,9 @@ |
85 | /* Define if you have the chroot function. */ | |
86 | #undef HAVE_CHROOT | |
87 | ||
88 | +/* Define if you have the clearenv function. */ | |
89 | +#undef HAVE_CLEARENV | |
90 | + | |
91 | /* Define if you have the crypt function. */ | |
92 | #undef HAVE_CRYPT | |
93 | ||
94 | @@ -929,6 +932,9 @@ | |
95 | /* */ | |
96 | #undef PHP_FASTCGI | |
97 | ||
98 | +/* Is experimental fastcgi process manager code activated */ | |
99 | +#undef PHP_FASTCGI_PM | |
100 | + | |
101 | /* */ | |
102 | #undef FORCE_CGI_REDIRECT | |
103 | ||
c6a6bfc9 | 104 | @@ -938,6 +944,27 @@ |
fd1be940 ER |
105 | /* */ |
106 | #undef ENABLE_PATHINFO_CHECK | |
107 | ||
108 | +/* do we have libxml? */ | |
109 | +#undef HAVE_LIBXML | |
c6a6bfc9 ER |
110 | + |
111 | +/* do we have prctl? */ | |
112 | +#undef HAVE_PRCTL | |
113 | + | |
114 | +/* do we have clock_gettime? */ | |
115 | +#undef HAVE_CLOCK_GETTIME | |
116 | + | |
117 | +/* do we have clock_get_time? */ | |
118 | +#undef HAVE_CLOCK_GET_TIME | |
119 | + | |
120 | +/* do we have ptrace? */ | |
121 | +#undef HAVE_PTRACE | |
122 | + | |
123 | +/* do we have mach_vm_read? */ | |
124 | +#undef HAVE_MACH_VM_READ | |
125 | + | |
126 | +/* /proc/pid/mem interface */ | |
127 | +#undef PROC_MEM_FILE | |
fd1be940 ER |
128 | + |
129 | /* Define if system uses EBCDIC */ | |
130 | #undef CHARSET_EBCDIC | |
131 | ||
5659f47e ER |
132 | --- php-5.2.6.fpm/sapi/cgi/cgi_main.c 2008-07-22 01:50:58.000000000 +0400 |
133 | +++ php-5.2.6/sapi/cgi/cgi_main.c 2008-11-03 20:21:40.431760373 +0200 | |
fd1be940 ER |
134 | @@ -55,6 +55,9 @@ |
135 | #if HAVE_SYS_WAIT_H | |
136 | #include <sys/wait.h> | |
137 | #endif | |
138 | +#if HAVE_FCNTL_H | |
139 | +#include <fcntl.h> | |
140 | +#endif | |
141 | #include "zend.h" | |
142 | #include "zend_extensions.h" | |
143 | #include "php_ini.h" | |
c6a6bfc9 | 144 | @@ -83,6 +86,11 @@ |
fd1be940 ER |
145 | #if PHP_FASTCGI |
146 | #include "fastcgi.h" | |
147 | ||
148 | +#if PHP_FASTCGI_PM | |
149 | +#include "fpm/fpm.h" | |
c6a6bfc9 | 150 | +#include "fpm/fpm_request.h" |
fd1be940 ER |
151 | +#endif |
152 | + | |
153 | #ifndef PHP_WIN32 | |
154 | /* XXX this will need to change later when threaded fastcgi is | |
155 | implemented. shane */ | |
c6a6bfc9 | 156 | @@ -109,8 +117,12 @@ |
fd1be940 ER |
157 | static pid_t pgroup; |
158 | #endif | |
159 | ||
160 | +static int request_body_fd; | |
161 | + | |
162 | #endif | |
163 | ||
164 | +static char *sapi_cgibin_getenv(char *name, size_t name_len TSRMLS_DC); | |
165 | + | |
166 | #define PHP_MODE_STANDARD 1 | |
167 | #define PHP_MODE_HIGHLIGHT 2 | |
168 | #define PHP_MODE_INDENT 3 | |
c6a6bfc9 | 169 | @@ -140,6 +152,10 @@ |
fd1be940 ER |
170 | {'w', 0, "strip"}, |
171 | {'?', 0, "usage"},/* help alias (both '?' and 'usage') */ | |
172 | {'v', 0, "version"}, | |
173 | +#if PHP_FASTCGI_PM | |
174 | + {'x', 0, "fpm"}, | |
175 | + {'y', 1, "fpm-config"}, | |
176 | +#endif | |
177 | {'z', 1, "zend-extension"}, | |
c6a6bfc9 ER |
178 | #if PHP_FASTCGI |
179 | {'T', 1, "timing"}, | |
180 | @@ -164,6 +180,7 @@ | |
fd1be940 ER |
181 | zend_bool impersonate; |
182 | # endif | |
fd1be940 | 183 | #endif |
c6a6bfc9 | 184 | + char *error_header; |
fd1be940 ER |
185 | } php_cgi_globals_struct; |
186 | ||
c6a6bfc9 ER |
187 | #ifdef ZTS |
188 | @@ -444,7 +461,28 @@ | |
fd1be940 ER |
189 | #if PHP_FASTCGI |
190 | if (fcgi_is_fastcgi()) { | |
191 | fcgi_request *request = (fcgi_request*) SG(server_context); | |
192 | - tmp_read_bytes = fcgi_read(request, buffer + read_bytes, count_bytes - read_bytes); | |
193 | + | |
194 | + if (request_body_fd == -1) { | |
c6a6bfc9 ER |
195 | + char *request_body_filename = sapi_cgibin_getenv((char *) "REQUEST_BODY_FILE", |
196 | + sizeof("REQUEST_BODY_FILE")-1 TSRMLS_CC); | |
197 | + | |
fd1be940 ER |
198 | + if (request_body_filename && *request_body_filename) { |
199 | + request_body_fd = open(request_body_filename, O_RDONLY); | |
c6a6bfc9 ER |
200 | + |
201 | + if (0 > request_body_fd) { | |
202 | + php_error(E_WARNING, "REQUEST_BODY_FILE: open('%s') failed: %s (%d)", | |
203 | + request_body_filename, strerror(errno), errno); | |
204 | + return 0; | |
205 | + } | |
fd1be940 ER |
206 | + } |
207 | + } | |
208 | + | |
209 | + /* If REQUEST_BODY_FILE variable not available - read post body from fastcgi stream */ | |
fd1be940 ER |
210 | + if (request_body_fd < 0) { |
211 | + tmp_read_bytes = fcgi_read(request, buffer + read_bytes, count_bytes - read_bytes); | |
212 | + } else { | |
213 | + tmp_read_bytes = read(request_body_fd, buffer + read_bytes, count_bytes - read_bytes); | |
214 | + } | |
215 | } else { | |
216 | tmp_read_bytes = read(0, buffer + read_bytes, count_bytes - read_bytes); | |
217 | } | |
c6a6bfc9 | 218 | @@ -756,7 +794,12 @@ |
fd1be940 ER |
219 | " -s Display colour syntax highlighted source.\n" |
220 | " -v Version number\n" | |
221 | " -w Display source with stripped comments and whitespace.\n" | |
c6a6bfc9 | 222 | - " -z <file> Load Zend extension <file>.\n" |
fd1be940 ER |
223 | +#if PHP_FASTCGI_PM |
224 | + " -x, --fpm Run in FastCGI process manager mode.\n" | |
225 | + " -y, --fpm-config <file>\n" | |
226 | + " Specify alternative path to FastCGI process manager config file.\n" | |
227 | +#endif | |
c6a6bfc9 ER |
228 | + " -z <file> Load Zend extension <file>.\n" |
229 | #if PHP_FASTCGI | |
230 | " -T <count> Measure execution time of script repeated <count> times.\n" | |
231 | #endif | |
232 | @@ -1173,6 +1216,7 @@ | |
fd1be940 ER |
233 | # ifdef PHP_WIN32 |
234 | STD_PHP_INI_ENTRY("fastcgi.impersonate", "0", PHP_INI_SYSTEM, OnUpdateBool, impersonate, php_cgi_globals_struct, php_cgi_globals) | |
235 | # endif | |
236 | + STD_PHP_INI_ENTRY("fastcgi.error_header", NULL, PHP_INI_SYSTEM, OnUpdateString, error_header, php_cgi_globals_struct, php_cgi_globals) | |
237 | #endif | |
238 | PHP_INI_END() | |
239 | ||
c6a6bfc9 | 240 | @@ -1195,6 +1239,7 @@ |
fd1be940 ER |
241 | # ifdef PHP_WIN32 |
242 | php_cgi_globals->impersonate = 0; | |
243 | # endif | |
244 | + php_cgi_globals->error_header = NULL; | |
245 | #endif | |
246 | } | |
247 | /* }}} */ | |
c6a6bfc9 ER |
248 | @@ -1227,9 +1272,47 @@ |
249 | static PHP_MINFO_FUNCTION(cgi) | |
250 | { | |
251 | DISPLAY_INI_ENTRIES(); | |
252 | + | |
253 | +#if PHP_FASTCGI_PM | |
254 | + | |
255 | +#include "fpm/fpm_autoconf.h" | |
256 | + | |
257 | + php_info_print_table_start(); | |
258 | + php_info_print_table_row(2, "php-fpm", fpm ? "active" : "inactive"); | |
259 | + php_info_print_table_row(2, "php-fpm version", PHP_FPM_VERSION); | |
260 | + php_info_print_table_end(); | |
261 | +#endif | |
262 | + | |
fd1be940 ER |
263 | } |
264 | /* }}} */ | |
265 | ||
266 | +#if PHP_FASTCGI | |
267 | +PHP_FUNCTION(fastcgi_finish_request) | |
268 | +{ | |
269 | + fcgi_request *request = (fcgi_request*) SG(server_context); | |
270 | + | |
271 | + if (fcgi_is_fastcgi() && request->fd >= 0) { | |
272 | + | |
273 | + php_end_ob_buffers(1 TSRMLS_CC); | |
274 | + php_header(TSRMLS_C); | |
275 | + | |
276 | + fcgi_flush(request, 1); | |
277 | + fcgi_close(request, 0, 0); | |
278 | + RETURN_TRUE; | |
279 | + } | |
280 | + | |
281 | + RETURN_FALSE; | |
282 | + | |
283 | +} | |
284 | +#endif | |
285 | + | |
286 | +function_entry cgi_fcgi_sapi_functions[] = { | |
287 | +#if PHP_FASTCGI | |
288 | + PHP_FE(fastcgi_finish_request, NULL) | |
289 | +#endif | |
290 | + {NULL, NULL, NULL} | |
291 | +}; | |
292 | + | |
293 | static zend_module_entry cgi_module_entry = { | |
294 | STANDARD_MODULE_HEADER, | |
295 | #if PHP_FASTCGI | |
c6a6bfc9 | 296 | @@ -1237,7 +1320,7 @@ |
fd1be940 ER |
297 | #else |
298 | "cgi", | |
299 | #endif | |
300 | - NULL, | |
301 | + cgi_fcgi_sapi_functions, | |
302 | PHP_MINIT(cgi), | |
303 | PHP_MSHUTDOWN(cgi), | |
304 | NULL, | |
c6a6bfc9 | 305 | @@ -1277,6 +1360,7 @@ |
fd1be940 ER |
306 | char *bindpath = NULL; |
307 | int fcgi_fd = 0; | |
308 | fcgi_request request; | |
fd1be940 | 309 | + char *fpm_config = NULL; |
c6a6bfc9 ER |
310 | int repeats = 1; |
311 | int benchmark = 0; | |
312 | #if HAVE_GETTIMEOFDAY | |
313 | @@ -1397,6 +1481,14 @@ | |
fd1be940 ER |
314 | case 's': /* generate highlighted HTML from source */ |
315 | behavior = PHP_MODE_HIGHLIGHT; | |
316 | break; | |
317 | +#if PHP_FASTCGI_PM | |
318 | + case 'y': | |
319 | + fpm_config = php_optarg; | |
320 | + break; | |
321 | + case 'x': | |
322 | + fpm = 1; | |
323 | + break; | |
324 | +#endif | |
325 | ||
326 | } | |
327 | ||
c6a6bfc9 | 328 | @@ -1459,6 +1551,19 @@ |
fd1be940 ER |
329 | #endif /* FORCE_CGI_REDIRECT */ |
330 | ||
331 | #if PHP_FASTCGI | |
332 | +#if PHP_FASTCGI_PM | |
333 | + if (fpm) { | |
334 | + if (0 > fpm_init(argc, argv, fpm_config)) { | |
335 | + return FAILURE; | |
336 | + } | |
337 | + | |
338 | + fcgi_fd = fpm_run(&max_requests); | |
339 | + | |
340 | + fcgi_set_is_fastcgi(fastcgi = 1); | |
341 | + } | |
342 | + else | |
343 | +#endif | |
344 | + | |
345 | if (bindpath) { | |
346 | fcgi_fd = fcgi_listen(bindpath, 128); | |
347 | if (fcgi_fd < 0) { | |
48f6ef1f | 348 | @@ -1625,7 +1625,11 @@ |
fd1be940 ER |
349 | |
350 | if (fastcgi) { | |
351 | /* How many times to run PHP scripts before dying */ | |
352 | - if (getenv("PHP_FCGI_MAX_REQUESTS")) { | |
5659f47e ER |
353 | + if ( |
354 | +#if PHP_FASTCGI_PM | |
355 | + !fpm && | |
356 | +#endif | |
357 | + getenv("PHP_FCGI_MAX_REQUESTS")) { | |
358 | max_requests = atoi(getenv("PHP_FCGI_MAX_REQUESTS")); | |
359 | if (max_requests < 0) { | |
360 | fprintf(stderr, "PHP_FCGI_MAX_REQUESTS is not valid\n"); | |
48f6ef1f | 361 | @@ -1642,7 +1646,11 @@ |
5659f47e ER |
362 | |
363 | #ifndef PHP_WIN32 | |
364 | /* Pre-fork, if required */ | |
48f6ef1f | 365 | - if (getenv("PHP_FCGI_CHILDREN")) { |
5659f47e ER |
366 | + if ( |
367 | +#if PHP_FASTCGI_PM | |
368 | + !fpm && | |
369 | +#endif | |
370 | + getenv("PHP_FCGI_CHILDREN")) { | |
371 | children = atoi(getenv("PHP_FCGI_CHILDREN")); | |
372 | if (children < 0) { | |
373 | fprintf(stderr, "PHP_FCGI_CHILDREN is not valid\n"); | |
374 | @@ -1616,6 +1729,8 @@ | |
fd1be940 ER |
375 | #endif |
376 | ||
377 | #if PHP_FASTCGI | |
378 | + request_body_fd = -1; | |
379 | + | |
380 | SG(server_context) = (void *) &request; | |
381 | #else | |
382 | SG(server_context) = (void *) 1; /* avoid server_context==NULL checks */ | |
c6a6bfc9 ER |
383 | @@ -1623,6 +1730,10 @@ |
384 | init_request_info(TSRMLS_C); | |
385 | CG(interactive) = 0; | |
386 | ||
387 | +#if PHP_FASTCGI_PM | |
388 | + if (fpm) fpm_request_info(); | |
389 | +#endif | |
390 | + | |
391 | if (!cgi | |
392 | #if PHP_FASTCGI | |
393 | && !fastcgi | |
394 | @@ -1914,6 +2025,10 @@ | |
395 | } | |
396 | } | |
397 | ||
398 | +#if PHP_FASTCGI_PM | |
399 | + if (fpm) fpm_request_executing(); | |
400 | +#endif | |
401 | + | |
402 | switch (behavior) { | |
403 | case PHP_MODE_STANDARD: | |
404 | php_execute_script(&file_handle TSRMLS_CC); | |
405 | @@ -1966,6 +2081,10 @@ | |
fd1be940 ER |
406 | |
407 | #if PHP_FASTCGI | |
408 | fastcgi_request_done: | |
409 | + | |
410 | + if (request_body_fd != -1) close(request_body_fd); | |
411 | + | |
412 | + request_body_fd = -2; | |
413 | #endif | |
414 | { | |
415 | char *path_translated; | |
c6a6bfc9 | 416 | @@ -1979,6 +2098,16 @@ |
fd1be940 ER |
417 | SG(request_info).path_translated = path_translated; |
418 | } | |
419 | ||
420 | + if (EG(exit_status) == 255) { | |
421 | + if (CGIG(error_header) && *CGIG(error_header)) { | |
422 | + sapi_header_line ctr = {0}; | |
423 | + | |
424 | + ctr.line = CGIG(error_header); | |
425 | + ctr.line_len = strlen(CGIG(error_header)); | |
426 | + sapi_header_op(SAPI_HEADER_REPLACE, &ctr TSRMLS_CC); | |
427 | + } | |
428 | + } | |
429 | + | |
430 | php_request_shutdown((void *) 0); | |
431 | if (exit_status == 0) { | |
432 | exit_status = EG(exit_status); | |
c6a6bfc9 ER |
433 | @@ -2016,15 +2145,20 @@ |
434 | if (bindpath) { | |
435 | free(bindpath); | |
436 | } | |
437 | - if (max_requests != 1) { | |
438 | - /* no need to return exit_status of the last request */ | |
439 | - exit_status = 0; | |
440 | - } | |
441 | break; | |
fd1be940 | 442 | } |
c6a6bfc9 ER |
443 | /* end of fastcgi loop */ |
444 | } | |
445 | fcgi_shutdown(); | |
fd1be940 | 446 | + |
c6a6bfc9 ER |
447 | + if (fcgi_in_shutdown() || /* graceful shutdown by a signal */ |
448 | + (max_requests && (requests == max_requests)) /* we were told to process max_requests and we are done */ | |
449 | + ) { | |
450 | + exit_status = 0; | |
451 | + } | |
452 | + else { | |
453 | + exit_status = 255; | |
454 | + } | |
455 | #endif | |
456 | ||
457 | if (cgi_sapi_module.php_ini_path_override) { | |
8c0dac15 ER |
458 | diff -Nru php-5.2.6.vanilla/sapi/cgi/config9.m4 php-5.2.6.fpm/sapi/cgi/config9.m4 |
459 | --- php-5.2.6.vanilla/sapi/cgi/config9.m4 2007-07-12 03:20:36.000000000 +0400 | |
460 | +++ php-5.2.6.fpm/sapi/cgi/config9.m4 2008-07-20 20:46:41.000000000 +0400 | |
fd1be940 ER |
461 | @@ -22,6 +22,10 @@ |
462 | [ --disable-path-info-check CGI: If this is disabled, paths such as | |
463 | /info.php/test?a=b will fail to work], yes, no) | |
464 | ||
465 | +PHP_ARG_ENABLE(fpm,, | |
466 | +[ --enable-fpm FastCGI: If this is enabled, the fastcgi support | |
467 | + will include experimental process manager code], no, no) | |
468 | + | |
469 | dnl | |
470 | dnl CGI setup | |
471 | dnl | |
472 | @@ -54,6 +58,20 @@ | |
473 | AC_DEFINE_UNQUOTED(PHP_FASTCGI, $PHP_ENABLE_FASTCGI, [ ]) | |
474 | AC_MSG_RESULT($PHP_FASTCGI) | |
475 | ||
476 | + dnl --enable-fpm | |
477 | + if test "$PHP_FASTCGI" = "yes"; then | |
c6a6bfc9 | 478 | + AC_MSG_CHECKING(whether to enable FastCGI Process Manager) |
fd1be940 ER |
479 | + if test "$PHP_FPM" = "yes"; then |
480 | + PHP_FASTCGI_PM=1 | |
481 | + else | |
482 | + PHP_FASTCGI_PM=0 | |
483 | + fi | |
484 | + AC_MSG_RESULT($PHP_FPM) | |
485 | + else | |
486 | + PHP_FASTCGI_PM=0 | |
487 | + fi | |
488 | + AC_DEFINE_UNQUOTED(PHP_FASTCGI_PM, $PHP_FASTCGI_PM, [Is experimental fastcgi process manager code activated]) | |
489 | + | |
490 | dnl --enable-force-cgi-redirect | |
491 | AC_MSG_CHECKING(whether to force Apache CGI redirect) | |
492 | if test "$PHP_FORCE_CGI_REDIRECT" = "yes"; then | |
75ddaf45 ER |
493 | @@ -108,13 +108,13 @@ |
494 | ||
495 | case $host_alias in | |
496 | *aix*) | |
497 | - BUILD_CGI="echo '\#! .' > php.sym && echo >>php.sym && nm -BCpg \`echo \$(PHP_GLOBAL_OBJS) \$(PHP_SAPI_OBJS) | sed 's/\([A-Za-z0-9_]*\)\.lo/\1.o/g'\` | \$(AWK) '{ if (((\$\$2 == \"T\") || (\$\$2 == \"D\") || (\$\$2 == \"B\")) && (substr(\$\$3,1,1) != \".\")) { print \$\$3 } }' | sort -u >> php.sym && \$(LIBTOOL) --mode=link \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) -Wl,-brtl -Wl,-bE:php.sym \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS) \$(PHP_SAPI_OBJS) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_CGI_PATH)" | |
498 | + BUILD_CGI="echo '\#! .' > php.sym && echo >>php.sym && nm -BCpg \`echo \$(PHP_GLOBAL_OBJS) \$(PHP_SAPI_OBJS) | sed 's/\([A-Za-z0-9_]*\)\.lo/\1.o/g'\` | \$(AWK) '{ if (((\$\$2 == \"T\") || (\$\$2 == \"D\") || (\$\$2 == \"B\")) && (substr(\$\$3,1,1) != \".\")) { print \$\$3 } }' | sort -u >> php.sym && \$(LIBTOOL) --mode=link \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) -Wl,-brtl -Wl,-bE:php.sym \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS) \$(PHP_SAPI_OBJS) \$(EXTRA_LIBS) \$(SAPI_EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_CGI_PATH)" | |
fd1be940 ER |
499 | ;; |
500 | *darwin*) | |
75ddaf45 ER |
501 | - BUILD_CGI="\$(CC) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(NATIVE_RPATHS) \$(PHP_GLOBAL_OBJS:.lo=.o) \$(PHP_SAPI_OBJS:.lo=.o) \$(PHP_FRAMEWORKS) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_CGI_PATH)" |
502 | + BUILD_CGI="\$(CC) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(NATIVE_RPATHS) \$(PHP_GLOBAL_OBJS:.lo=.o) \$(PHP_SAPI_OBJS:.lo=.o) \$(PHP_FRAMEWORKS) \$(EXTRA_LIBS) \$(SAPI_EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_CGI_PATH)" | |
fd1be940 ER |
503 | ;; |
504 | *) | |
75ddaf45 ER |
505 | - BUILD_CGI="\$(LIBTOOL) --mode=link \$(CC) -export-dynamic \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(PHP_RPATHS) libphp_common.la \$(PHP_SAPI_OBJS) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_CGI_PATH)" |
506 | + BUILD_CGI="\$(LIBTOOL) --mode=link \$(CC) -export-dynamic \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(PHP_RPATHS) libphp_common.la \$(PHP_SAPI_OBJS) \$(EXTRA_LIBS) \$(SAPI_EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_CGI_PATH)" | |
fd1be940 ER |
507 | ;; |
508 | esac | |
509 | ||
8c0dac15 ER |
510 | diff -Nru php-5.2.6.vanilla/sapi/cgi/fastcgi.c php-5.2.6.fpm/sapi/cgi/fastcgi.c |
511 | --- php-5.2.6.vanilla/sapi/cgi/fastcgi.c 2008-04-03 14:24:44.000000000 +0400 | |
512 | +++ php-5.2.6.fpm/sapi/cgi/fastcgi.c 2008-05-15 23:37:01.000000000 +0400 | |
c6a6bfc9 ER |
513 | @@ -27,6 +27,11 @@ |
514 | #include <stdarg.h> | |
515 | #include <errno.h> | |
516 | ||
517 | +#if PHP_FASTCGI_PM | |
518 | +#include "fpm/fpm.h" | |
519 | +#include "fpm/fpm_request.h" | |
520 | +#endif | |
521 | + | |
522 | #ifdef _WIN32 | |
523 | ||
524 | #include <windows.h> | |
525 | @@ -240,6 +245,8 @@ | |
fd1be940 ER |
526 | } else { |
527 | return is_fastcgi = 0; | |
528 | } | |
529 | + | |
530 | + fcgi_set_allowed_clients(getenv("FCGI_WEB_SERVER_ADDRS")); | |
531 | #endif | |
532 | } | |
533 | return is_fastcgi; | |
c6a6bfc9 | 534 | @@ -255,9 +262,24 @@ |
fd1be940 ER |
535 | } |
536 | } | |
537 | ||
538 | +void fcgi_set_is_fastcgi(int new_value) | |
539 | +{ | |
540 | + is_fastcgi = new_value; | |
541 | +} | |
c6a6bfc9 ER |
542 | + |
543 | +void fcgi_set_in_shutdown(int new_value) | |
544 | +{ | |
545 | + in_shutdown = new_value; | |
546 | +} | |
fd1be940 ER |
547 | + |
548 | void fcgi_shutdown(void) | |
549 | { | |
550 | is_fastcgi = 0; | |
551 | + | |
552 | + if (allowed_clients) { | |
553 | + free(allowed_clients); | |
554 | + allowed_clients = 0; | |
555 | + } | |
556 | } | |
557 | ||
558 | #ifdef _WIN32 | |
c6a6bfc9 | 559 | @@ -330,6 +352,41 @@ |
fd1be940 ER |
560 | } |
561 | #endif | |
562 | ||
563 | +void fcgi_set_allowed_clients(char *ip) | |
564 | +{ | |
565 | + char *cur, *end; | |
566 | + int n; | |
567 | + | |
568 | + if (ip) { | |
569 | + ip = strdup(ip); | |
570 | + cur = ip; | |
571 | + n = 0; | |
572 | + while (*cur) { | |
573 | + if (*cur == ',') n++; | |
574 | + cur++; | |
575 | + } | |
576 | + if (allowed_clients) free(allowed_clients); | |
577 | + allowed_clients = malloc(sizeof(in_addr_t) * (n+2)); | |
578 | + n = 0; | |
579 | + cur = ip; | |
580 | + while (cur) { | |
581 | + end = strchr(cur, ','); | |
582 | + if (end) { | |
583 | + *end = 0; | |
584 | + end++; | |
585 | + } | |
586 | + allowed_clients[n] = inet_addr(cur); | |
587 | + if (allowed_clients[n] == INADDR_NONE) { | |
588 | + fprintf(stderr, "Wrong IP address '%s' in FCGI_WEB_SERVER_ADDRS\n", cur); | |
589 | + } | |
590 | + n++; | |
591 | + cur = end; | |
592 | + } | |
593 | + allowed_clients[n] = INADDR_NONE; | |
594 | + free(ip); | |
595 | + } | |
596 | +} | |
597 | + | |
598 | static int is_port_number(const char *bindpath) | |
599 | { | |
600 | while (*bindpath) { | |
c6a6bfc9 | 601 | @@ -458,38 +515,6 @@ |
fd1be940 ER |
602 | |
603 | if (!tcp) { | |
604 | chmod(path, 0777); | |
605 | - } else { | |
606 | - char *ip = getenv("FCGI_WEB_SERVER_ADDRS"); | |
607 | - char *cur, *end; | |
608 | - int n; | |
609 | - | |
610 | - if (ip) { | |
611 | - ip = strdup(ip); | |
612 | - cur = ip; | |
613 | - n = 0; | |
614 | - while (*cur) { | |
615 | - if (*cur == ',') n++; | |
616 | - cur++; | |
617 | - } | |
618 | - allowed_clients = malloc(sizeof(in_addr_t) * (n+2)); | |
619 | - n = 0; | |
620 | - cur = ip; | |
621 | - while (cur) { | |
622 | - end = strchr(cur, ','); | |
623 | - if (end) { | |
624 | - *end = 0; | |
625 | - end++; | |
626 | - } | |
627 | - allowed_clients[n] = inet_addr(cur); | |
628 | - if (allowed_clients[n] == INADDR_NONE) { | |
629 | - fprintf(stderr, "Wrong IP address '%s' in FCGI_WEB_SERVER_ADDRS\n", cur); | |
630 | - } | |
631 | - n++; | |
632 | - cur = end; | |
633 | - } | |
634 | - allowed_clients[n] = INADDR_NONE; | |
635 | - free(ip); | |
636 | - } | |
637 | } | |
638 | ||
639 | if (!is_initialized) { | |
c6a6bfc9 | 640 | @@ -829,7 +854,7 @@ |
fd1be940 ER |
641 | return n; |
642 | } | |
643 | ||
644 | -static inline void fcgi_close(fcgi_request *req, int force, int destroy) | |
645 | +void fcgi_close(fcgi_request *req, int force, int destroy) | |
646 | { | |
647 | if (destroy) { | |
648 | zend_hash_destroy(&req->env); | |
c6a6bfc9 ER |
649 | @@ -869,6 +894,10 @@ |
650 | close(req->fd); | |
651 | #endif | |
652 | req->fd = -1; | |
653 | + | |
654 | +#if PHP_FASTCGI_PM | |
655 | + if (fpm) fpm_request_finished(); | |
656 | +#endif | |
657 | } | |
658 | } | |
659 | ||
660 | @@ -916,6 +945,10 @@ | |
661 | sa_t sa; | |
662 | socklen_t len = sizeof(sa); | |
663 | ||
664 | +#if PHP_FASTCGI_PM | |
665 | + if (fpm) fpm_request_accepting(); | |
666 | +#endif | |
667 | + | |
668 | FCGI_LOCK(req->listen_socket); | |
669 | req->fd = accept(listen_socket, (struct sockaddr *)&sa, &len); | |
670 | FCGI_UNLOCK(req->listen_socket); | |
671 | @@ -951,6 +984,11 @@ | |
672 | break; | |
673 | #else | |
674 | if (req->fd >= 0) { | |
675 | + | |
676 | +#if PHP_FASTCGI_PM | |
677 | + if (fpm) fpm_request_reading_headers(); | |
678 | +#endif | |
679 | + | |
680 | #if defined(HAVE_SYS_POLL_H) && defined(HAVE_POLL) | |
681 | struct pollfd fds; | |
682 | int ret; | |
8c0dac15 ER |
683 | diff -Nru php-5.2.6.vanilla/sapi/cgi/fastcgi.h php-5.2.6.fpm/sapi/cgi/fastcgi.h |
684 | --- php-5.2.6.vanilla/sapi/cgi/fastcgi.h 2007-12-31 10:20:16.000000000 +0300 | |
685 | +++ php-5.2.6.fpm/sapi/cgi/fastcgi.h 2008-05-01 20:42:06.000000000 +0400 | |
c6a6bfc9 | 686 | @@ -114,6 +114,9 @@ |
fd1be940 ER |
687 | int fcgi_init(void); |
688 | void fcgi_shutdown(void); | |
689 | int fcgi_is_fastcgi(void); | |
690 | +void fcgi_set_is_fastcgi(int); | |
c6a6bfc9 | 691 | +void fcgi_set_in_shutdown(int); |
fd1be940 ER |
692 | +void fcgi_set_allowed_clients(char *); |
693 | int fcgi_in_shutdown(void); | |
694 | int fcgi_listen(const char *path, int backlog); | |
695 | void fcgi_init_request(fcgi_request *req, int listen_socket); | |
c6a6bfc9 | 696 | @@ -128,6 +131,8 @@ |
fd1be940 ER |
697 | int fcgi_write(fcgi_request *req, fcgi_request_type type, const char *str, int len); |
698 | int fcgi_flush(fcgi_request *req, int close); | |
699 | ||
700 | +void fcgi_close(fcgi_request *req, int force, int destroy); | |
701 | + | |
702 | #ifdef PHP_WIN32 | |
703 | void fcgi_impersonate(void); | |
704 | #endif | |
8c0dac15 ER |
705 | diff -Nru php-5.2.6.vanilla/sapi/cgi/fpm/acinclude.m4 php-5.2.6.fpm/sapi/cgi/fpm/acinclude.m4 |
706 | --- php-5.2.6.vanilla/sapi/cgi/fpm/acinclude.m4 1970-01-01 03:00:00.000000000 +0300 | |
707 | +++ php-5.2.6.fpm/sapi/cgi/fpm/acinclude.m4 2008-07-21 06:39:38.000000000 +0400 | |
c6a6bfc9 | 708 | @@ -0,0 +1,383 @@ |
fd1be940 ER |
709 | + |
710 | +AC_DEFUN([AC_FPM_CHECK_FUNC], | |
711 | +[ | |
712 | + SAVED_CFLAGS="$CFLAGS" | |
713 | + CFLAGS="$CFLAGS $2" | |
714 | + SAVED_LIBS="$LIBS" | |
715 | + LIBS="$LIBS $3" | |
716 | + | |
717 | + AC_CHECK_FUNC([$1],[$4],[$5]) | |
718 | + | |
719 | + CFLAGS="$SAVED_CFLAGS" | |
720 | + LIBS="$SAVED_LIBS" | |
721 | +]) | |
722 | + | |
723 | +AC_DEFUN([AC_FPM_LIBEVENT], | |
724 | +[ | |
725 | + AC_ARG_WITH([libevent], | |
726 | + [ --with-libevent=DIR FPM: libevent install directory]) | |
727 | + | |
728 | + LIBEVENT_CFLAGS="" | |
729 | + LIBEVENT_LIBS="-levent" | |
730 | + LIBEVENT_INCLUDE_PATH="" | |
731 | + | |
732 | + if test "$with_libevent" != "no" -a -n "$with_libevent"; then | |
733 | + LIBEVENT_CFLAGS="-I$with_libevent/include" | |
734 | + LIBEVENT_LIBS="-L$with_libevent/lib $LIBEVENT_LIBS" | |
735 | + LIBEVENT_INCLUDE_PATH="$with_libevent/include" | |
736 | + fi | |
737 | + | |
738 | + AC_MSG_CHECKING([for event.h]) | |
739 | + | |
740 | + found=no | |
741 | + | |
742 | + for dir in "$LIBEVENT_INCLUDE_PATH" /usr/include ; do | |
c6a6bfc9 | 743 | + if test -r "$dir/event.h" ; then |
fd1be940 ER |
744 | + found=yes |
745 | + break | |
746 | + fi | |
747 | + done | |
748 | + | |
749 | + AC_MSG_RESULT([$found]) | |
750 | + | |
751 | + AC_FPM_CHECK_FUNC([event_set], [$LIBEVENT_CFLAGS], [$LIBEVENT_LIBS], , | |
752 | + [AC_MSG_ERROR([Failed to link with libevent. Perhaps --with-libevent=DIR option could help.])]) | |
753 | + | |
754 | + AC_FPM_CHECK_FUNC([event_base_free], [$LIBEVENT_CFLAGS], [$LIBEVENT_LIBS], , | |
755 | + [AC_MSG_ERROR([You have too old version. libevent version >= 1.2 is required.])]) | |
756 | + | |
757 | +]) | |
758 | + | |
759 | +AC_DEFUN([AC_FPM_LIBXML], | |
760 | +[ | |
761 | + AC_MSG_RESULT([checking for XML configuration]) | |
762 | + | |
763 | + AC_ARG_WITH(xml-config, | |
764 | + [ --with-xml-config=PATH FPM: use xml-config in PATH to find libxml], | |
765 | + [XMLCONFIG="$withval"], | |
766 | + [AC_PATH_PROGS(XMLCONFIG, [xml2-config xml-config], "")] | |
767 | + ) | |
768 | + | |
769 | + if test "x$XMLCONFIG" = "x"; then | |
770 | + AC_MSG_ERROR([XML configuration could not be found]) | |
771 | + else | |
772 | + AC_MSG_CHECKING([for libxml library]) | |
773 | + | |
774 | + if test ! -x "$XMLCONFIG"; then | |
775 | + AC_MSG_ERROR([$XMLCONFIG cannot be executed]) | |
776 | + fi | |
777 | + | |
778 | + LIBXML_LIBS="`$XMLCONFIG --libs`" | |
779 | + LIBXML_CFLAGS="`$XMLCONFIG --cflags`" | |
780 | + LIBXML_VERSION="`$XMLCONFIG --version`" | |
781 | + | |
782 | + AC_MSG_RESULT([yes, $LIBXML_VERSION]) | |
783 | + | |
784 | + AC_FPM_CHECK_FUNC([xmlParseFile], [$LIBXML_CFLAGS], [$LIBXML_LIBS], , | |
785 | + [AC_MSG_ERROR([Failed to link with libxml])]) | |
786 | + | |
787 | + AC_DEFINE(HAVE_LIBXML, 1, [do we have libxml?]) | |
788 | + fi | |
789 | +]) | |
790 | + | |
791 | +AC_DEFUN([AC_FPM_JUDY], | |
792 | +[ | |
793 | + AC_ARG_WITH([Judy], | |
794 | + [ --with-Judy=DIR FPM: Judy install directory]) | |
795 | + | |
796 | + JUDY_CFLAGS="" | |
797 | + JUDY_LIBS="-lJudy" | |
798 | + JUDY_INCLUDE_PATH="" | |
799 | + | |
800 | + if test "$with_Judy" != "no" -a -n "$with_Judy"; then | |
801 | + JUDY_INCLUDE_PATH="$with_Judy/include" | |
802 | + JUDY_CFLAGS="-I$with_Judy/include $JUDY_CFLAGS" | |
803 | + JUDY_LIBS="-L$with_Judy/lib $JUDY_LIBS" | |
804 | + fi | |
805 | + | |
806 | + AC_MSG_CHECKING([for Judy.h]) | |
807 | + | |
808 | + found=no | |
809 | + | |
810 | + for dir in "$JUDY_INCLUDE_PATH" /usr/include ; do | |
c6a6bfc9 | 811 | + if test -r "$dir/Judy.h" ; then |
fd1be940 ER |
812 | + found=yes |
813 | + break | |
814 | + fi | |
815 | + done | |
816 | + | |
817 | + AC_MSG_RESULT([$found]) | |
818 | + | |
819 | + AC_FPM_CHECK_FUNC([JudyLCount], [$JUDY_CFLAGS], [$JUDY_LIBS], , | |
820 | + [AC_MSG_ERROR([Failed to link with Judy])]) | |
821 | + | |
822 | +]) | |
823 | + | |
c6a6bfc9 ER |
824 | +AC_DEFUN([AC_FPM_CLOCK], |
825 | +[ | |
826 | + have_clock_gettime=no | |
827 | + | |
828 | + AC_MSG_CHECKING([for clock_gettime]) | |
829 | + | |
830 | + AC_TRY_COMPILE([ #include <time.h> ], [struct timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts);], [ | |
831 | + have_clock_gettime=yes | |
832 | + AC_MSG_RESULT([yes]) | |
833 | + ], [ | |
834 | + AC_MSG_RESULT([no]) | |
835 | + ]) | |
836 | + | |
837 | + if test "$have_clock_gettime" = "no"; then | |
838 | + AC_MSG_CHECKING([for clock_gettime in -lrt]) | |
839 | + | |
840 | + SAVED_LIBS="$LIBS" | |
841 | + LIBS="$LIBS -lrt" | |
842 | + | |
843 | + AC_TRY_COMPILE([ #include <time.h> ], [struct timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts);], [ | |
844 | + have_clock_gettime=yes | |
845 | + AC_MSG_RESULT([yes]) | |
846 | + ], [ | |
847 | + LIBS="$SAVED_LIBS" | |
848 | + AC_MSG_RESULT([no]) | |
849 | + ]) | |
850 | + fi | |
851 | + | |
852 | + if test "$have_clock_gettime" = "yes"; then | |
853 | + AC_DEFINE([HAVE_CLOCK_GETTIME], 1, [do we have clock_gettime?]) | |
854 | + fi | |
855 | + | |
856 | + have_clock_get_time=no | |
857 | + | |
858 | + if test "$have_clock_gettime" = "no"; then | |
859 | + AC_MSG_CHECKING([for clock_get_time]) | |
860 | + | |
861 | + AC_TRY_RUN([ #include <mach/mach.h> | |
862 | + #include <mach/clock.h> | |
863 | + #include <mach/mach_error.h> | |
864 | + | |
865 | + int main() | |
866 | + { | |
867 | + kern_return_t ret; clock_serv_t aClock; mach_timespec_t aTime; | |
868 | + ret = host_get_clock_service(mach_host_self(), REALTIME_CLOCK, &aClock); | |
869 | + | |
870 | + if (ret != KERN_SUCCESS) { | |
871 | + return 1; | |
872 | + } | |
873 | + | |
874 | + ret = clock_get_time(aClock, &aTime); | |
875 | + if (ret != KERN_SUCCESS) { | |
876 | + return 2; | |
877 | + } | |
878 | + | |
879 | + return 0; | |
880 | + } | |
881 | + ], [ | |
882 | + have_clock_get_time=yes | |
883 | + AC_MSG_RESULT([yes]) | |
884 | + ], [ | |
885 | + AC_MSG_RESULT([no]) | |
886 | + ]) | |
887 | + fi | |
888 | + | |
889 | + if test "$have_clock_get_time" = "yes"; then | |
890 | + AC_DEFINE([HAVE_CLOCK_GET_TIME], 1, [do we have clock_get_time?]) | |
891 | + fi | |
892 | +]) | |
893 | + | |
894 | +AC_DEFUN([AC_FPM_TRACE], | |
895 | +[ | |
896 | + have_ptrace=no | |
897 | + have_broken_ptrace=no | |
898 | + | |
899 | + AC_MSG_CHECKING([for ptrace]) | |
900 | + | |
901 | + AC_TRY_COMPILE([ | |
902 | + #include <sys/types.h> | |
903 | + #include <sys/ptrace.h> ], [ptrace(0, 0, (void *) 0, 0);], [ | |
904 | + have_ptrace=yes | |
905 | + AC_MSG_RESULT([yes]) | |
906 | + ], [ | |
907 | + AC_MSG_RESULT([no]) | |
908 | + ]) | |
909 | + | |
910 | + if test "$have_ptrace" = "yes"; then | |
911 | + AC_MSG_CHECKING([whether ptrace works]) | |
912 | + | |
913 | + AC_TRY_RUN([ | |
914 | + #include <unistd.h> | |
915 | + #include <signal.h> | |
916 | + #include <sys/wait.h> | |
917 | + #include <sys/types.h> | |
918 | + #include <sys/ptrace.h> | |
919 | + #include <errno.h> | |
920 | + | |
921 | + #if !defined(PTRACE_ATTACH) && defined(PT_ATTACH) | |
922 | + #define PTRACE_ATTACH PT_ATTACH | |
923 | + #endif | |
924 | + | |
925 | + #if !defined(PTRACE_DETACH) && defined(PT_DETACH) | |
926 | + #define PTRACE_DETACH PT_DETACH | |
927 | + #endif | |
928 | + | |
929 | + #if !defined(PTRACE_PEEKDATA) && defined(PT_READ_D) | |
930 | + #define PTRACE_PEEKDATA PT_READ_D | |
931 | + #endif | |
932 | + | |
933 | + int main() | |
934 | + { | |
935 | + long v1 = (unsigned int) -1; /* copy will fail if sizeof(long) == 8 and we've got "int ptrace()" */ | |
936 | + long v2; | |
937 | + pid_t child; | |
938 | + int status; | |
939 | + | |
940 | + if ( (child = fork()) ) { /* parent */ | |
941 | + int ret = 0; | |
942 | + | |
943 | + if (0 > ptrace(PTRACE_ATTACH, child, 0, 0)) { | |
944 | + return 1; | |
945 | + } | |
946 | + | |
947 | + waitpid(child, &status, 0); | |
948 | + | |
949 | + #ifdef PT_IO | |
950 | + struct ptrace_io_desc ptio = { | |
951 | + .piod_op = PIOD_READ_D, | |
952 | + .piod_offs = &v1, | |
953 | + .piod_addr = &v2, | |
954 | + .piod_len = sizeof(v1) | |
955 | + }; | |
956 | + | |
957 | + if (0 > ptrace(PT_IO, child, (void *) &ptio, 0)) { | |
958 | + ret = 1; | |
959 | + } | |
960 | + #else | |
961 | + errno = 0; | |
962 | + | |
963 | + v2 = ptrace(PTRACE_PEEKDATA, child, (void *) &v1, 0); | |
964 | + | |
965 | + if (errno) { | |
966 | + ret = 1; | |
967 | + } | |
968 | + #endif | |
969 | + ptrace(PTRACE_DETACH, child, (void *) 1, 0); | |
970 | + | |
971 | + kill(child, SIGKILL); | |
972 | + | |
973 | + return ret ? ret : (v1 != v2); | |
974 | + } | |
975 | + else { /* child */ | |
976 | + sleep(10); | |
977 | + return 0; | |
978 | + } | |
979 | + } | |
980 | + ], [ | |
981 | + AC_MSG_RESULT([yes]) | |
982 | + ], [ | |
983 | + have_ptrace=no | |
984 | + have_broken_ptrace=yes | |
985 | + AC_MSG_RESULT([no]) | |
986 | + ]) | |
987 | + fi | |
988 | + | |
989 | + if test "$have_ptrace" = "yes"; then | |
990 | + AC_DEFINE([HAVE_PTRACE], 1, [do we have ptrace?]) | |
991 | + fi | |
992 | + | |
993 | + have_mach_vm_read=no | |
994 | + | |
995 | + if test "$have_broken_ptrace" = "yes"; then | |
996 | + AC_MSG_CHECKING([for mach_vm_read]) | |
997 | + | |
998 | + AC_TRY_COMPILE([ #include <mach/mach.h> | |
999 | + #include <mach/mach_vm.h> | |
1000 | + ], [ | |
1001 | + mach_vm_read((vm_map_t)0, (mach_vm_address_t)0, (mach_vm_size_t)0, (vm_offset_t *)0, (mach_msg_type_number_t*)0); | |
1002 | + ], [ | |
1003 | + have_mach_vm_read=yes | |
1004 | + AC_MSG_RESULT([yes]) | |
1005 | + ], [ | |
1006 | + AC_MSG_RESULT([no]) | |
1007 | + ]) | |
1008 | + fi | |
1009 | + | |
1010 | + if test "$have_mach_vm_read" = "yes"; then | |
1011 | + AC_DEFINE([HAVE_MACH_VM_READ], 1, [do we have mach_vm_read?]) | |
1012 | + fi | |
1013 | + | |
1014 | + proc_mem_file="" | |
1015 | + | |
1016 | + if test -r /proc/$$/mem ; then | |
1017 | + proc_mem_file="mem" | |
1018 | + else | |
1019 | + if test -r /proc/$$/as ; then | |
1020 | + proc_mem_file="as" | |
1021 | + fi | |
1022 | + fi | |
1023 | + | |
1024 | + if test -n "$proc_mem_file" ; then | |
1025 | + AC_MSG_CHECKING([for proc mem file]) | |
1026 | + | |
1027 | + AC_TRY_RUN([ | |
1028 | + #define _GNU_SOURCE | |
1029 | + #define _FILE_OFFSET_BITS 64 | |
1030 | + #include <stdint.h> | |
1031 | + #include <unistd.h> | |
1032 | + #include <sys/types.h> | |
1033 | + #include <sys/stat.h> | |
1034 | + #include <fcntl.h> | |
1035 | + #include <stdio.h> | |
1036 | + int main() | |
1037 | + { | |
1038 | + long v1 = (unsigned int) -1, v2 = 0; | |
1039 | + char buf[128]; | |
1040 | + int fd; | |
1041 | + sprintf(buf, "/proc/%d/$proc_mem_file", getpid()); | |
1042 | + fd = open(buf, O_RDONLY); | |
1043 | + if (0 > fd) { | |
1044 | + return 1; | |
1045 | + } | |
1046 | + if (sizeof(long) != pread(fd, &v2, sizeof(long), (uintptr_t) &v1)) { | |
1047 | + close(fd); | |
1048 | + return 1; | |
1049 | + } | |
1050 | + close(fd); | |
1051 | + return v1 != v2; | |
1052 | + } | |
1053 | + ], [ | |
1054 | + AC_MSG_RESULT([$proc_mem_file]) | |
1055 | + ], [ | |
1056 | + proc_mem_file="" | |
1057 | + AC_MSG_RESULT([no]) | |
1058 | + ]) | |
1059 | + fi | |
1060 | + | |
1061 | + if test -n "$proc_mem_file"; then | |
1062 | + AC_DEFINE_UNQUOTED([PROC_MEM_FILE], "$proc_mem_file", [/proc/pid/mem interface]) | |
1063 | + fi | |
1064 | + | |
1065 | + FPM_TRACE_SRCS="" | |
1066 | + | |
1067 | + if test "$have_ptrace" = "yes"; then | |
1068 | + FPM_TRACE_SRCS="fpm_trace_ptrace.c" | |
1069 | + elif test -n "$proc_mem_file"; then | |
1070 | + FPM_TRACE_SRCS="fpm_trace_pread.c" | |
1071 | + elif test "$have_mach_vm_read" = "yes" ; then | |
1072 | + FPM_TRACE_SRCS="fpm_trace_mach.c" | |
1073 | + fi | |
1074 | + | |
1075 | + if test -n "$FPM_TRACE_SRCS"; then | |
1076 | + FPM_TRACE_SRCS="fpm_trace.c $FPM_TRACE_SRCS" | |
1077 | + fi | |
1078 | + | |
1079 | +]) | |
1080 | + | |
1081 | +AC_DEFUN([AC_FPM_PRCTL], | |
1082 | +[ | |
1083 | + AC_MSG_CHECKING([for prctl]) | |
1084 | + | |
1085 | + AC_TRY_COMPILE([ #include <sys/prctl.h> ], [prctl(0, 0, 0, 0, 0);], [ | |
1086 | + AC_DEFINE([HAVE_PRCTL], 1, [do we have prctl?]) | |
1087 | + AC_MSG_RESULT([yes]) | |
1088 | + ], [ | |
1089 | + AC_MSG_RESULT([no]) | |
1090 | + ]) | |
1091 | +]) | |
8c0dac15 ER |
1092 | diff -Nru php-5.2.6.vanilla/sapi/cgi/fpm/conf/php-fpm.conf.in php-5.2.6.fpm/sapi/cgi/fpm/conf/php-fpm.conf.in |
1093 | --- php-5.2.6.vanilla/sapi/cgi/fpm/conf/php-fpm.conf.in 1970-01-01 03:00:00.000000000 +0300 | |
1094 | +++ php-5.2.6.fpm/sapi/cgi/fpm/conf/php-fpm.conf.in 2008-05-23 00:53:15.000000000 +0400 | |
c6a6bfc9 | 1095 | @@ -0,0 +1,156 @@ |
fd1be940 ER |
1096 | +<?xml version="1.0" ?> |
1097 | +<configuration> | |
1098 | + | |
1099 | + All relative paths in this config are relative to php's install prefix | |
1100 | + | |
1101 | + <section name="global_options"> | |
1102 | + | |
1103 | + Pid file | |
c6a6bfc9 | 1104 | + <value name="pid_file">@php_fpm_pid_path@</value> |
fd1be940 ER |
1105 | + |
1106 | + Error log file | |
c6a6bfc9 ER |
1107 | + <value name="error_log">@php_fpm_log_path@</value> |
1108 | + | |
1109 | + Log level | |
1110 | + <value name="log_level">notice</value> | |
fd1be940 ER |
1111 | + |
1112 | + When this amount of php processes exited with SIGSEGV or SIGBUS ... | |
1113 | + <value name="emergency_restart_threshold">10</value> | |
1114 | + | |
c6a6bfc9 | 1115 | + ... in a less than this interval of time, a graceful restart will be initiated. |
fd1be940 ER |
1116 | + Useful to work around accidental curruptions in accelerator's shared memory. |
1117 | + <value name="emergency_restart_interval">1m</value> | |
1118 | + | |
1119 | + Time limit on waiting child's reaction on signals from master | |
1120 | + <value name="process_control_timeout">5s</value> | |
1121 | + | |
1122 | + Set to 'no' to debug fpm | |
1123 | + <value name="daemonize">yes</value> | |
1124 | + | |
1125 | + </section> | |
1126 | + | |
1127 | + <workers> | |
1128 | + | |
1129 | + <section name="pool"> | |
1130 | + | |
1131 | + Name of pool. Used in logs and stats. | |
c6a6bfc9 | 1132 | + <value name="name">default</value> |
fd1be940 ER |
1133 | + |
1134 | + Address to accept fastcgi requests on. | |
1135 | + Valid syntax is 'ip.ad.re.ss:port' or just 'port' or '/path/to/unix/socket' | |
1136 | + <value name="listen_address">127.0.0.1:9000</value> | |
1137 | + | |
1138 | + <value name="listen_options"> | |
1139 | + | |
1140 | + Set listen(2) backlog | |
1141 | + <value name="backlog">-1</value> | |
1142 | + | |
1143 | + Set permissions for unix socket, if one used. | |
1144 | + In Linux read/write permissions must be set in order to allow connections from web server. | |
1145 | + Many BSD-derrived systems allow connections regardless of permissions. | |
1146 | + <value name="owner"></value> | |
1147 | + <value name="group"></value> | |
1148 | + <value name="mode">0666</value> | |
1149 | + </value> | |
1150 | + | |
1151 | + Additional php.ini defines, specific to this pool of workers. | |
1152 | + <value name="php_defines"> | |
1153 | + <!-- <value name="sendmail_path">/usr/sbin/sendmail -t -i</value> --> | |
1154 | + <!-- <value name="display_errors">0</value> --> | |
1155 | + </value> | |
1156 | + | |
1157 | + Unix user of processes | |
c6a6bfc9 | 1158 | + <!-- <value name="user">nobody</value> --> |
fd1be940 ER |
1159 | + |
1160 | + Unix group of processes | |
c6a6bfc9 | 1161 | + <!-- <value name="group">@php_fpm_group@</value> --> |
fd1be940 ER |
1162 | + |
1163 | + Process manager settings | |
1164 | + <value name="pm"> | |
1165 | + | |
1166 | + Sets style of controling worker process count. | |
1167 | + Valid values are 'static' and 'apache-like' | |
1168 | + <value name="style">static</value> | |
1169 | + | |
1170 | + Sets the limit on the number of simultaneous requests that will be served. | |
1171 | + Equivalent to Apache MaxClients directive. | |
1172 | + Equivalent to PHP_FCGI_CHILDREN environment in original php.fcgi | |
1173 | + Used with any pm_style. | |
1174 | + <value name="max_children">5</value> | |
1175 | + | |
1176 | + Settings group for 'apache-like' pm style | |
1177 | + <value name="apache_like"> | |
1178 | + | |
1179 | + Sets the number of server processes created on startup. | |
1180 | + Used only when 'apache-like' pm_style is selected | |
1181 | + <value name="StartServers">20</value> | |
1182 | + | |
1183 | + Sets the desired minimum number of idle server processes. | |
1184 | + Used only when 'apache-like' pm_style is selected | |
1185 | + <value name="MinSpareServers">5</value> | |
1186 | + | |
1187 | + Sets the desired maximum number of idle server processes. | |
1188 | + Used only when 'apache-like' pm_style is selected | |
1189 | + <value name="MaxSpareServers">35</value> | |
1190 | + | |
1191 | + </value> | |
1192 | + | |
1193 | + </value> | |
1194 | + | |
c6a6bfc9 ER |
1195 | + The timeout (in seconds) for serving a single request after which the worker process will be terminated |
1196 | + Should be used when 'max_execution_time' ini option does not stop script execution for some reason | |
1197 | + '0s' means 'off' | |
1198 | + <value name="request_terminate_timeout">0s</value> | |
1199 | + | |
1200 | + The timeout (in seconds) for serving of single request after which a php backtrace will be dumped to slow.log file | |
1201 | + '0s' means 'off' | |
1202 | + <value name="request_slowlog_timeout">0s</value> | |
1203 | + | |
1204 | + The log file for slow requests | |
1205 | + <value name="slowlog">logs/slow.log</value> | |
fd1be940 ER |
1206 | + |
1207 | + Set open file desc rlimit | |
1208 | + <value name="rlimit_files">1024</value> | |
1209 | + | |
1210 | + Set max core size rlimit | |
c6a6bfc9 | 1211 | + <value name="rlimit_core">0</value> |
fd1be940 | 1212 | + |
c6a6bfc9 | 1213 | + Chroot to this directory at the start, absolute path |
fd1be940 ER |
1214 | + <value name="chroot"></value> |
1215 | + | |
c6a6bfc9 | 1216 | + Chdir to this directory at the start, absolute path |
fd1be940 ER |
1217 | + <value name="chdir"></value> |
1218 | + | |
c6a6bfc9 | 1219 | + Redirect workers' stdout and stderr into main error log. |
fd1be940 ER |
1220 | + If not set, they will be redirected to /dev/null, according to FastCGI specs |
1221 | + <value name="catch_workers_output">yes</value> | |
1222 | + | |
1223 | + How much requests each process should execute before respawn. | |
1224 | + Useful to work around memory leaks in 3rd party libraries. | |
1225 | + For endless request processing please specify 0 | |
1226 | + Equivalent to PHP_FCGI_MAX_REQUESTS | |
1227 | + <value name="max_requests">500</value> | |
1228 | + | |
1229 | + Comma separated list of ipv4 addresses of FastCGI clients that allowed to connect. | |
1230 | + Equivalent to FCGI_WEB_SERVER_ADDRS environment in original php.fcgi (5.2.2+) | |
1231 | + Makes sense only with AF_INET listening socket. | |
1232 | + <value name="allowed_clients">127.0.0.1</value> | |
1233 | + | |
1234 | + Pass environment variables like LD_LIBRARY_PATH | |
1235 | + All $VARIABLEs are taken from current environment | |
1236 | + <value name="environment"> | |
1237 | + <value name="HOSTNAME">$HOSTNAME</value> | |
1238 | + <value name="PATH">/usr/local/bin:/usr/bin:/bin</value> | |
1239 | + <value name="TMP">/tmp</value> | |
1240 | + <value name="TMPDIR">/tmp</value> | |
1241 | + <value name="TEMP">/tmp</value> | |
1242 | + <value name="OSTYPE">$OSTYPE</value> | |
1243 | + <value name="MACHTYPE">$MACHTYPE</value> | |
1244 | + <value name="MALLOC_CHECK_">2</value> | |
1245 | + </value> | |
1246 | + | |
1247 | + </section> | |
1248 | + | |
1249 | + </workers> | |
1250 | + | |
1251 | +</configuration> | |
75ddaf45 ER |
1252 | --- php-5.2.6.fpm/sapi/cgi/fpm/config.m4 2008-09-19 05:22:37.000000000 +0400 |
1253 | +++ php-5.2.6.fpm/sapi/cgi/fpm/config.m4 2008-09-19 05:22:37.000000000 +0400 | |
1254 | @@ -0,0 +1,118 @@ | |
c6a6bfc9 ER |
1255 | + |
1256 | +FPM_VERSION="0.5.9" | |
1257 | + | |
1258 | +PHP_ARG_WITH(fpm-conf, for php-fpm config file path, | |
1259 | +[ --with-fpm-conf=PATH Set the path for php-fpm configuration file [PREFIX/etc/php-fpm.conf]], \$prefix/etc/php-fpm.conf, no) | |
1260 | + | |
1261 | +PHP_ARG_WITH(fpm-log, for php-fpm log file path, | |
1262 | +[ --with-fpm-log=PATH Set the path for php-fpm log file [PREFIX/logs/php-fpm.log]], \$prefix/logs/php-fpm.log, no) | |
1263 | + | |
1264 | +PHP_ARG_WITH(fpm-pid, for php-fpm pid file path, | |
1265 | +[ --with-fpm-pid=PATH Set the path for php-fpm pid file [PREFIX/logs/php-fpm.pid]], \$prefix/logs/php-fpm.pid, no) | |
fd1be940 ER |
1266 | + |
1267 | +dnl AC_FPM_LIBEVENT | |
1268 | +AC_FPM_LIBXML | |
c6a6bfc9 ER |
1269 | +AC_FPM_PRCTL |
1270 | +AC_FPM_CLOCK | |
1271 | +AC_FPM_TRACE | |
fd1be940 ER |
1272 | +dnl AC_FPM_JUDY |
1273 | + | |
75ddaf45 ER |
1274 | +LIBEVENT_CFLAGS="" |
1275 | +LIBEVENT_LIBS="-levent" | |
fd1be940 ER |
1276 | + |
1277 | +SAPI_EXTRA_DEPS="$LIBEVENT_LIBS" | |
1278 | + | |
c6a6bfc9 ER |
1279 | +FPM_SOURCES="fpm.c \ |
1280 | + fpm_conf.c \ | |
1281 | + fpm_signals.c \ | |
1282 | + fpm_children.c \ | |
1283 | + fpm_worker_pool.c \ | |
1284 | + fpm_unix.c \ | |
1285 | + fpm_cleanup.c \ | |
1286 | + fpm_sockets.c \ | |
1287 | + fpm_stdio.c \ | |
1288 | + fpm_env.c \ | |
1289 | + fpm_events.c \ | |
1290 | + fpm_php.c \ | |
1291 | + fpm_php_trace.c \ | |
1292 | + $FPM_TRACE_SRCS \ | |
1293 | + fpm_process_ctl.c \ | |
1294 | + fpm_request.c \ | |
1295 | + fpm_clock.c \ | |
1296 | + fpm_shm.c \ | |
1297 | + fpm_shm_slots.c \ | |
1298 | + xml_config.c \ | |
1299 | + zlog.c" | |
fd1be940 ER |
1300 | + |
1301 | +FPM_CFLAGS="$LIBEVENT_CFLAGS $LIBXML_CFLAGS $JUDY_CFLAGS" | |
fd1be940 ER |
1302 | + |
1303 | +dnl FPM_CFLAGS="$FPM_CFLAGS -DJUDYERROR_NOTEST" # for Judy | |
8c0dac15 | 1304 | +FPM_CFLAGS="$FPM_CFLAGS -I$abs_srcdir/sapi/cgi" # for fastcgi.h |
fd1be940 | 1305 | + |
c6a6bfc9 ER |
1306 | +if test "$ICC" = "yes" ; then |
1307 | + FPM_ADD_CFLAGS="-Wall -wd279,310,869,810,981" | |
1308 | +elif test "$GCC" = "yes" ; then | |
1309 | + FPM_ADD_CFLAGS="-Wall -Wpointer-arith -Wno-unused-parameter -Wunused-variable -Wunused-value -fno-strict-aliasing" | |
1310 | +fi | |
1311 | + | |
1312 | +if test -n "$FPM_WERROR" ; then | |
1313 | + FPM_ADD_CFLAGS="$FPM_ADD_CFLAGS -Werror" | |
fd1be940 ER |
1314 | +fi |
1315 | + | |
c6a6bfc9 ER |
1316 | +FPM_CFLAGS="$FPM_ADD_CFLAGS $FPM_CFLAGS" |
1317 | + | |
8c0dac15 | 1318 | +PHP_ADD_MAKEFILE_FRAGMENT($abs_srcdir/sapi/cgi/fpm/Makefile.frag) |
fd1be940 | 1319 | + |
8c0dac15 | 1320 | +PHP_ADD_SOURCES(sapi/cgi/fpm, $FPM_SOURCES, $FPM_CFLAGS, sapi) |
fd1be940 | 1321 | + |
8c0dac15 | 1322 | +PHP_ADD_BUILD_DIR(sapi/cgi/fpm) |
fd1be940 ER |
1323 | + |
1324 | +install_fpm="install-fpm" | |
1325 | + | |
c6a6bfc9 ER |
1326 | +SAPI_EXTRA_LIBS="$LIBEVENT_LIBS $LIBXML_LIBS $JUDY_LIBS" |
1327 | + | |
1328 | + | |
1329 | +if test "$prefix" = "NONE" ; then | |
1330 | + fpm_prefix=/usr/local | |
1331 | +else | |
1332 | + fpm_prefix="$prefix" | |
1333 | +fi | |
1334 | + | |
1335 | +if test "$PHP_FPM_CONF" = "\$prefix/etc/php-fpm.conf" ; then | |
1336 | + php_fpm_conf_path="$fpm_prefix/etc/php-fpm.conf" | |
1337 | +else | |
1338 | + php_fpm_conf_path="$PHP_FPM_CONF" | |
1339 | +fi | |
1340 | + | |
1341 | +if test "$PHP_FPM_LOG" = "\$prefix/logs/php-fpm.log" ; then | |
1342 | + php_fpm_log_path="$fpm_prefix/logs/php-fpm.log" | |
1343 | +else | |
1344 | + php_fpm_log_path="$PHP_FPM_LOG" | |
1345 | +fi | |
1346 | + | |
1347 | +if test "$PHP_FPM_PID" = "\$prefix/logs/php-fpm.pid" ; then | |
1348 | + php_fpm_pid_path="$fpm_prefix/logs/php-fpm.pid" | |
1349 | +else | |
1350 | + php_fpm_pid_path="$PHP_FPM_PID" | |
1351 | +fi | |
1352 | + | |
1353 | + | |
1354 | +if grep nobody /etc/group >/dev/null 2>&1; then | |
1355 | + php_fpm_group=nobody | |
1356 | +else | |
1357 | + if grep nogroup /etc/group >/dev/null 2>&1; then | |
1358 | + php_fpm_group=nogroup | |
1359 | + else | |
1360 | + php_fpm_group=nobody | |
1361 | + fi | |
1362 | +fi | |
1363 | + | |
1364 | +PHP_SUBST_OLD(php_fpm_conf_path) | |
1365 | +PHP_SUBST_OLD(php_fpm_log_path) | |
1366 | +PHP_SUBST_OLD(php_fpm_pid_path) | |
1367 | +PHP_SUBST_OLD(php_fpm_group) | |
1368 | +PHP_SUBST_OLD(FPM_VERSION) | |
1369 | + | |
8c0dac15 ER |
1370 | +PHP_OUTPUT(sapi/cgi/fpm/fpm_autoconf.h) |
1371 | +PHP_OUTPUT(sapi/cgi/fpm/php-fpm.conf:sapi/cgi/fpm/conf/php-fpm.conf.in) | |
1372 | +PHP_OUTPUT(sapi/cgi/fpm/php-fpm:sapi/cgi/fpm/init.d/php-fpm.in) | |
1373 | diff -Nru php-5.2.6.vanilla/sapi/cgi/fpm/fpm_arrays.h php-5.2.6.fpm/sapi/cgi/fpm/fpm_arrays.h | |
1374 | --- php-5.2.6.vanilla/sapi/cgi/fpm/fpm_arrays.h 1970-01-01 03:00:00.000000000 +0300 | |
1375 | +++ php-5.2.6.fpm/sapi/cgi/fpm/fpm_arrays.h 2008-05-24 21:38:47.000000000 +0400 | |
c6a6bfc9 ER |
1376 | @@ -0,0 +1,110 @@ |
1377 | + | |
1378 | + /* $Id$ */ | |
1379 | + /* (c) 2007,2008 Andrei Nigmatulin */ | |
1380 | + | |
1381 | +#ifndef FPM_ARRAYS_H | |
1382 | +#define FPM_ARRAYS_H 1 | |
1383 | + | |
1384 | +#include <stdlib.h> | |
1385 | +#include <string.h> | |
1386 | + | |
1387 | +struct fpm_array_s { | |
1388 | + void *data; | |
1389 | + size_t sz; | |
1390 | + size_t used; | |
1391 | + size_t allocated; | |
1392 | +}; | |
1393 | + | |
1394 | +static inline struct fpm_array_s *fpm_array_init(struct fpm_array_s *a, unsigned int sz, unsigned int initial_num) | |
1395 | +{ | |
1396 | + void *allocated = 0; | |
1397 | + | |
1398 | + if (!a) { | |
1399 | + a = malloc(sizeof(struct fpm_array_s)); | |
1400 | + | |
1401 | + if (!a) { | |
1402 | + return 0; | |
1403 | + } | |
1404 | + | |
1405 | + allocated = a; | |
1406 | + } | |
1407 | + | |
1408 | + a->sz = sz; | |
1409 | + | |
1410 | + a->data = calloc(sz, initial_num); | |
1411 | + | |
1412 | + if (!a->data) { | |
1413 | + free(allocated); | |
1414 | + return 0; | |
1415 | + } | |
1416 | + | |
1417 | + a->allocated = initial_num; | |
1418 | + a->used = 0; | |
1419 | + | |
1420 | + return a; | |
1421 | +} | |
1422 | + | |
1423 | +static inline void *fpm_array_item(struct fpm_array_s *a, unsigned int n) | |
1424 | +{ | |
1425 | + char *ret; | |
1426 | + | |
1427 | + ret = (char *) a->data + a->sz * n; | |
1428 | + | |
1429 | + return ret; | |
1430 | +} | |
1431 | + | |
1432 | +static inline void *fpm_array_item_last(struct fpm_array_s *a) | |
1433 | +{ | |
1434 | + return fpm_array_item(a, a->used - 1); | |
1435 | +} | |
1436 | + | |
1437 | +static inline int fpm_array_item_remove(struct fpm_array_s *a, unsigned int n) | |
1438 | +{ | |
1439 | + int ret = -1; | |
1440 | + | |
1441 | + if (n < a->used - 1) { | |
1442 | + void *last = fpm_array_item(a, a->used - 1); | |
1443 | + void *to_remove = fpm_array_item(a, n); | |
1444 | + | |
1445 | + memcpy(to_remove, last, a->sz); | |
1446 | + | |
1447 | + ret = n; | |
1448 | + } | |
1449 | + | |
1450 | + --a->used; | |
1451 | + | |
1452 | + return ret; | |
1453 | +} | |
1454 | + | |
1455 | +static inline void *fpm_array_push(struct fpm_array_s *a) | |
1456 | +{ | |
1457 | + void *ret; | |
1458 | + | |
1459 | + if (a->used == a->allocated) { | |
1460 | + size_t new_allocated = a->allocated ? a->allocated * 2 : 20; | |
1461 | + void *new_ptr = realloc(a->data, a->sz * new_allocated); | |
1462 | + | |
1463 | + if (!new_ptr) { | |
1464 | + return 0; | |
1465 | + } | |
1466 | + | |
1467 | + a->data = new_ptr; | |
1468 | + a->allocated = new_allocated; | |
1469 | + } | |
1470 | + | |
1471 | + ret = fpm_array_item(a, a->used); | |
1472 | + | |
1473 | + ++a->used; | |
1474 | + | |
1475 | + return ret; | |
1476 | +} | |
1477 | + | |
1478 | +static inline void fpm_array_free(struct fpm_array_s *a) | |
1479 | +{ | |
1480 | + free(a->data); | |
1481 | + a->data = 0; | |
1482 | + a->sz = 0; | |
1483 | + a->used = a->allocated = 0; | |
1484 | +} | |
1485 | + | |
1486 | +#endif | |
8c0dac15 ER |
1487 | diff -Nru php-5.2.6.vanilla/sapi/cgi/fpm/fpm_atomic.h php-5.2.6.fpm/sapi/cgi/fpm/fpm_atomic.h |
1488 | --- php-5.2.6.vanilla/sapi/cgi/fpm/fpm_atomic.h 1970-01-01 03:00:00.000000000 +0300 | |
1489 | +++ php-5.2.6.fpm/sapi/cgi/fpm/fpm_atomic.h 2008-09-19 03:34:11.000000000 +0400 | |
c6a6bfc9 | 1490 | @@ -0,0 +1,85 @@ |
fd1be940 ER |
1491 | + |
1492 | + /* $Id$ */ | |
c6a6bfc9 ER |
1493 | + /* (c) 2007,2008 Andrei Nigmatulin */ |
1494 | + | |
1495 | +#ifndef FPM_ATOMIC_H | |
1496 | +#define FPM_ATOMIC_H 1 | |
1497 | + | |
1498 | +#include <stdint.h> | |
1499 | +#include <sched.h> | |
1500 | + | |
1501 | +#if ( __i386__ || __i386 ) | |
1502 | + | |
1503 | +typedef int32_t atomic_int_t; | |
1504 | +typedef uint32_t atomic_uint_t; | |
1505 | +typedef volatile atomic_uint_t atomic_t; | |
1506 | + | |
1507 | + | |
1508 | +static inline atomic_int_t atomic_fetch_add(atomic_t *value, atomic_int_t add) | |
1509 | +{ | |
1510 | + __asm__ volatile ( "lock;" "xaddl %0, %1;" : | |
1511 | + "+r" (add) : "m" (*value) : "memory"); | |
1512 | + | |
1513 | + return add; | |
1514 | +} | |
1515 | + | |
1516 | +static inline atomic_uint_t atomic_cmp_set(atomic_t *lock, atomic_uint_t old, atomic_uint_t set) | |
1517 | +{ | |
1518 | + unsigned char res; | |
1519 | + | |
1520 | + __asm__ volatile ( "lock;" "cmpxchgl %3, %1;" "sete %0;" : | |
1521 | + "=a" (res) : "m" (*lock), "a" (old), "r" (set) : "memory"); | |
1522 | + | |
1523 | + return res; | |
1524 | +} | |
1525 | + | |
1526 | +#elif ( __amd64__ || __amd64 ) | |
1527 | + | |
1528 | +typedef int64_t atomic_int_t; | |
1529 | +typedef uint64_t atomic_uint_t; | |
1530 | +typedef volatile atomic_uint_t atomic_t; | |
1531 | + | |
1532 | +static inline atomic_int_t atomic_fetch_add(atomic_t *value, atomic_int_t add) | |
1533 | +{ | |
1534 | + __asm__ volatile ( "lock;" "xaddq %0, %1;" : | |
1535 | + "+r" (add) : "m" (*value) : "memory"); | |
1536 | + | |
1537 | + return add; | |
1538 | +} | |
1539 | + | |
1540 | +static inline atomic_uint_t atomic_cmp_set(atomic_t *lock, atomic_uint_t old, atomic_uint_t set) | |
1541 | +{ | |
1542 | + unsigned char res; | |
1543 | + | |
1544 | + __asm__ volatile ( "lock;" "cmpxchgq %3, %1;" "sete %0;" : | |
1545 | + "=a" (res) : "m" (*lock), "a" (old), "r" (set) : "memory"); | |
1546 | + | |
1547 | + return res; | |
1548 | +} | |
1549 | + | |
1550 | +#else | |
1551 | + | |
1552 | +#error unsupported processor. please write a patch and send it to me | |
1553 | + | |
1554 | +#endif | |
1555 | + | |
1556 | +static inline int fpm_spinlock(atomic_t *lock, int try_once) | |
1557 | +{ | |
1558 | + if (try_once) { | |
1559 | + return atomic_cmp_set(lock, 0, 1) ? 0 : -1; | |
1560 | + } | |
1561 | + | |
1562 | + for (;;) { | |
1563 | + | |
1564 | + if (atomic_cmp_set(lock, 0, 1)) { | |
1565 | + break; | |
1566 | + } | |
1567 | + | |
1568 | + sched_yield(); | |
1569 | + } | |
1570 | + | |
1571 | + return 0; | |
1572 | +} | |
1573 | + | |
1574 | +#endif | |
1575 | + | |
8c0dac15 ER |
1576 | diff -Nru php-5.2.6.vanilla/sapi/cgi/fpm/fpm_autoconf.h.in php-5.2.6.fpm/sapi/cgi/fpm/fpm_autoconf.h.in |
1577 | --- php-5.2.6.vanilla/sapi/cgi/fpm/fpm_autoconf.h.in 1970-01-01 03:00:00.000000000 +0300 | |
1578 | +++ php-5.2.6.fpm/sapi/cgi/fpm/fpm_autoconf.h.in 2008-05-24 21:38:47.000000000 +0400 | |
c6a6bfc9 ER |
1579 | @@ -0,0 +1,9 @@ |
1580 | + | |
1581 | + /* $Id$ */ | |
1582 | + /* (c) 2007,2008 Andrei Nigmatulin */ | |
1583 | + | |
1584 | +#define PHP_FPM_VERSION "@FPM_VERSION@" | |
1585 | +#define PHP_FPM_CONF_PATH "@php_fpm_conf_path@" | |
1586 | +#define PHP_FPM_LOG_PATH "@php_fpm_log_path@" | |
1587 | +#define PHP_FPM_PID_PATH "@php_fpm_pid_path@" | |
1588 | + | |
8c0dac15 ER |
1589 | diff -Nru php-5.2.6.vanilla/sapi/cgi/fpm/fpm.c php-5.2.6.fpm/sapi/cgi/fpm/fpm.c |
1590 | --- php-5.2.6.vanilla/sapi/cgi/fpm/fpm.c 1970-01-01 03:00:00.000000000 +0300 | |
1591 | +++ php-5.2.6.fpm/sapi/cgi/fpm/fpm.c 2008-07-20 20:38:31.000000000 +0400 | |
c6a6bfc9 ER |
1592 | @@ -0,0 +1,84 @@ |
1593 | + | |
1594 | + /* $Id$ */ | |
1595 | + /* (c) 2007,2008 Andrei Nigmatulin */ | |
fd1be940 ER |
1596 | + |
1597 | +#include "fpm_config.h" | |
1598 | + | |
1599 | +#include <stdlib.h> /* for exit */ | |
1600 | + | |
1601 | +#include "fpm.h" | |
1602 | +#include "fpm_children.h" | |
1603 | +#include "fpm_signals.h" | |
1604 | +#include "fpm_env.h" | |
1605 | +#include "fpm_events.h" | |
1606 | +#include "fpm_cleanup.h" | |
1607 | +#include "fpm_php.h" | |
1608 | +#include "fpm_sockets.h" | |
1609 | +#include "fpm_unix.h" | |
1610 | +#include "fpm_process_ctl.h" | |
1611 | +#include "fpm_conf.h" | |
1612 | +#include "fpm_worker_pool.h" | |
1613 | +#include "fpm_stdio.h" | |
1614 | +#include "zlog.h" | |
1615 | + | |
c6a6bfc9 ER |
1616 | +int fpm; |
1617 | + | |
fd1be940 ER |
1618 | +struct fpm_globals_s fpm_globals; |
1619 | + | |
1620 | +int fpm_init(int argc, char **argv, char *config) | |
1621 | +{ | |
c6a6bfc9 ER |
1622 | + fpm_globals.argc = argc; |
1623 | + fpm_globals.argv = argv; | |
1624 | + fpm_globals.config = config; | |
fd1be940 | 1625 | + |
c6a6bfc9 ER |
1626 | + if (0 > fpm_php_init_main() || |
1627 | + 0 > fpm_stdio_init_main() || | |
1628 | + 0 > fpm_conf_init_main() || | |
fd1be940 ER |
1629 | + 0 > fpm_unix_init_main() || |
1630 | + 0 > fpm_env_init_main() || | |
1631 | + 0 > fpm_signals_init_main() || | |
c6a6bfc9 | 1632 | + 0 > fpm_pctl_init_main() || |
fd1be940 ER |
1633 | + 0 > fpm_children_init_main() || |
1634 | + 0 > fpm_sockets_init_main() || | |
fd1be940 | 1635 | + 0 > fpm_worker_pool_init_main() || |
c6a6bfc9 | 1636 | + 0 > fpm_event_init_main()) { |
fd1be940 ER |
1637 | + return -1; |
1638 | + } | |
1639 | + | |
1640 | + if (0 > fpm_conf_write_pid()) { | |
1641 | + return -1; | |
1642 | + } | |
1643 | + | |
c6a6bfc9 | 1644 | + zlog(ZLOG_STUFF, ZLOG_NOTICE, "fpm is running, pid %d", (int) fpm_globals.parent_pid); |
fd1be940 ER |
1645 | + |
1646 | + return 0; | |
1647 | +} | |
1648 | + | |
1649 | +/* children: return listening socket | |
1650 | + parent: never return */ | |
1651 | +int fpm_run(int *max_requests) | |
1652 | +{ | |
1653 | + struct fpm_worker_pool_s *wp; | |
1654 | + | |
1655 | + /* create initial children in all pools */ | |
1656 | + for (wp = fpm_worker_all_pools; wp; wp = wp->next) { | |
1657 | + int is_parent; | |
1658 | + | |
1659 | + is_parent = fpm_children_create_initial(wp); | |
1660 | + | |
1661 | + if (!is_parent) { | |
1662 | + goto run_child; | |
1663 | + } | |
1664 | + } | |
1665 | + | |
1666 | + /* run event loop forever */ | |
1667 | + fpm_event_loop(); | |
1668 | + | |
c6a6bfc9 | 1669 | +run_child: /* only workers reach this point */ |
fd1be940 ER |
1670 | + |
1671 | + fpm_cleanups_run(FPM_CLEANUP_CHILD); | |
1672 | + | |
1673 | + *max_requests = fpm_globals.max_requests; | |
1674 | + return fpm_globals.listening_socket; | |
1675 | +} | |
1676 | + | |
8c0dac15 ER |
1677 | diff -Nru php-5.2.6.vanilla/sapi/cgi/fpm/fpm_children.c php-5.2.6.fpm/sapi/cgi/fpm/fpm_children.c |
1678 | --- php-5.2.6.vanilla/sapi/cgi/fpm/fpm_children.c 1970-01-01 03:00:00.000000000 +0300 | |
1679 | +++ php-5.2.6.fpm/sapi/cgi/fpm/fpm_children.c 2008-08-26 19:09:15.000000000 +0400 | |
c6a6bfc9 | 1680 | @@ -0,0 +1,383 @@ |
fd1be940 ER |
1681 | + |
1682 | + /* $Id$ */ | |
c6a6bfc9 | 1683 | + /* (c) 2007,2008 Andrei Nigmatulin */ |
fd1be940 ER |
1684 | + |
1685 | +#include "fpm_config.h" | |
1686 | + | |
1687 | +#include <sys/types.h> | |
1688 | +#include <sys/wait.h> | |
1689 | +#include <time.h> | |
1690 | +#include <unistd.h> | |
1691 | +#include <string.h> | |
1692 | +#include <stdio.h> | |
1693 | + | |
1694 | +#include "fpm.h" | |
1695 | +#include "fpm_children.h" | |
1696 | +#include "fpm_signals.h" | |
1697 | +#include "fpm_worker_pool.h" | |
1698 | +#include "fpm_sockets.h" | |
1699 | +#include "fpm_process_ctl.h" | |
1700 | +#include "fpm_php.h" | |
1701 | +#include "fpm_conf.h" | |
1702 | +#include "fpm_cleanup.h" | |
1703 | +#include "fpm_events.h" | |
c6a6bfc9 | 1704 | +#include "fpm_clock.h" |
fd1be940 ER |
1705 | +#include "fpm_stdio.h" |
1706 | +#include "fpm_unix.h" | |
1707 | +#include "fpm_env.h" | |
c6a6bfc9 | 1708 | +#include "fpm_shm_slots.h" |
fd1be940 ER |
1709 | + |
1710 | +#include "zlog.h" | |
1711 | + | |
1712 | +static time_t *last_faults; | |
1713 | +static int fault; | |
1714 | + | |
fd1be940 ER |
1715 | +static int fpm_children_make(struct fpm_worker_pool_s *wp, int in_event_loop); |
1716 | + | |
1717 | +static void fpm_children_cleanup(int which, void *arg) | |
1718 | +{ | |
fd1be940 | 1719 | + free(last_faults); |
fd1be940 ER |
1720 | +} |
1721 | + | |
1722 | +static struct fpm_child_s *fpm_child_alloc() | |
1723 | +{ | |
1724 | + struct fpm_child_s *ret; | |
1725 | + | |
fd1be940 ER |
1726 | + ret = malloc(sizeof(struct fpm_child_s)); |
1727 | + | |
1728 | + if (!ret) return 0; | |
1729 | + | |
fd1be940 ER |
1730 | + memset(ret, 0, sizeof(*ret)); |
1731 | + | |
1732 | + return ret; | |
1733 | +} | |
1734 | + | |
c6a6bfc9 | 1735 | +static void fpm_child_free(struct fpm_child_s *child) |
fd1be940 | 1736 | +{ |
c6a6bfc9 ER |
1737 | + free(child); |
1738 | +} | |
fd1be940 | 1739 | + |
c6a6bfc9 ER |
1740 | +static void fpm_child_close(struct fpm_child_s *child, int in_event_loop) |
1741 | +{ | |
fd1be940 ER |
1742 | + if (child->fd_stdout != -1) { |
1743 | + if (in_event_loop) { | |
1744 | + fpm_event_fire(&child->ev_stdout); | |
1745 | + } | |
1746 | + if (child->fd_stdout != -1) { | |
1747 | + close(child->fd_stdout); | |
1748 | + } | |
1749 | + } | |
1750 | + | |
1751 | + if (child->fd_stderr != -1) { | |
1752 | + if (in_event_loop) { | |
1753 | + fpm_event_fire(&child->ev_stderr); | |
1754 | + } | |
1755 | + if (child->fd_stderr != -1) { | |
1756 | + close(child->fd_stderr); | |
1757 | + } | |
1758 | + } | |
1759 | + | |
c6a6bfc9 | 1760 | + fpm_child_free(child); |
fd1be940 ER |
1761 | +} |
1762 | + | |
c6a6bfc9 | 1763 | +static void fpm_child_link(struct fpm_child_s *child) |
fd1be940 | 1764 | +{ |
c6a6bfc9 | 1765 | + struct fpm_worker_pool_s *wp = child->wp; |
fd1be940 | 1766 | + |
c6a6bfc9 | 1767 | + ++wp->running_children; |
fd1be940 ER |
1768 | + ++fpm_globals.running_children; |
1769 | + | |
c6a6bfc9 | 1770 | + child->next = wp->children; |
fd1be940 ER |
1771 | + if (child->next) child->next->prev = child; |
1772 | + child->prev = 0; | |
c6a6bfc9 ER |
1773 | + wp->children = child; |
1774 | +} | |
1775 | + | |
1776 | +static void fpm_child_unlink(struct fpm_child_s *child) | |
1777 | +{ | |
1778 | + --child->wp->running_children; | |
1779 | + --fpm_globals.running_children; | |
1780 | + | |
1781 | + if (child->prev) child->prev->next = child->next; | |
1782 | + else child->wp->children = child->next; | |
1783 | + if (child->next) child->next->prev = child->prev; | |
fd1be940 | 1784 | + |
fd1be940 ER |
1785 | +} |
1786 | + | |
c6a6bfc9 | 1787 | +static struct fpm_child_s *fpm_child_find(pid_t pid) |
fd1be940 | 1788 | +{ |
c6a6bfc9 | 1789 | + struct fpm_worker_pool_s *wp; |
fd1be940 ER |
1790 | + struct fpm_child_s *child = 0; |
1791 | + | |
c6a6bfc9 ER |
1792 | + for (wp = fpm_worker_all_pools; wp; wp = wp->next) { |
1793 | + | |
1794 | + for (child = wp->children; child; child = child->next) { | |
1795 | + if (child->pid == pid) { | |
1796 | + break; | |
1797 | + } | |
fd1be940 | 1798 | + } |
c6a6bfc9 ER |
1799 | + |
1800 | + if (child) break; | |
fd1be940 ER |
1801 | + } |
1802 | + | |
1803 | + if (!child) { | |
1804 | + return 0; | |
1805 | + } | |
1806 | + | |
fd1be940 ER |
1807 | + return child; |
1808 | +} | |
1809 | + | |
1810 | +static void fpm_child_init(struct fpm_worker_pool_s *wp) | |
1811 | +{ | |
1812 | + fpm_globals.max_requests = wp->config->max_requests; | |
c6a6bfc9 ER |
1813 | + |
1814 | + if (0 > fpm_stdio_init_child(wp) || | |
1815 | + 0 > fpm_unix_init_child(wp) || | |
1816 | + 0 > fpm_signals_init_child() || | |
1817 | + 0 > fpm_env_init_child(wp) || | |
1818 | + 0 > fpm_php_init_child(wp)) { | |
1819 | + | |
1820 | + zlog(ZLOG_STUFF, ZLOG_ERROR, "child failed to initialize (pool %s)", wp->config->name); | |
1821 | + exit(255); | |
1822 | + } | |
fd1be940 ER |
1823 | +} |
1824 | + | |
1825 | +int fpm_children_free(struct fpm_child_s *child) | |
1826 | +{ | |
1827 | + struct fpm_child_s *next; | |
1828 | + | |
1829 | + for (; child; child = next) { | |
1830 | + next = child->next; | |
c6a6bfc9 | 1831 | + fpm_child_close(child, 0 /* in_event_loop */); |
fd1be940 ER |
1832 | + } |
1833 | + | |
1834 | + return 0; | |
1835 | +} | |
1836 | + | |
fd1be940 ER |
1837 | +void fpm_children_bury() |
1838 | +{ | |
1839 | + int status; | |
1840 | + pid_t pid; | |
1841 | + struct fpm_child_s *child; | |
1842 | + | |
c6a6bfc9 | 1843 | + while ( (pid = waitpid(-1, &status, WNOHANG | WUNTRACED)) > 0) { |
fd1be940 ER |
1844 | + char buf[128]; |
1845 | + int severity = ZLOG_NOTICE; | |
1846 | + | |
c6a6bfc9 ER |
1847 | + child = fpm_child_find(pid); |
1848 | + | |
fd1be940 ER |
1849 | + if (WIFEXITED(status)) { |
1850 | + | |
1851 | + snprintf(buf, sizeof(buf), "with code %d", WEXITSTATUS(status)); | |
1852 | + | |
1853 | + if (WEXITSTATUS(status) != 0) { | |
1854 | + severity = ZLOG_WARNING; | |
1855 | + } | |
1856 | + | |
1857 | + } | |
c6a6bfc9 ER |
1858 | + else if (WIFSIGNALED(status)) { |
1859 | + const char *signame = fpm_signal_names[WTERMSIG(status)]; | |
1860 | + const char *have_core = WCOREDUMP(status) ? " (core dumped)" : ""; | |
fd1be940 | 1861 | + |
c6a6bfc9 ER |
1862 | + if (signame == NULL) { |
1863 | + signame = ""; | |
1864 | + } | |
1865 | + | |
1866 | + snprintf(buf, sizeof(buf), "on signal %d %s%s", WTERMSIG(status), signame, have_core); | |
fd1be940 ER |
1867 | + |
1868 | + if (WTERMSIG(status) != SIGQUIT) { /* possible request loss */ | |
1869 | + severity = ZLOG_WARNING; | |
1870 | + } | |
1871 | + } | |
c6a6bfc9 ER |
1872 | + else if (WIFSTOPPED(status)) { |
1873 | + | |
1874 | + zlog(ZLOG_STUFF, ZLOG_NOTICE, "child %d stopped for tracing", (int) pid); | |
1875 | + | |
1876 | + if (child && child->tracer) { | |
1877 | + child->tracer(child); | |
1878 | + } | |
fd1be940 | 1879 | + |
c6a6bfc9 ER |
1880 | + continue; |
1881 | + } | |
fd1be940 ER |
1882 | + |
1883 | + if (child) { | |
1884 | + struct fpm_worker_pool_s *wp = child->wp; | |
1885 | + struct timeval tv1, tv2; | |
1886 | + | |
c6a6bfc9 ER |
1887 | + fpm_child_unlink(child); |
1888 | + | |
1889 | + fpm_shm_slots_discard_slot(child); | |
1890 | + | |
1891 | + fpm_clock_get(&tv1); | |
fd1be940 ER |
1892 | + |
1893 | + timersub(&tv1, &child->started, &tv2); | |
1894 | + | |
c6a6bfc9 | 1895 | + zlog(ZLOG_STUFF, severity, "child %d (pool %s) exited %s after %ld.%06d seconds from start", (int) pid, |
fd1be940 ER |
1896 | + child->wp->config->name, buf, tv2.tv_sec, (int) tv2.tv_usec); |
1897 | + | |
c6a6bfc9 | 1898 | + fpm_child_close(child, 1 /* in event_loop */); |
fd1be940 ER |
1899 | + |
1900 | + fpm_pctl_child_exited(); | |
1901 | + | |
1902 | + if (last_faults && (WTERMSIG(status) == SIGSEGV || WTERMSIG(status) == SIGBUS)) { | |
1903 | + time_t now = tv1.tv_sec; | |
1904 | + int restart_condition = 1; | |
1905 | + int i; | |
1906 | + | |
1907 | + last_faults[fault++] = now; | |
1908 | + | |
1909 | + if (fault == fpm_global_options.emergency_restart_threshold) { | |
1910 | + fault = 0; | |
1911 | + } | |
1912 | + | |
1913 | + for (i = 0; i < fpm_global_options.emergency_restart_threshold; i++) { | |
1914 | + if (now - last_faults[i] > fpm_global_options.emergency_restart_interval) { | |
1915 | + restart_condition = 0; | |
1916 | + break; | |
1917 | + } | |
1918 | + } | |
1919 | + | |
1920 | + if (restart_condition) { | |
1921 | + | |
1922 | + zlog(ZLOG_STUFF, ZLOG_WARNING, "failed processes threshold (%d in %d sec) is reached, initiating reload", | |
1923 | + fpm_global_options.emergency_restart_threshold, fpm_global_options.emergency_restart_interval); | |
1924 | + | |
1925 | + fpm_pctl(FPM_PCTL_STATE_RELOADING, FPM_PCTL_ACTION_SET); | |
1926 | + } | |
1927 | + } | |
1928 | + | |
1929 | + fpm_children_make(wp, 1 /* in event loop */); | |
c6a6bfc9 ER |
1930 | + |
1931 | + if (fpm_globals.is_child) { | |
1932 | + break; | |
1933 | + } | |
fd1be940 ER |
1934 | + } |
1935 | + else { | |
1936 | + zlog(ZLOG_STUFF, ZLOG_ALERT, "oops, unknown child exited %s", buf); | |
1937 | + } | |
1938 | + } | |
1939 | + | |
1940 | +} | |
1941 | + | |
c6a6bfc9 ER |
1942 | +static struct fpm_child_s *fpm_resources_prepare(struct fpm_worker_pool_s *wp) |
1943 | +{ | |
1944 | + struct fpm_child_s *c; | |
1945 | + | |
1946 | + c = fpm_child_alloc(); | |
1947 | + | |
1948 | + if (!c) { | |
1949 | + zlog(ZLOG_STUFF, ZLOG_ERROR, "malloc failed (pool %s)", wp->config->name); | |
1950 | + return 0; | |
1951 | + } | |
1952 | + | |
1953 | + c->wp = wp; | |
1954 | + c->fd_stdout = -1; c->fd_stderr = -1; | |
1955 | + | |
1956 | + if (0 > fpm_stdio_prepare_pipes(c)) { | |
1957 | + fpm_child_free(c); | |
1958 | + return 0; | |
1959 | + } | |
1960 | + | |
1961 | + if (0 > fpm_shm_slots_prepare_slot(c)) { | |
1962 | + fpm_stdio_discard_pipes(c); | |
1963 | + fpm_child_free(c); | |
1964 | + return 0; | |
1965 | + } | |
1966 | + | |
1967 | + return c; | |
1968 | +} | |
1969 | + | |
1970 | +static void fpm_resources_discard(struct fpm_child_s *child) | |
1971 | +{ | |
1972 | + fpm_shm_slots_discard_slot(child); | |
1973 | + fpm_stdio_discard_pipes(child); | |
1974 | + fpm_child_free(child); | |
1975 | +} | |
1976 | + | |
1977 | +static void fpm_child_resources_use(struct fpm_child_s *child) | |
1978 | +{ | |
1979 | + fpm_shm_slots_child_use_slot(child); | |
1980 | + fpm_stdio_child_use_pipes(child); | |
1981 | + fpm_child_free(child); | |
1982 | +} | |
1983 | + | |
1984 | +static void fpm_parent_resources_use(struct fpm_child_s *child) | |
1985 | +{ | |
1986 | + fpm_shm_slots_parent_use_slot(child); | |
1987 | + fpm_stdio_parent_use_pipes(child); | |
1988 | + fpm_child_link(child); | |
1989 | +} | |
1990 | + | |
fd1be940 ER |
1991 | +static int fpm_children_make(struct fpm_worker_pool_s *wp, int in_event_loop) |
1992 | +{ | |
1993 | + int enough = 0; | |
c6a6bfc9 ER |
1994 | + pid_t pid; |
1995 | + struct fpm_child_s *child; | |
fd1be940 ER |
1996 | + |
1997 | + while (!enough && fpm_pctl_can_spawn_children() && wp->running_children < wp->config->pm->max_children) { | |
fd1be940 | 1998 | + |
c6a6bfc9 ER |
1999 | + child = fpm_resources_prepare(wp); |
2000 | + | |
2001 | + if (!child) { | |
fd1be940 ER |
2002 | + enough = 1; |
2003 | + break; | |
2004 | + } | |
2005 | + | |
2006 | + pid = fork(); | |
2007 | + | |
2008 | + switch (pid) { | |
2009 | + | |
2010 | + case 0 : | |
c6a6bfc9 | 2011 | + fpm_child_resources_use(child); |
fd1be940 ER |
2012 | + fpm_globals.is_child = 1; |
2013 | + if (in_event_loop) { | |
2014 | + fpm_event_exit_loop(); | |
2015 | + } | |
2016 | + fpm_child_init(wp); | |
2017 | + return 0; | |
2018 | + | |
2019 | + case -1 : | |
2020 | + zlog(ZLOG_STUFF, ZLOG_SYSERROR, "fork() failed"); | |
2021 | + enough = 1; | |
c6a6bfc9 ER |
2022 | + |
2023 | + fpm_resources_discard(child); | |
2024 | + | |
fd1be940 ER |
2025 | + break; /* dont try any more on error */ |
2026 | + | |
2027 | + default : | |
c6a6bfc9 ER |
2028 | + child->pid = pid; |
2029 | + fpm_clock_get(&child->started); | |
2030 | + fpm_parent_resources_use(child); | |
fd1be940 | 2031 | + |
c6a6bfc9 | 2032 | + zlog(ZLOG_STUFF, ZLOG_NOTICE, "child %d (pool %s) started", (int) pid, wp->config->name); |
fd1be940 ER |
2033 | + } |
2034 | + | |
2035 | + } | |
2036 | + | |
2037 | + return 1; /* we are done */ | |
2038 | +} | |
2039 | + | |
2040 | +int fpm_children_create_initial(struct fpm_worker_pool_s *wp) | |
2041 | +{ | |
2042 | + return fpm_children_make(wp, 0 /* not in event loop yet */); | |
2043 | +} | |
2044 | + | |
2045 | +int fpm_children_init_main() | |
2046 | +{ | |
2047 | + if (fpm_global_options.emergency_restart_threshold && | |
2048 | + fpm_global_options.emergency_restart_interval) { | |
2049 | + | |
2050 | + last_faults = malloc(sizeof(time_t) * fpm_global_options.emergency_restart_threshold); | |
2051 | + | |
2052 | + if (!last_faults) { | |
2053 | + return -1; | |
2054 | + } | |
2055 | + | |
2056 | + memset(last_faults, 0, sizeof(time_t) * fpm_global_options.emergency_restart_threshold); | |
2057 | + } | |
2058 | + | |
2059 | + fpm_cleanup_add(FPM_CLEANUP_ALL, fpm_children_cleanup, 0); | |
2060 | + | |
2061 | + return 0; | |
2062 | +} | |
c6a6bfc9 | 2063 | + |
8c0dac15 ER |
2064 | diff -Nru php-5.2.6.vanilla/sapi/cgi/fpm/fpm_children.h php-5.2.6.fpm/sapi/cgi/fpm/fpm_children.h |
2065 | --- php-5.2.6.vanilla/sapi/cgi/fpm/fpm_children.h 1970-01-01 03:00:00.000000000 +0300 | |
2066 | +++ php-5.2.6.fpm/sapi/cgi/fpm/fpm_children.h 2008-05-24 21:38:47.000000000 +0400 | |
c6a6bfc9 | 2067 | @@ -0,0 +1,33 @@ |
fd1be940 ER |
2068 | + |
2069 | + /* $Id$ */ | |
c6a6bfc9 | 2070 | + /* (c) 2007,2008 Andrei Nigmatulin */ |
fd1be940 ER |
2071 | + |
2072 | +#ifndef FPM_CHILDREN_H | |
2073 | +#define FPM_CHILDREN_H 1 | |
2074 | + | |
2075 | +#include <sys/time.h> | |
2076 | +#include <sys/types.h> | |
2077 | +#include <event.h> | |
2078 | + | |
2079 | +#include "fpm_worker_pool.h" | |
2080 | + | |
2081 | +int fpm_children_create_initial(struct fpm_worker_pool_s *wp); | |
2082 | +int fpm_children_free(struct fpm_child_s *child); | |
2083 | +void fpm_children_bury(); | |
2084 | +int fpm_children_init_main(); | |
2085 | + | |
2086 | +struct fpm_child_s; | |
2087 | + | |
2088 | +struct fpm_child_s { | |
2089 | + struct fpm_child_s *prev, *next; | |
2090 | + struct timeval started; | |
2091 | + struct fpm_worker_pool_s *wp; | |
2092 | + struct event ev_stdout, ev_stderr; | |
c6a6bfc9 | 2093 | + int shm_slot_i; |
fd1be940 | 2094 | + int fd_stdout, fd_stderr; |
c6a6bfc9 ER |
2095 | + void (*tracer)(struct fpm_child_s *); |
2096 | + struct timeval slow_logged; | |
fd1be940 ER |
2097 | + pid_t pid; |
2098 | +}; | |
2099 | + | |
2100 | +#endif | |
8c0dac15 ER |
2101 | diff -Nru php-5.2.6.vanilla/sapi/cgi/fpm/fpm_cleanup.c php-5.2.6.fpm/sapi/cgi/fpm/fpm_cleanup.c |
2102 | --- php-5.2.6.vanilla/sapi/cgi/fpm/fpm_cleanup.c 1970-01-01 03:00:00.000000000 +0300 | |
2103 | +++ php-5.2.6.fpm/sapi/cgi/fpm/fpm_cleanup.c 2008-05-24 21:38:47.000000000 +0400 | |
c6a6bfc9 | 2104 | @@ -0,0 +1,51 @@ |
fd1be940 ER |
2105 | + |
2106 | + /* $Id$ */ | |
c6a6bfc9 | 2107 | + /* (c) 2007,2008 Andrei Nigmatulin */ |
fd1be940 ER |
2108 | + |
2109 | +#include "fpm_config.h" | |
2110 | + | |
2111 | +#include <stdlib.h> | |
2112 | + | |
c6a6bfc9 | 2113 | +#include "fpm_arrays.h" |
fd1be940 ER |
2114 | +#include "fpm_cleanup.h" |
2115 | +#include "zlog.h" | |
2116 | + | |
2117 | +struct cleanup_s { | |
2118 | + int type; | |
2119 | + void (*cleanup)(int, void *); | |
2120 | + void *arg; | |
2121 | +}; | |
2122 | + | |
c6a6bfc9 | 2123 | +static struct fpm_array_s cleanups = { .sz = sizeof(struct cleanup_s) }; |
fd1be940 ER |
2124 | + |
2125 | +int fpm_cleanup_add(int type, void (*cleanup)(int, void *), void *arg) | |
2126 | +{ | |
c6a6bfc9 | 2127 | + struct cleanup_s *c; |
fd1be940 | 2128 | + |
c6a6bfc9 | 2129 | + c = fpm_array_push(&cleanups); |
fd1be940 | 2130 | + |
c6a6bfc9 ER |
2131 | + if (!c) { |
2132 | + return -1; | |
fd1be940 ER |
2133 | + } |
2134 | + | |
c6a6bfc9 ER |
2135 | + c->type = type; |
2136 | + c->cleanup = cleanup; | |
2137 | + c->arg = arg; | |
fd1be940 ER |
2138 | + |
2139 | + return 0; | |
2140 | +} | |
2141 | + | |
2142 | +void fpm_cleanups_run(int type) | |
2143 | +{ | |
c6a6bfc9 ER |
2144 | + struct cleanup_s *c = fpm_array_item_last(&cleanups); |
2145 | + int cl = cleanups.used; | |
fd1be940 | 2146 | + |
c6a6bfc9 | 2147 | + for ( ; cl--; c--) { |
fd1be940 ER |
2148 | + if (c->type & type) { |
2149 | + c->cleanup(type, c->arg); | |
2150 | + } | |
2151 | + } | |
2152 | + | |
c6a6bfc9 | 2153 | + fpm_array_free(&cleanups); |
fd1be940 | 2154 | +} |
c6a6bfc9 | 2155 | + |
8c0dac15 ER |
2156 | diff -Nru php-5.2.6.vanilla/sapi/cgi/fpm/fpm_cleanup.h php-5.2.6.fpm/sapi/cgi/fpm/fpm_cleanup.h |
2157 | --- php-5.2.6.vanilla/sapi/cgi/fpm/fpm_cleanup.h 1970-01-01 03:00:00.000000000 +0300 | |
2158 | +++ php-5.2.6.fpm/sapi/cgi/fpm/fpm_cleanup.h 2008-05-24 21:38:47.000000000 +0400 | |
fd1be940 ER |
2159 | @@ -0,0 +1,21 @@ |
2160 | + | |
2161 | + /* $Id$ */ | |
c6a6bfc9 | 2162 | + /* (c) 2007,2008 Andrei Nigmatulin */ |
fd1be940 ER |
2163 | + |
2164 | +#ifndef FPM_CLEANUP_H | |
2165 | +#define FPM_CLEANUP_H 1 | |
2166 | + | |
2167 | +int fpm_cleanup_add(int type, void (*cleanup)(int, void *), void *); | |
2168 | +void fpm_cleanups_run(int type); | |
2169 | + | |
2170 | +enum { | |
2171 | + FPM_CLEANUP_CHILD = (1 << 0), | |
2172 | + FPM_CLEANUP_PARENT_EXIT = (1 << 1), | |
2173 | + FPM_CLEANUP_PARENT_EXIT_MAIN = (1 << 2), | |
2174 | + FPM_CLEANUP_PARENT_EXEC = (1 << 3), | |
2175 | + FPM_CLEANUP_PARENT = (1 << 1) | (1 << 2) | (1 << 3), | |
2176 | + FPM_CLEANUP_ALL = ~0, | |
2177 | +}; | |
2178 | + | |
2179 | +#endif | |
2180 | + | |
8c0dac15 ER |
2181 | diff -Nru php-5.2.6.vanilla/sapi/cgi/fpm/fpm_clock.c php-5.2.6.fpm/sapi/cgi/fpm/fpm_clock.c |
2182 | --- php-5.2.6.vanilla/sapi/cgi/fpm/fpm_clock.c 1970-01-01 03:00:00.000000000 +0300 | |
2183 | +++ php-5.2.6.fpm/sapi/cgi/fpm/fpm_clock.c 2008-09-19 03:19:59.000000000 +0400 | |
c6a6bfc9 ER |
2184 | @@ -0,0 +1,115 @@ |
2185 | + | |
2186 | + /* $Id$ */ | |
2187 | + /* (c) 2007,2008 Andrei Nigmatulin */ | |
2188 | + | |
2189 | +#include "fpm_config.h" | |
2190 | + | |
2191 | +#if defined(HAVE_CLOCK_GETTIME) | |
2192 | +#include <time.h> /* for CLOCK_MONOTONIC */ | |
2193 | +#endif | |
2194 | + | |
2195 | +#include "fpm_clock.h" | |
2196 | +#include "zlog.h" | |
2197 | + | |
2198 | + | |
2199 | +/* posix monotonic clock - preferred source of time */ | |
2200 | +#if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC) | |
2201 | + | |
2202 | +static int monotonic_works; | |
2203 | + | |
2204 | +int fpm_clock_init() | |
2205 | +{ | |
2206 | + struct timespec ts; | |
2207 | + | |
2208 | + monotonic_works = 0; | |
2209 | + | |
2210 | + if (0 == clock_gettime(CLOCK_MONOTONIC, &ts)) { | |
2211 | + monotonic_works = 1; | |
2212 | + } | |
2213 | + | |
2214 | + return 0; | |
2215 | +} | |
2216 | + | |
2217 | +int fpm_clock_get(struct timeval *tv) | |
2218 | +{ | |
2219 | + if (monotonic_works) { | |
2220 | + struct timespec ts; | |
2221 | + | |
2222 | + if (0 > clock_gettime(CLOCK_MONOTONIC, &ts)) { | |
2223 | + zlog(ZLOG_STUFF, ZLOG_SYSERROR, "clock_gettime() failed"); | |
2224 | + return -1; | |
2225 | + } | |
2226 | + | |
2227 | + tv->tv_sec = ts.tv_sec; | |
2228 | + tv->tv_usec = ts.tv_nsec / 1000; | |
2229 | + return 0; | |
2230 | + } | |
2231 | + | |
2232 | + return gettimeofday(tv, 0); | |
2233 | +} | |
2234 | + | |
2235 | +/* macosx clock */ | |
2236 | +#elif defined(HAVE_CLOCK_GET_TIME) | |
2237 | + | |
2238 | +#include <mach/mach.h> | |
2239 | +#include <mach/clock.h> | |
2240 | +#include <mach/mach_error.h> | |
2241 | + | |
2242 | +static clock_serv_t mach_clock; | |
2243 | + | |
2244 | +/* this code borrowed from here: http://lists.apple.com/archives/Darwin-development/2002/Mar/msg00746.html */ | |
2245 | +/* mach_clock also should be re-initialized in child process after fork */ | |
2246 | +int fpm_clock_init() | |
2247 | +{ | |
2248 | + kern_return_t ret; | |
2249 | + mach_timespec_t aTime; | |
2250 | + | |
2251 | + ret = host_get_clock_service(mach_host_self(), REALTIME_CLOCK, &mach_clock); | |
2252 | + | |
2253 | + if (ret != KERN_SUCCESS) { | |
2254 | + zlog(ZLOG_STUFF, ZLOG_ERROR, "host_get_clock_service() failed: %s", mach_error_string(ret)); | |
2255 | + return -1; | |
2256 | + } | |
2257 | + | |
2258 | + /* test if it works */ | |
2259 | + ret = clock_get_time(mach_clock, &aTime); | |
2260 | + | |
2261 | + if (ret != KERN_SUCCESS) { | |
2262 | + zlog(ZLOG_STUFF, ZLOG_ERROR, "clock_get_time() failed: %s", mach_error_string(ret)); | |
2263 | + return -1; | |
2264 | + } | |
2265 | + | |
2266 | + return 0; | |
2267 | +} | |
2268 | + | |
2269 | +int fpm_clock_get(struct timeval *tv) | |
2270 | +{ | |
2271 | + kern_return_t ret; | |
2272 | + mach_timespec_t aTime; | |
2273 | + | |
2274 | + ret = clock_get_time(mach_clock, &aTime); | |
2275 | + | |
2276 | + if (ret != KERN_SUCCESS) { | |
2277 | + zlog(ZLOG_STUFF, ZLOG_ERROR, "clock_get_time() failed: %s", mach_error_string(ret)); | |
2278 | + return -1; | |
2279 | + } | |
2280 | + | |
2281 | + tv->tv_sec = aTime.tv_sec; | |
2282 | + tv->tv_usec = aTime.tv_nsec / 1000; | |
2283 | + | |
2284 | + return 0; | |
2285 | +} | |
2286 | + | |
2287 | +#else /* no clock */ | |
2288 | + | |
2289 | +int fpm_clock_init() | |
2290 | +{ | |
2291 | + return 0; | |
2292 | +} | |
2293 | + | |
2294 | +int fpm_clock_get(struct timeval *tv) | |
2295 | +{ | |
2296 | + return gettimeofday(tv, 0); | |
2297 | +} | |
2298 | + | |
2299 | +#endif | |
8c0dac15 ER |
2300 | diff -Nru php-5.2.6.vanilla/sapi/cgi/fpm/fpm_clock.h php-5.2.6.fpm/sapi/cgi/fpm/fpm_clock.h |
2301 | --- php-5.2.6.vanilla/sapi/cgi/fpm/fpm_clock.h 1970-01-01 03:00:00.000000000 +0300 | |
2302 | +++ php-5.2.6.fpm/sapi/cgi/fpm/fpm_clock.h 2008-05-24 21:38:47.000000000 +0400 | |
c6a6bfc9 ER |
2303 | @@ -0,0 +1,13 @@ |
2304 | + | |
2305 | + /* $Id$ */ | |
2306 | + /* (c) 2007,2008 Andrei Nigmatulin */ | |
2307 | + | |
2308 | +#ifndef FPM_CLOCK_H | |
2309 | +#define FPM_CLOCK_H 1 | |
2310 | + | |
2311 | +#include <sys/time.h> | |
2312 | + | |
2313 | +int fpm_clock_init(); | |
2314 | +int fpm_clock_get(struct timeval *tv); | |
2315 | + | |
2316 | +#endif | |
8c0dac15 ER |
2317 | diff -Nru php-5.2.6.vanilla/sapi/cgi/fpm/fpm_conf.c php-5.2.6.fpm/sapi/cgi/fpm/fpm_conf.c |
2318 | --- php-5.2.6.vanilla/sapi/cgi/fpm/fpm_conf.c 1970-01-01 03:00:00.000000000 +0300 | |
2319 | +++ php-5.2.6.fpm/sapi/cgi/fpm/fpm_conf.c 2008-09-19 04:54:15.000000000 +0400 | |
c6a6bfc9 | 2320 | @@ -0,0 +1,530 @@ |
fd1be940 ER |
2321 | + |
2322 | + /* $Id$ */ | |
c6a6bfc9 | 2323 | + /* (c) 2007,2008 Andrei Nigmatulin */ |
fd1be940 ER |
2324 | + |
2325 | +#include "fpm_config.h" | |
2326 | + | |
2327 | +#include <sys/types.h> | |
2328 | +#include <sys/stat.h> | |
2329 | +#include <fcntl.h> | |
2330 | +#include <string.h> | |
2331 | +#include <stdlib.h> | |
2332 | +#include <stddef.h> | |
2333 | +#include <stdint.h> | |
2334 | +#include <stdio.h> | |
2335 | +#include <unistd.h> | |
2336 | + | |
2337 | +#include "fpm.h" | |
2338 | +#include "fpm_conf.h" | |
c6a6bfc9 | 2339 | +#include "fpm_stdio.h" |
fd1be940 ER |
2340 | +#include "fpm_worker_pool.h" |
2341 | +#include "fpm_cleanup.h" | |
2342 | +#include "fpm_php.h" | |
2343 | +#include "fpm_sockets.h" | |
2344 | +#include "xml_config.h" | |
2345 | +#include "zlog.h" | |
2346 | + | |
2347 | + | |
2348 | +struct fpm_options_s fpm_global_options; | |
2349 | + | |
2350 | +static void *fpm_global_options_ptr() | |
2351 | +{ | |
2352 | + return &fpm_global_options; | |
2353 | +} | |
2354 | + | |
c6a6bfc9 ER |
2355 | +static char *fpm_conf_set_log_level(void **conf, char *name, void *vv, intptr_t offset) |
2356 | +{ | |
2357 | + char *value = vv; | |
2358 | + | |
2359 | + if (!strcmp(value, "debug")) { | |
2360 | + fpm_globals.log_level = ZLOG_DEBUG; | |
2361 | + } | |
2362 | + else if (!strcmp(value, "notice")) { | |
2363 | + fpm_globals.log_level = ZLOG_NOTICE; | |
2364 | + } | |
2365 | + else if (!strcmp(value, "warn")) { | |
2366 | + fpm_globals.log_level = ZLOG_WARNING; | |
2367 | + } | |
2368 | + else if (!strcmp(value, "error")) { | |
2369 | + fpm_globals.log_level = ZLOG_ERROR; | |
2370 | + } | |
2371 | + else if (!strcmp(value, "alert")) { | |
2372 | + fpm_globals.log_level = ZLOG_ALERT; | |
2373 | + } | |
2374 | + else { | |
2375 | + return "invalid value for 'log_level'"; | |
2376 | + } | |
2377 | + | |
2378 | + return NULL; | |
2379 | +} | |
2380 | + | |
fd1be940 ER |
2381 | +static struct xml_conf_section xml_section_fpm_global_options = { |
2382 | + .conf = &fpm_global_options_ptr, | |
2383 | + .path = "/configuration/global_options", | |
c6a6bfc9 | 2384 | + .parsers = (struct xml_value_parser []) { |
fd1be940 ER |
2385 | + { XML_CONF_SCALAR, "emergency_restart_threshold", &xml_conf_set_slot_integer, offsetof(struct fpm_options_s, emergency_restart_threshold) }, |
2386 | + { XML_CONF_SCALAR, "emergency_restart_interval", &xml_conf_set_slot_time, offsetof(struct fpm_options_s, emergency_restart_interval) }, | |
2387 | + { XML_CONF_SCALAR, "process_control_timeout", &xml_conf_set_slot_time, offsetof(struct fpm_options_s, process_control_timeout) }, | |
2388 | + { XML_CONF_SCALAR, "daemonize", &xml_conf_set_slot_boolean, offsetof(struct fpm_options_s, daemonize) }, | |
2389 | + { XML_CONF_SCALAR, "pid_file", &xml_conf_set_slot_string, offsetof(struct fpm_options_s, pid_file) }, | |
2390 | + { XML_CONF_SCALAR, "error_log", &xml_conf_set_slot_string, offsetof(struct fpm_options_s, error_log) }, | |
c6a6bfc9 | 2391 | + { XML_CONF_SCALAR, "log_level", &fpm_conf_set_log_level, 0 }, |
fd1be940 ER |
2392 | + { 0, 0, 0, 0 } |
2393 | + } | |
2394 | +}; | |
2395 | + | |
2396 | +static char *fpm_conf_set_pm_style(void **conf, char *name, void *vv, intptr_t offset) | |
2397 | +{ | |
2398 | + char *value = vv; | |
2399 | + struct fpm_pm_s *c = *conf; | |
2400 | + | |
2401 | + if (!strcmp(value, "static")) { | |
2402 | + c->style = PM_STYLE_STATIC; | |
2403 | + } | |
2404 | + else if (!strcmp(value, "apache-like")) { | |
2405 | + c->style = PM_STYLE_APACHE_LIKE; | |
2406 | + } | |
2407 | + else { | |
2408 | + return "invalid value for 'style'"; | |
2409 | + } | |
2410 | + | |
2411 | + return NULL; | |
2412 | +} | |
2413 | + | |
2414 | +static char *fpm_conf_set_rlimit_core(void **conf, char *name, void *vv, intptr_t offset) | |
2415 | +{ | |
2416 | + char *value = vv; | |
2417 | + struct fpm_worker_pool_config_s *c = *conf; | |
2418 | + | |
2419 | + if (!strcmp(value, "unlimited")) { | |
2420 | + c->rlimit_core = -1; | |
2421 | + } | |
2422 | + else { | |
2423 | + int int_value; | |
2424 | + void *subconf = &int_value; | |
2425 | + char *error; | |
2426 | + | |
2427 | + error = xml_conf_set_slot_integer(&subconf, name, vv, 0); | |
2428 | + | |
2429 | + if (error) return error; | |
2430 | + | |
2431 | + if (int_value < 0) return "invalid value for 'rlimit_core'"; | |
2432 | + | |
2433 | + c->rlimit_core = int_value; | |
2434 | + } | |
2435 | + | |
2436 | + return NULL; | |
2437 | +} | |
2438 | + | |
2439 | +static char *fpm_conf_set_catch_workers_output(void **conf, char *name, void *vv, intptr_t offset) | |
2440 | +{ | |
2441 | + struct fpm_worker_pool_config_s *c = *conf; | |
2442 | + int int_value; | |
2443 | + void *subconf = &int_value; | |
2444 | + char *error; | |
2445 | + | |
2446 | + error = xml_conf_set_slot_boolean(&subconf, name, vv, 0); | |
2447 | + | |
2448 | + if (error) return error; | |
2449 | + | |
2450 | + c->catch_workers_output = int_value; | |
2451 | + | |
2452 | + return NULL; | |
2453 | +} | |
2454 | + | |
c6a6bfc9 ER |
2455 | +static struct xml_conf_section fpm_conf_set_apache_like_subsection_conf = { |
2456 | + .path = "apache_like somewhere", /* fixme */ | |
2457 | + .parsers = (struct xml_value_parser []) { | |
2458 | + { XML_CONF_SCALAR, "StartServers", &xml_conf_set_slot_integer, offsetof(struct fpm_pm_s, options_apache_like.StartServers) }, | |
2459 | + { XML_CONF_SCALAR, "MinSpareServers", &xml_conf_set_slot_integer, offsetof(struct fpm_pm_s, options_apache_like.MinSpareServers) }, | |
2460 | + { XML_CONF_SCALAR, "MaxSpareServers", &xml_conf_set_slot_integer, offsetof(struct fpm_pm_s, options_apache_like.MaxSpareServers) }, | |
2461 | + { 0, 0, 0, 0 } | |
2462 | + } | |
2463 | +}; | |
2464 | + | |
fd1be940 ER |
2465 | +static char *fpm_conf_set_apache_like_subsection(void **conf, char *name, void *xml_node, intptr_t offset) |
2466 | +{ | |
fd1be940 ER |
2467 | + return xml_conf_parse_section(conf, &fpm_conf_set_apache_like_subsection_conf, xml_node); |
2468 | +} | |
2469 | + | |
c6a6bfc9 ER |
2470 | +static struct xml_conf_section fpm_conf_set_listen_options_subsection_conf = { |
2471 | + .path = "listen options somewhere", /* fixme */ | |
2472 | + .parsers = (struct xml_value_parser []) { | |
2473 | + { XML_CONF_SCALAR, "backlog", &xml_conf_set_slot_integer, offsetof(struct fpm_listen_options_s, backlog) }, | |
2474 | + { XML_CONF_SCALAR, "owner", &xml_conf_set_slot_string, offsetof(struct fpm_listen_options_s, owner) }, | |
2475 | + { XML_CONF_SCALAR, "group", &xml_conf_set_slot_string, offsetof(struct fpm_listen_options_s, group) }, | |
2476 | + { XML_CONF_SCALAR, "mode", &xml_conf_set_slot_string, offsetof(struct fpm_listen_options_s, mode) }, | |
2477 | + { 0, 0, 0, 0 } | |
2478 | + } | |
2479 | +}; | |
2480 | + | |
fd1be940 ER |
2481 | +static char *fpm_conf_set_listen_options_subsection(void **conf, char *name, void *xml_node, intptr_t offset) |
2482 | +{ | |
2483 | + void *subconf = (char *) *conf + offset; | |
2484 | + struct fpm_listen_options_s *lo; | |
2485 | + | |
fd1be940 ER |
2486 | + lo = malloc(sizeof(*lo)); |
2487 | + | |
2488 | + if (!lo) { | |
c6a6bfc9 | 2489 | + return "malloc() failed"; |
fd1be940 ER |
2490 | + } |
2491 | + | |
2492 | + memset(lo, 0, sizeof(*lo)); | |
2493 | + | |
2494 | + lo->backlog = -1; | |
2495 | + | |
2496 | + * (struct fpm_listen_options_s **) subconf = lo; | |
2497 | + | |
2498 | + subconf = lo; | |
2499 | + | |
2500 | + return xml_conf_parse_section(&subconf, &fpm_conf_set_listen_options_subsection_conf, xml_node); | |
2501 | +} | |
2502 | + | |
c6a6bfc9 ER |
2503 | +static struct xml_conf_section fpm_conf_set_pm_subsection_conf = { |
2504 | + .path = "pm settings somewhere", /* fixme */ | |
2505 | + .parsers = (struct xml_value_parser []) { | |
2506 | + { XML_CONF_SCALAR, "style", &fpm_conf_set_pm_style, 0 }, | |
2507 | + { XML_CONF_SCALAR, "max_children", &xml_conf_set_slot_integer, offsetof(struct fpm_pm_s, max_children) }, | |
2508 | + { XML_CONF_SUBSECTION, "apache_like", &fpm_conf_set_apache_like_subsection, offsetof(struct fpm_pm_s, options_apache_like) }, | |
2509 | + { 0, 0, 0, 0 } | |
2510 | + } | |
2511 | +}; | |
2512 | + | |
fd1be940 ER |
2513 | +static char *fpm_conf_set_pm_subsection(void **conf, char *name, void *xml_node, intptr_t offset) |
2514 | +{ | |
2515 | + void *subconf = (char *) *conf + offset; | |
2516 | + struct fpm_pm_s *pm; | |
2517 | + | |
fd1be940 ER |
2518 | + pm = malloc(sizeof(*pm)); |
2519 | + | |
2520 | + if (!pm) { | |
2521 | + return "fpm_conf_set_pm_subsection(): malloc failed"; | |
2522 | + } | |
2523 | + | |
2524 | + memset(pm, 0, sizeof(*pm)); | |
2525 | + | |
2526 | + * (struct fpm_pm_s **) subconf = pm; | |
2527 | + | |
2528 | + subconf = pm; | |
2529 | + | |
2530 | + return xml_conf_parse_section(&subconf, &fpm_conf_set_pm_subsection_conf, xml_node); | |
2531 | +} | |
2532 | + | |
2533 | +static char *xml_conf_set_slot_key_value_pair(void **conf, char *name, void *vv, intptr_t offset) | |
2534 | +{ | |
2535 | + char *value = vv; | |
2536 | + struct key_value_s *kv; | |
2537 | + struct key_value_s ***parent = (struct key_value_s ***) conf; | |
2538 | + | |
2539 | + kv = malloc(sizeof(*kv)); | |
2540 | + | |
2541 | + if (!kv) { | |
c6a6bfc9 | 2542 | + return "malloc() failed"; |
fd1be940 ER |
2543 | + } |
2544 | + | |
2545 | + memset(kv, 0, sizeof(*kv)); | |
2546 | + | |
2547 | + kv->key = strdup(name); | |
2548 | + kv->value = strdup(value); | |
2549 | + | |
2550 | + if (!kv->key || !kv->value) { | |
2551 | + return "xml_conf_set_slot_key_value_pair(): strdup() failed"; | |
2552 | + } | |
2553 | + | |
2554 | + **parent = kv; | |
2555 | + | |
2556 | + *parent = &kv->next; | |
2557 | + | |
2558 | + return NULL; | |
2559 | +} | |
2560 | + | |
c6a6bfc9 ER |
2561 | +static struct xml_conf_section fpm_conf_set_key_value_pairs_subsection_conf = { |
2562 | + .path = "key_value_pairs somewhere", /* fixme */ | |
2563 | + .parsers = (struct xml_value_parser []) { | |
2564 | + { XML_CONF_SCALAR, 0, &xml_conf_set_slot_key_value_pair, 0 }, | |
2565 | + { 0, 0, 0, 0 } | |
2566 | + } | |
2567 | +}; | |
2568 | + | |
fd1be940 ER |
2569 | +static char *fpm_conf_set_key_value_pairs_subsection(void **conf, char *name, void *xml_node, intptr_t offset) |
2570 | +{ | |
2571 | + void *next_kv = (char *) *conf + offset; | |
2572 | + | |
fd1be940 ER |
2573 | + return xml_conf_parse_section(&next_kv, &fpm_conf_set_key_value_pairs_subsection_conf, xml_node); |
2574 | +} | |
2575 | + | |
2576 | +static void *fpm_worker_pool_config_alloc() | |
2577 | +{ | |
2578 | + static struct fpm_worker_pool_s *current_wp = 0; | |
2579 | + struct fpm_worker_pool_s *wp; | |
2580 | + | |
2581 | + wp = fpm_worker_pool_alloc(); | |
2582 | + | |
2583 | + if (!wp) return 0; | |
2584 | + | |
2585 | + wp->config = malloc(sizeof(struct fpm_worker_pool_config_s)); | |
2586 | + | |
2587 | + if (!wp->config) return 0; | |
2588 | + | |
2589 | + memset(wp->config, 0, sizeof(struct fpm_worker_pool_config_s)); | |
2590 | + | |
2591 | + if (current_wp) current_wp->next = wp; | |
2592 | + | |
2593 | + current_wp = wp; | |
2594 | + | |
2595 | + return wp->config; | |
2596 | +} | |
2597 | + | |
2598 | +int fpm_worker_pool_config_free(struct fpm_worker_pool_config_s *wpc) | |
2599 | +{ | |
2600 | + struct key_value_s *kv, *kv_next; | |
2601 | + | |
2602 | + free(wpc->name); | |
2603 | + free(wpc->listen_address); | |
2604 | + if (wpc->listen_options) { | |
2605 | + free(wpc->listen_options->owner); | |
2606 | + free(wpc->listen_options->group); | |
2607 | + free(wpc->listen_options->mode); | |
2608 | + free(wpc->listen_options); | |
2609 | + } | |
2610 | + for (kv = wpc->php_defines; kv; kv = kv_next) { | |
2611 | + kv_next = kv->next; | |
2612 | + free(kv->key); | |
2613 | + free(kv->value); | |
2614 | + free(kv); | |
2615 | + } | |
2616 | + for (kv = wpc->environment; kv; kv = kv_next) { | |
2617 | + kv_next = kv->next; | |
2618 | + free(kv->key); | |
2619 | + free(kv->value); | |
2620 | + free(kv); | |
2621 | + } | |
2622 | + free(wpc->pm); | |
2623 | + free(wpc->user); | |
2624 | + free(wpc->group); | |
2625 | + free(wpc->chroot); | |
2626 | + free(wpc->chdir); | |
2627 | + free(wpc->allowed_clients); | |
c6a6bfc9 | 2628 | + free(wpc->slowlog); |
fd1be940 ER |
2629 | + |
2630 | + return 0; | |
2631 | +} | |
2632 | + | |
2633 | +static struct xml_conf_section xml_section_fpm_worker_pool_config = { | |
2634 | + .conf = &fpm_worker_pool_config_alloc, | |
2635 | + .path = "/configuration/workers/pool", | |
c6a6bfc9 | 2636 | + .parsers = (struct xml_value_parser []) { |
fd1be940 ER |
2637 | + { XML_CONF_SCALAR, "name", &xml_conf_set_slot_string, offsetof(struct fpm_worker_pool_config_s, name) }, |
2638 | + { XML_CONF_SCALAR, "listen_address", &xml_conf_set_slot_string, offsetof(struct fpm_worker_pool_config_s, listen_address) }, | |
2639 | + { XML_CONF_SUBSECTION, "listen_options", &fpm_conf_set_listen_options_subsection, offsetof(struct fpm_worker_pool_config_s, listen_options) }, | |
2640 | + { XML_CONF_SUBSECTION, "php_defines", &fpm_conf_set_key_value_pairs_subsection, offsetof(struct fpm_worker_pool_config_s, php_defines) }, | |
2641 | + { XML_CONF_SCALAR, "user", &xml_conf_set_slot_string, offsetof(struct fpm_worker_pool_config_s, user) }, | |
2642 | + { XML_CONF_SCALAR, "group", &xml_conf_set_slot_string, offsetof(struct fpm_worker_pool_config_s, group) }, | |
2643 | + { XML_CONF_SCALAR, "chroot", &xml_conf_set_slot_string, offsetof(struct fpm_worker_pool_config_s, chroot) }, | |
2644 | + { XML_CONF_SCALAR, "chdir", &xml_conf_set_slot_string, offsetof(struct fpm_worker_pool_config_s, chdir) }, | |
2645 | + { XML_CONF_SCALAR, "allowed_clients", &xml_conf_set_slot_string, offsetof(struct fpm_worker_pool_config_s, allowed_clients) }, | |
2646 | + { XML_CONF_SUBSECTION, "environment", &fpm_conf_set_key_value_pairs_subsection, offsetof(struct fpm_worker_pool_config_s, environment) }, | |
c6a6bfc9 ER |
2647 | + { XML_CONF_SCALAR, "request_terminate_timeout", &xml_conf_set_slot_time, offsetof(struct fpm_worker_pool_config_s, request_terminate_timeout) }, |
2648 | + { XML_CONF_SCALAR, "request_slowlog_timeout", &xml_conf_set_slot_time, offsetof(struct fpm_worker_pool_config_s, request_slowlog_timeout) }, | |
2649 | + { XML_CONF_SCALAR, "slowlog", &xml_conf_set_slot_string, offsetof(struct fpm_worker_pool_config_s, slowlog) }, | |
fd1be940 ER |
2650 | + { XML_CONF_SCALAR, "rlimit_files", &xml_conf_set_slot_integer, offsetof(struct fpm_worker_pool_config_s, rlimit_files) }, |
2651 | + { XML_CONF_SCALAR, "rlimit_core", &fpm_conf_set_rlimit_core, 0 }, | |
2652 | + { XML_CONF_SCALAR, "max_requests", &xml_conf_set_slot_integer, offsetof(struct fpm_worker_pool_config_s, max_requests) }, | |
2653 | + { XML_CONF_SCALAR, "catch_workers_output", &fpm_conf_set_catch_workers_output, 0 }, | |
2654 | + { XML_CONF_SUBSECTION, "pm", &fpm_conf_set_pm_subsection, offsetof(struct fpm_worker_pool_config_s, pm) }, | |
2655 | + { 0, 0, 0, 0 } | |
2656 | + } | |
2657 | +}; | |
2658 | + | |
2659 | +static struct xml_conf_section *fpm_conf_all_sections[] = { | |
2660 | + &xml_section_fpm_global_options, | |
2661 | + &xml_section_fpm_worker_pool_config, | |
2662 | + 0 | |
2663 | +}; | |
2664 | + | |
2665 | +static int fpm_evaluate_full_path(char **path) | |
2666 | +{ | |
2667 | + if (**path != '/') { | |
2668 | + char *full_path; | |
2669 | + | |
2670 | + full_path = malloc(sizeof(PHP_PREFIX) + strlen(*path) + 1); | |
2671 | + | |
2672 | + if (!full_path) return -1; | |
2673 | + | |
2674 | + sprintf(full_path, "%s/%s", PHP_PREFIX, *path); | |
2675 | + | |
2676 | + free(*path); | |
2677 | + | |
2678 | + *path = full_path; | |
2679 | + } | |
2680 | + | |
2681 | + return 0; | |
2682 | +} | |
2683 | + | |
2684 | +static int fpm_conf_process_all_pools() | |
2685 | +{ | |
2686 | + struct fpm_worker_pool_s *wp; | |
2687 | + | |
2688 | + if (!fpm_worker_all_pools) { | |
2689 | + zlog(ZLOG_STUFF, ZLOG_ERROR, "at least one pool section must be specified in config file"); | |
2690 | + return -1; | |
2691 | + } | |
2692 | + | |
2693 | + for (wp = fpm_worker_all_pools; wp; wp = wp->next) { | |
2694 | + | |
2695 | + if (wp->config->listen_address && *wp->config->listen_address) { | |
2696 | + | |
2697 | + wp->listen_address_domain = fpm_sockets_domain_from_address(wp->config->listen_address); | |
2698 | + | |
2699 | + if (wp->listen_address_domain == FPM_AF_UNIX && *wp->config->listen_address != '/') { | |
2700 | + fpm_evaluate_full_path(&wp->config->listen_address); | |
2701 | + } | |
2702 | + | |
2703 | + } | |
2704 | + else { | |
2705 | + | |
2706 | + wp->is_template = 1; | |
2707 | + | |
2708 | + } | |
c6a6bfc9 ER |
2709 | + |
2710 | + if (wp->config->request_slowlog_timeout) { | |
2711 | +#if HAVE_FPM_TRACE | |
2712 | + if (! (wp->config->slowlog && *wp->config->slowlog)) { | |
2713 | + zlog(ZLOG_STUFF, ZLOG_ERROR, "pool %s: 'slowlog' must be specified for use with 'request_slowlog_timeout'", | |
2714 | + wp->config->name); | |
2715 | + return -1; | |
2716 | + } | |
2717 | +#else | |
2718 | + static int warned = 0; | |
2719 | + | |
2720 | + if (!warned) { | |
2721 | + zlog(ZLOG_STUFF, ZLOG_WARNING, "pool %s: 'request_slowlog_timeout' is not supported on your system", | |
2722 | + wp->config->name); | |
2723 | + warned = 1; | |
2724 | + } | |
2725 | + | |
2726 | + wp->config->request_slowlog_timeout = 0; | |
2727 | +#endif | |
2728 | + } | |
2729 | + | |
2730 | + if (wp->config->request_slowlog_timeout && wp->config->slowlog && *wp->config->slowlog) { | |
2731 | + int fd; | |
2732 | + | |
2733 | + fpm_evaluate_full_path(&wp->config->slowlog); | |
2734 | + | |
2735 | + if (wp->config->request_slowlog_timeout) { | |
2736 | + fd = open(wp->config->slowlog, O_WRONLY | O_APPEND | O_CREAT, S_IRUSR | S_IWUSR); | |
2737 | + | |
2738 | + if (0 > fd) { | |
2739 | + zlog(ZLOG_STUFF, ZLOG_SYSERROR, "open(%s) failed", wp->config->slowlog); | |
2740 | + return -1; | |
2741 | + } | |
2742 | + close(fd); | |
2743 | + } | |
2744 | + } | |
fd1be940 ER |
2745 | + } |
2746 | + | |
2747 | + return 0; | |
2748 | +} | |
2749 | + | |
2750 | +int fpm_conf_unlink_pid() | |
2751 | +{ | |
c6a6bfc9 ER |
2752 | + if (fpm_global_options.pid_file) { |
2753 | + | |
2754 | + if (0 > unlink(fpm_global_options.pid_file)) { | |
2755 | + zlog(ZLOG_STUFF, ZLOG_SYSERROR, "unlink(\"%s\") failed", fpm_global_options.pid_file); | |
2756 | + return -1; | |
2757 | + } | |
2758 | + | |
fd1be940 ER |
2759 | + } |
2760 | + | |
2761 | + return 0; | |
2762 | +} | |
2763 | + | |
2764 | +int fpm_conf_write_pid() | |
2765 | +{ | |
2766 | + int fd; | |
2767 | + | |
2768 | + if (fpm_global_options.pid_file) { | |
2769 | + char buf[64]; | |
2770 | + int len; | |
2771 | + | |
2772 | + unlink(fpm_global_options.pid_file); | |
2773 | + | |
2774 | + fd = creat(fpm_global_options.pid_file, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); | |
2775 | + | |
c6a6bfc9 | 2776 | + if (fd < 0) { |
fd1be940 ER |
2777 | + zlog(ZLOG_STUFF, ZLOG_SYSERROR, "creat(\"%s\") failed", fpm_global_options.pid_file); |
2778 | + return -1; | |
2779 | + } | |
2780 | + | |
c6a6bfc9 | 2781 | + len = sprintf(buf, "%d", (int) fpm_globals.parent_pid); |
fd1be940 ER |
2782 | + |
2783 | + if (len != write(fd, buf, len)) { | |
2784 | + zlog(ZLOG_STUFF, ZLOG_SYSERROR, "write() failed"); | |
2785 | + return -1; | |
2786 | + } | |
2787 | + | |
2788 | + close(fd); | |
2789 | + } | |
2790 | + | |
2791 | + return 0; | |
2792 | +} | |
2793 | + | |
2794 | +static int fpm_conf_post_process() | |
2795 | +{ | |
fd1be940 ER |
2796 | + if (fpm_global_options.pid_file) { |
2797 | + fpm_evaluate_full_path(&fpm_global_options.pid_file); | |
2798 | + } | |
2799 | + | |
2800 | + if (!fpm_global_options.error_log) { | |
c6a6bfc9 | 2801 | + fpm_global_options.error_log = strdup(PHP_FPM_LOG_PATH); |
fd1be940 ER |
2802 | + } |
2803 | + | |
2804 | + fpm_evaluate_full_path(&fpm_global_options.error_log); | |
2805 | + | |
c6a6bfc9 | 2806 | + if (0 > fpm_stdio_open_error_log(0)) { |
fd1be940 ER |
2807 | + return -1; |
2808 | + } | |
2809 | + | |
fd1be940 ER |
2810 | + return fpm_conf_process_all_pools(); |
2811 | +} | |
2812 | + | |
2813 | +static void fpm_conf_cleanup(int which, void *arg) | |
2814 | +{ | |
2815 | + free(fpm_global_options.pid_file); | |
2816 | + free(fpm_global_options.error_log); | |
2817 | + fpm_global_options.pid_file = 0; | |
2818 | + fpm_global_options.error_log = 0; | |
2819 | +} | |
2820 | + | |
c6a6bfc9 | 2821 | +int fpm_conf_init_main() |
fd1be940 | 2822 | +{ |
c6a6bfc9 | 2823 | + char *filename = fpm_globals.config; |
fd1be940 ER |
2824 | + char *err; |
2825 | + | |
2826 | + if (0 > xml_conf_sections_register(fpm_conf_all_sections)) { | |
2827 | + return -1; | |
2828 | + } | |
2829 | + | |
2830 | + if (filename == NULL) { | |
c6a6bfc9 | 2831 | + filename = PHP_FPM_CONF_PATH; |
fd1be940 ER |
2832 | + } |
2833 | + | |
2834 | + err = xml_conf_load_file(filename); | |
2835 | + | |
2836 | + if (err) { | |
2837 | + zlog(ZLOG_STUFF, ZLOG_ERROR, "failed to load configuration file: %s", err); | |
2838 | + return -1; | |
2839 | + } | |
2840 | + | |
2841 | + if (0 > fpm_conf_post_process()) { | |
2842 | + return -1; | |
2843 | + } | |
2844 | + | |
2845 | + xml_conf_clean(); | |
2846 | + | |
2847 | + fpm_cleanup_add(FPM_CLEANUP_ALL, fpm_conf_cleanup, 0); | |
2848 | + | |
2849 | + return 0; | |
2850 | +} | |
8c0dac15 ER |
2851 | diff -Nru php-5.2.6.vanilla/sapi/cgi/fpm/fpm_conf.h php-5.2.6.fpm/sapi/cgi/fpm/fpm_conf.h |
2852 | --- php-5.2.6.vanilla/sapi/cgi/fpm/fpm_conf.h 1970-01-01 03:00:00.000000000 +0300 | |
2853 | +++ php-5.2.6.fpm/sapi/cgi/fpm/fpm_conf.h 2008-08-26 19:09:15.000000000 +0400 | |
c6a6bfc9 | 2854 | @@ -0,0 +1,73 @@ |
fd1be940 ER |
2855 | + |
2856 | + /* $Id$ */ | |
c6a6bfc9 | 2857 | + /* (c) 2007,2008 Andrei Nigmatulin */ |
fd1be940 ER |
2858 | + |
2859 | +#ifndef FPM_CONF_H | |
2860 | +#define FPM_CONF_H 1 | |
2861 | + | |
fd1be940 ER |
2862 | +struct key_value_s; |
2863 | + | |
2864 | +struct key_value_s { | |
2865 | + struct key_value_s *next; | |
2866 | + char *key; | |
2867 | + char *value; | |
2868 | +}; | |
2869 | + | |
2870 | +struct fpm_options_s { | |
2871 | + int emergency_restart_threshold; | |
2872 | + int emergency_restart_interval; | |
2873 | + int process_control_timeout; | |
2874 | + int daemonize; | |
2875 | + char *pid_file; | |
2876 | + char *error_log; | |
2877 | +}; | |
2878 | + | |
2879 | +extern struct fpm_options_s fpm_global_options; | |
2880 | + | |
2881 | +struct fpm_pm_s { | |
2882 | + int style; | |
2883 | + int max_children; | |
2884 | + struct { | |
2885 | + int StartServers; | |
2886 | + int MinSpareServers; | |
2887 | + int MaxSpareServers; | |
2888 | + } options_apache_like; | |
2889 | +}; | |
2890 | + | |
2891 | +struct fpm_listen_options_s { | |
2892 | + int backlog; | |
2893 | + char *owner; | |
2894 | + char *group; | |
2895 | + char *mode; | |
2896 | +}; | |
2897 | + | |
2898 | +struct fpm_worker_pool_config_s { | |
2899 | + char *name; | |
2900 | + char *listen_address; | |
2901 | + struct fpm_listen_options_s *listen_options; | |
2902 | + struct key_value_s *php_defines; | |
2903 | + char *user; | |
2904 | + char *group; | |
2905 | + char *chroot; | |
2906 | + char *chdir; | |
2907 | + char *allowed_clients; | |
2908 | + struct key_value_s *environment; | |
2909 | + struct fpm_pm_s *pm; | |
c6a6bfc9 ER |
2910 | + int request_terminate_timeout; |
2911 | + int request_slowlog_timeout; | |
2912 | + char *slowlog; | |
fd1be940 ER |
2913 | + int max_requests; |
2914 | + int rlimit_files; | |
2915 | + int rlimit_core; | |
c6a6bfc9 | 2916 | + unsigned catch_workers_output:1; |
fd1be940 ER |
2917 | +}; |
2918 | + | |
2919 | +enum { PM_STYLE_STATIC = 1, PM_STYLE_APACHE_LIKE = 2 }; | |
2920 | + | |
c6a6bfc9 | 2921 | +int fpm_conf_init_main(); |
fd1be940 ER |
2922 | +int fpm_worker_pool_config_free(struct fpm_worker_pool_config_s *wpc); |
2923 | +int fpm_conf_write_pid(); | |
2924 | +int fpm_conf_unlink_pid(); | |
2925 | + | |
2926 | +#endif | |
2927 | + | |
8c0dac15 ER |
2928 | diff -Nru php-5.2.6.vanilla/sapi/cgi/fpm/fpm_config.h php-5.2.6.fpm/sapi/cgi/fpm/fpm_config.h |
2929 | --- php-5.2.6.vanilla/sapi/cgi/fpm/fpm_config.h 1970-01-01 03:00:00.000000000 +0300 | |
2930 | +++ php-5.2.6.fpm/sapi/cgi/fpm/fpm_config.h 2008-05-25 04:30:43.000000000 +0400 | |
c6a6bfc9 | 2931 | @@ -0,0 +1,39 @@ |
fd1be940 ER |
2932 | + |
2933 | + /* $Id$ */ | |
c6a6bfc9 | 2934 | + /* (c) 2007,2008 Andrei Nigmatulin */ |
fd1be940 ER |
2935 | + |
2936 | +#include "php_config.h" | |
c6a6bfc9 | 2937 | +#include "fpm_autoconf.h" |
fd1be940 ER |
2938 | + |
2939 | + | |
2940 | +/* Solaris does not have it */ | |
2941 | +#ifndef INADDR_NONE | |
2942 | +#define INADDR_NONE (-1) | |
2943 | +#endif | |
2944 | + | |
2945 | + | |
2946 | +/* If we're not using GNU C, elide __attribute__ */ | |
2947 | +#ifndef __GNUC__ | |
2948 | +# define __attribute__(x) /*NOTHING*/ | |
2949 | +#endif | |
2950 | + | |
2951 | + | |
2952 | +/* Solaris does not have it */ | |
2953 | +#ifndef timersub | |
2954 | +#define timersub(tvp, uvp, vvp) \ | |
2955 | + do { \ | |
2956 | + (vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec; \ | |
2957 | + (vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec; \ | |
2958 | + if ((vvp)->tv_usec < 0) { \ | |
2959 | + (vvp)->tv_sec--; \ | |
2960 | + (vvp)->tv_usec += 1000000; \ | |
2961 | + } \ | |
2962 | + } while (0) | |
2963 | +#endif | |
c6a6bfc9 ER |
2964 | + |
2965 | +#if defined(HAVE_PTRACE) || defined(PROC_MEM_FILE) || defined(HAVE_MACH_VM_READ) | |
2966 | +#define HAVE_FPM_TRACE 1 | |
2967 | +#else | |
2968 | +#define HAVE_FPM_TRACE 0 | |
2969 | +#endif | |
2970 | + | |
8c0dac15 ER |
2971 | diff -Nru php-5.2.6.vanilla/sapi/cgi/fpm/fpm_env.c php-5.2.6.fpm/sapi/cgi/fpm/fpm_env.c |
2972 | --- php-5.2.6.vanilla/sapi/cgi/fpm/fpm_env.c 1970-01-01 03:00:00.000000000 +0300 | |
2973 | +++ php-5.2.6.fpm/sapi/cgi/fpm/fpm_env.c 2008-09-19 03:19:59.000000000 +0400 | |
fd1be940 ER |
2974 | @@ -0,0 +1,125 @@ |
2975 | + | |
2976 | + /* $Id$ */ | |
c6a6bfc9 | 2977 | + /* (c) 2007,2008 Andrei Nigmatulin */ |
fd1be940 ER |
2978 | + |
2979 | +#include "fpm_config.h" | |
2980 | + | |
2981 | +#ifdef HAVE_ALLOCA_H | |
2982 | +#include <alloca.h> | |
2983 | +#endif | |
2984 | +#include <stdio.h> | |
2985 | +#include <stdlib.h> | |
2986 | +#include <string.h> | |
2987 | + | |
2988 | +#include "fpm_env.h" | |
2989 | +#include "zlog.h" | |
2990 | + | |
c6a6bfc9 | 2991 | +#ifndef HAVE_SETENV |
fd1be940 ER |
2992 | +int setenv(char *name, char *value, int overwrite) |
2993 | +{ | |
2994 | + int name_len = strlen(name); | |
2995 | + int value_len = strlen(value); | |
2996 | + char *var = alloca(name_len + 1 + value_len + 1); | |
2997 | + | |
2998 | + memcpy(var, name, name_len); | |
2999 | + | |
3000 | + var[name_len] = '='; | |
3001 | + | |
3002 | + memcpy(var + name_len + 1, value, value_len); | |
3003 | + | |
3004 | + var[name_len + 1 + value_len] = '\0'; | |
3005 | + | |
3006 | + return putenv(var); | |
3007 | +} | |
3008 | +#endif | |
3009 | + | |
c6a6bfc9 | 3010 | +#ifndef HAVE_CLEARENV |
fd1be940 ER |
3011 | +void clearenv() |
3012 | +{ | |
3013 | + char **envp; | |
3014 | + char *s; | |
3015 | + | |
3016 | + /* this algo is the only one known to me | |
3017 | + that works well on all systems */ | |
3018 | + while (*(envp = environ)) { | |
3019 | + char *eq = strchr(*envp, '='); | |
3020 | + | |
3021 | + s = strdup(*envp); | |
3022 | + | |
3023 | + if (eq) s[eq - *envp] = '\0'; | |
3024 | + | |
3025 | + unsetenv(s); | |
3026 | + free(s); | |
3027 | + } | |
3028 | + | |
3029 | +} | |
3030 | +#endif | |
3031 | + | |
3032 | + | |
3033 | +int fpm_env_init_child(struct fpm_worker_pool_s *wp) | |
3034 | +{ | |
3035 | + struct key_value_s *kv; | |
3036 | + | |
3037 | + clearenv(); | |
3038 | + | |
3039 | + for (kv = wp->config->environment; kv; kv = kv->next) { | |
3040 | + setenv(kv->key, kv->value, 1); | |
3041 | + } | |
3042 | + | |
3043 | + if (wp->user) { | |
3044 | + setenv("USER", wp->user, 1); | |
3045 | + } | |
3046 | + | |
3047 | + if (wp->home) { | |
3048 | + setenv("HOME", wp->home, 1); | |
3049 | + } | |
3050 | + | |
3051 | + return 0; | |
3052 | +} | |
3053 | + | |
3054 | +static int fpm_env_conf_wp(struct fpm_worker_pool_s *wp) | |
3055 | +{ | |
3056 | + struct key_value_s *kv; | |
3057 | + | |
3058 | + kv = wp->config->environment; | |
3059 | + | |
3060 | + for (kv = wp->config->environment; kv; kv = kv->next) { | |
3061 | + if (*kv->value == '$') { | |
3062 | + char *value = getenv(kv->value + 1); | |
3063 | + | |
3064 | + if (!value) value = ""; | |
3065 | + | |
3066 | + free(kv->value); | |
3067 | + kv->value = strdup(value); | |
3068 | + } | |
3069 | + | |
3070 | + /* autodetected values should be removed | |
3071 | + if these vars specified in config */ | |
3072 | + if (!strcmp(kv->key, "USER")) { | |
3073 | + free(wp->user); | |
3074 | + wp->user = 0; | |
3075 | + } | |
3076 | + | |
3077 | + if (!strcmp(kv->key, "HOME")) { | |
3078 | + free(wp->home); | |
3079 | + wp->home = 0; | |
3080 | + } | |
3081 | + } | |
3082 | + | |
3083 | + return 0; | |
3084 | +} | |
3085 | + | |
3086 | +int fpm_env_init_main() | |
3087 | +{ | |
3088 | + struct fpm_worker_pool_s *wp; | |
3089 | + | |
3090 | + for (wp = fpm_worker_all_pools; wp; wp = wp->next) { | |
3091 | + | |
3092 | + if (0 > fpm_env_conf_wp(wp)) { | |
3093 | + return -1; | |
3094 | + } | |
3095 | + | |
3096 | + } | |
3097 | + | |
3098 | + return 0; | |
3099 | +} | |
8c0dac15 ER |
3100 | diff -Nru php-5.2.6.vanilla/sapi/cgi/fpm/fpm_env.h php-5.2.6.fpm/sapi/cgi/fpm/fpm_env.h |
3101 | --- php-5.2.6.vanilla/sapi/cgi/fpm/fpm_env.h 1970-01-01 03:00:00.000000000 +0300 | |
3102 | +++ php-5.2.6.fpm/sapi/cgi/fpm/fpm_env.h 2008-09-19 03:19:59.000000000 +0400 | |
fd1be940 ER |
3103 | @@ -0,0 +1,24 @@ |
3104 | + | |
3105 | + /* $Id$ */ | |
c6a6bfc9 | 3106 | + /* (c) 2007,2008 Andrei Nigmatulin */ |
fd1be940 ER |
3107 | + |
3108 | +#ifndef FPM_ENV_H | |
3109 | +#define FPM_ENV_H 1 | |
3110 | + | |
3111 | +#include "fpm_worker_pool.h" | |
3112 | + | |
3113 | +int fpm_env_init_child(struct fpm_worker_pool_s *wp); | |
3114 | +int fpm_env_init_main(); | |
3115 | + | |
3116 | +extern char **environ; | |
3117 | + | |
c6a6bfc9 | 3118 | +#ifndef HAVE_SETENV |
fd1be940 ER |
3119 | +int setenv(char *name, char *value, int overwrite); |
3120 | +#endif | |
3121 | + | |
c6a6bfc9 | 3122 | +#ifndef HAVE_CLEARENV |
fd1be940 ER |
3123 | +void clearenv(); |
3124 | +#endif | |
3125 | + | |
3126 | +#endif | |
3127 | + | |
8c0dac15 ER |
3128 | diff -Nru php-5.2.6.vanilla/sapi/cgi/fpm/fpm_events.c php-5.2.6.fpm/sapi/cgi/fpm/fpm_events.c |
3129 | --- php-5.2.6.vanilla/sapi/cgi/fpm/fpm_events.c 1970-01-01 03:00:00.000000000 +0300 | |
3130 | +++ php-5.2.6.fpm/sapi/cgi/fpm/fpm_events.c 2008-08-26 19:09:15.000000000 +0400 | |
c6a6bfc9 | 3131 | @@ -0,0 +1,133 @@ |
fd1be940 ER |
3132 | + |
3133 | + /* $Id$ */ | |
c6a6bfc9 | 3134 | + /* (c) 2007,2008 Andrei Nigmatulin */ |
fd1be940 ER |
3135 | + |
3136 | +#include "fpm_config.h" | |
3137 | + | |
3138 | +#include <unistd.h> | |
3139 | +#include <errno.h> | |
3140 | +#include <stdlib.h> /* for putenv */ | |
3141 | +#include <string.h> | |
3142 | +#include <sys/types.h> /* for event.h below */ | |
3143 | +#include <event.h> | |
3144 | + | |
c6a6bfc9 | 3145 | +#include "fpm.h" |
fd1be940 ER |
3146 | +#include "fpm_process_ctl.h" |
3147 | +#include "fpm_events.h" | |
3148 | +#include "fpm_cleanup.h" | |
c6a6bfc9 | 3149 | +#include "fpm_stdio.h" |
fd1be940 ER |
3150 | +#include "fpm_signals.h" |
3151 | +#include "fpm_children.h" | |
3152 | +#include "zlog.h" | |
3153 | + | |
fd1be940 ER |
3154 | +static void fpm_event_cleanup(int which, void *arg) |
3155 | +{ | |
3156 | + event_base_free(0); | |
3157 | +} | |
3158 | + | |
3159 | +static void fpm_got_signal(int fd, short ev, void *arg) | |
3160 | +{ | |
3161 | + char c; | |
3162 | + int res; | |
3163 | + | |
3164 | + do { | |
fd1be940 | 3165 | + |
c6a6bfc9 ER |
3166 | + do { |
3167 | + res = read(fd, &c, 1); | |
3168 | + } while (res == -1 && errno == EINTR); | |
3169 | + | |
3170 | + if (res <= 0) { | |
3171 | + if (res < 0 && errno != EAGAIN && errno != EWOULDBLOCK) { | |
3172 | + zlog(ZLOG_STUFF, ZLOG_SYSERROR, "read() failed"); | |
3173 | + } | |
3174 | + return; | |
fd1be940 | 3175 | + } |
fd1be940 | 3176 | + |
c6a6bfc9 ER |
3177 | + switch (c) { |
3178 | + case 'C' : /* SIGCHLD */ | |
3179 | + zlog(ZLOG_STUFF, ZLOG_NOTICE, "received SIGCHLD"); | |
3180 | + fpm_children_bury(); | |
3181 | + break; | |
3182 | + case 'I' : /* SIGINT */ | |
3183 | + zlog(ZLOG_STUFF, ZLOG_NOTICE, "received SIGINT"); | |
3184 | + fpm_pctl(FPM_PCTL_STATE_TERMINATING, FPM_PCTL_ACTION_SET); | |
3185 | + break; | |
3186 | + case 'T' : /* SIGTERM */ | |
3187 | + zlog(ZLOG_STUFF, ZLOG_NOTICE, "received SIGTERM"); | |
3188 | + fpm_pctl(FPM_PCTL_STATE_TERMINATING, FPM_PCTL_ACTION_SET); | |
3189 | + break; | |
3190 | + case 'Q' : /* SIGQUIT */ | |
3191 | + zlog(ZLOG_STUFF, ZLOG_NOTICE, "received SIGQUIT"); | |
3192 | + fpm_pctl(FPM_PCTL_STATE_FINISHING, FPM_PCTL_ACTION_SET); | |
3193 | + break; | |
3194 | + case '1' : /* SIGUSR1 */ | |
3195 | + zlog(ZLOG_STUFF, ZLOG_NOTICE, "received SIGUSR1"); | |
3196 | + if (0 == fpm_stdio_open_error_log(1)) { | |
3197 | + zlog(ZLOG_STUFF, ZLOG_NOTICE, "log file re-opened"); | |
3198 | + } | |
3199 | + break; | |
3200 | + case '2' : /* SIGUSR2 */ | |
3201 | + zlog(ZLOG_STUFF, ZLOG_NOTICE, "received SIGUSR2"); | |
3202 | + fpm_pctl(FPM_PCTL_STATE_RELOADING, FPM_PCTL_ACTION_SET); | |
3203 | + break; | |
3204 | + } | |
3205 | + | |
3206 | + if (fpm_globals.is_child) { | |
fd1be940 | 3207 | + break; |
c6a6bfc9 ER |
3208 | + } |
3209 | + | |
3210 | + } while (1); | |
fd1be940 ER |
3211 | + |
3212 | + return; | |
3213 | +} | |
3214 | + | |
3215 | +int fpm_event_init_main() | |
3216 | +{ | |
3217 | + event_init(); | |
3218 | + | |
3219 | + zlog(ZLOG_STUFF, ZLOG_NOTICE, "libevent: using %s", event_get_method()); | |
3220 | + | |
3221 | + fpm_cleanup_add(FPM_CLEANUP_ALL, fpm_event_cleanup, 0); | |
3222 | + | |
3223 | + return 0; | |
3224 | +} | |
3225 | + | |
3226 | +int fpm_event_loop() | |
3227 | +{ | |
3228 | + static struct event signal_fd_event; | |
3229 | + | |
3230 | + event_set(&signal_fd_event, fpm_signals_get_fd(), EV_PERSIST | EV_READ, &fpm_got_signal, 0); | |
3231 | + | |
3232 | + event_add(&signal_fd_event, 0); | |
3233 | + | |
c6a6bfc9 ER |
3234 | + fpm_pctl_heartbeat(-1, 0, 0); |
3235 | + | |
fd1be940 ER |
3236 | + zlog(ZLOG_STUFF, ZLOG_NOTICE, "libevent: entering main loop"); |
3237 | + | |
3238 | + event_loop(0); | |
3239 | + | |
fd1be940 ER |
3240 | + return 0; |
3241 | +} | |
3242 | + | |
3243 | +int fpm_event_add(int fd, struct event *ev, void (*callback)(int, short, void *), void *arg) | |
3244 | +{ | |
3245 | + event_set(ev, fd, EV_PERSIST | EV_READ, callback, arg); | |
3246 | + | |
3247 | + return event_add(ev, 0); | |
3248 | +} | |
3249 | + | |
3250 | +int fpm_event_del(struct event *ev) | |
3251 | +{ | |
3252 | + return event_del(ev); | |
3253 | +} | |
3254 | + | |
3255 | +void fpm_event_exit_loop() | |
3256 | +{ | |
3257 | + event_loopexit(0); | |
3258 | +} | |
3259 | + | |
3260 | +void fpm_event_fire(struct event *ev) | |
3261 | +{ | |
c6a6bfc9 | 3262 | + (*ev->ev_callback)( (int) ev->ev_fd, (short) ev->ev_res, ev->ev_arg); |
fd1be940 | 3263 | +} |
c6a6bfc9 | 3264 | + |
8c0dac15 ER |
3265 | diff -Nru php-5.2.6.vanilla/sapi/cgi/fpm/fpm_events.h php-5.2.6.fpm/sapi/cgi/fpm/fpm_events.h |
3266 | --- php-5.2.6.vanilla/sapi/cgi/fpm/fpm_events.h 1970-01-01 03:00:00.000000000 +0300 | |
3267 | +++ php-5.2.6.fpm/sapi/cgi/fpm/fpm_events.h 2008-05-24 21:38:47.000000000 +0400 | |
c6a6bfc9 | 3268 | @@ -0,0 +1,16 @@ |
fd1be940 ER |
3269 | + |
3270 | + /* $Id$ */ | |
c6a6bfc9 | 3271 | + /* (c) 2007,2008 Andrei Nigmatulin */ |
fd1be940 ER |
3272 | + |
3273 | +#ifndef FPM_EVENTS_H | |
3274 | +#define FPM_EVENTS_H 1 | |
3275 | + | |
fd1be940 ER |
3276 | +void fpm_event_exit_loop(); |
3277 | +int fpm_event_loop(); | |
3278 | +int fpm_event_add(int fd, struct event *ev, void (*callback)(int, short, void *), void *arg); | |
3279 | +int fpm_event_del(struct event *ev); | |
3280 | +void fpm_event_fire(struct event *ev); | |
3281 | +int fpm_event_init_main(); | |
3282 | + | |
3283 | + | |
3284 | +#endif | |
8c0dac15 ER |
3285 | diff -Nru php-5.2.6.vanilla/sapi/cgi/fpm/fpm.h php-5.2.6.fpm/sapi/cgi/fpm/fpm.h |
3286 | --- php-5.2.6.vanilla/sapi/cgi/fpm/fpm.h 1970-01-01 03:00:00.000000000 +0300 | |
3287 | +++ php-5.2.6.fpm/sapi/cgi/fpm/fpm.h 2008-05-24 21:38:47.000000000 +0400 | |
c6a6bfc9 | 3288 | @@ -0,0 +1,30 @@ |
fd1be940 ER |
3289 | + |
3290 | + /* $Id$ */ | |
c6a6bfc9 | 3291 | + /* (c) 2007,2008 Andrei Nigmatulin */ |
fd1be940 ER |
3292 | + |
3293 | +#ifndef FPM_H | |
3294 | +#define FPM_H 1 | |
3295 | + | |
c6a6bfc9 ER |
3296 | +#include <unistd.h> |
3297 | + | |
fd1be940 ER |
3298 | +int fpm_run(int *max_requests); |
3299 | +int fpm_init(int argc, char **argv, char *config); | |
fd1be940 ER |
3300 | + |
3301 | +struct fpm_globals_s { | |
c6a6bfc9 ER |
3302 | + pid_t parent_pid; |
3303 | + int argc; | |
3304 | + char **argv; | |
3305 | + char *config; | |
fd1be940 ER |
3306 | + int running_children; |
3307 | + int error_log_fd; | |
c6a6bfc9 | 3308 | + int log_level; |
fd1be940 ER |
3309 | + int listening_socket; /* for this child */ |
3310 | + int max_requests; /* for this child */ | |
3311 | + int is_child; | |
3312 | +}; | |
3313 | + | |
3314 | +extern struct fpm_globals_s fpm_globals; | |
3315 | + | |
c6a6bfc9 ER |
3316 | +extern int fpm; |
3317 | + | |
fd1be940 | 3318 | +#endif |
8c0dac15 ER |
3319 | diff -Nru php-5.2.6.vanilla/sapi/cgi/fpm/fpm_php.c php-5.2.6.fpm/sapi/cgi/fpm/fpm_php.c |
3320 | --- php-5.2.6.vanilla/sapi/cgi/fpm/fpm_php.c 1970-01-01 03:00:00.000000000 +0300 | |
3321 | +++ php-5.2.6.fpm/sapi/cgi/fpm/fpm_php.c 2008-07-20 20:16:28.000000000 +0400 | |
c6a6bfc9 | 3322 | @@ -0,0 +1,171 @@ |
fd1be940 ER |
3323 | + |
3324 | + /* $Id$ */ | |
c6a6bfc9 | 3325 | + /* (c) 2007,2008 Andrei Nigmatulin */ |
fd1be940 ER |
3326 | + |
3327 | +#include "fpm_config.h" | |
3328 | + | |
fd1be940 ER |
3329 | +#include <stdlib.h> |
3330 | +#include <string.h> | |
3331 | + | |
3332 | +#include "php.h" | |
3333 | +#include "php_main.h" | |
3334 | +#include "php_ini.h" | |
c6a6bfc9 | 3335 | +#include "ext/standard/dl.h" |
fd1be940 ER |
3336 | + |
3337 | +#include "fastcgi.h" | |
3338 | + | |
3339 | +#include "fpm.h" | |
3340 | +#include "fpm_php.h" | |
3341 | +#include "fpm_cleanup.h" | |
3342 | +#include "fpm_worker_pool.h" | |
3343 | + | |
3344 | +static int zend_ini_alter_master(char *name, int name_length, char *new_value, int new_value_length, int stage) | |
3345 | +{ | |
3346 | + zend_ini_entry *ini_entry; | |
3347 | + char *duplicate; | |
3348 | + | |
3349 | + if (zend_hash_find(EG(ini_directives), name, name_length, (void **) &ini_entry) == FAILURE) { | |
3350 | + return FAILURE; | |
3351 | + } | |
3352 | + | |
3353 | + duplicate = strdup(new_value); | |
3354 | + | |
3355 | + if (!ini_entry->on_modify | |
3356 | + || ini_entry->on_modify(ini_entry, duplicate, new_value_length, | |
c6a6bfc9 | 3357 | + ini_entry->mh_arg1, ini_entry->mh_arg2, ini_entry->mh_arg3, stage) == SUCCESS) { |
fd1be940 ER |
3358 | + ini_entry->value = duplicate; |
3359 | + ini_entry->value_length = new_value_length; | |
3360 | + } else { | |
3361 | + free(duplicate); | |
3362 | + } | |
3363 | + | |
3364 | + return SUCCESS; | |
3365 | +} | |
3366 | + | |
c6a6bfc9 ER |
3367 | +static void fpm_php_disable(char *value, int (*zend_disable)(char *, uint)) |
3368 | +{ | |
3369 | + char *s = 0, *e = value; | |
3370 | + | |
3371 | + while (*e) { | |
3372 | + switch (*e) { | |
3373 | + case ' ': | |
3374 | + case ',': | |
3375 | + if (s) { | |
3376 | + *e = '\0'; | |
3377 | + zend_disable(s, e - s); | |
3378 | + s = 0; | |
3379 | + } | |
3380 | + break; | |
3381 | + default: | |
3382 | + if (!s) { | |
3383 | + s = e; | |
3384 | + } | |
3385 | + break; | |
3386 | + } | |
3387 | + e++; | |
3388 | + } | |
3389 | + | |
3390 | + if (s) { | |
3391 | + zend_disable(s, e - s); | |
3392 | + } | |
3393 | +} | |
3394 | + | |
fd1be940 ER |
3395 | +static int fpm_php_apply_defines(struct fpm_worker_pool_s *wp) |
3396 | +{ | |
c6a6bfc9 ER |
3397 | + struct key_value_s *kv; |
3398 | + | |
3399 | + for (kv = wp->config->php_defines; kv; kv = kv->next) { | |
3400 | + char *name = kv->key; | |
3401 | + char *value = kv->value; | |
3402 | + int name_len = strlen(name); | |
3403 | + int value_len = strlen(value); | |
fd1be940 | 3404 | + |
c6a6bfc9 ER |
3405 | + if (!strcmp(name, "extension") && *value) { |
3406 | + zval zv; | |
fd1be940 | 3407 | + |
c6a6bfc9 ER |
3408 | +#if defined(PHP_VERSION_ID) && (PHP_VERSION_ID >= 50300) |
3409 | + php_dl(value, MODULE_PERSISTENT, &zv, 1); | |
3410 | +#else | |
3411 | + zval filename; | |
3412 | + ZVAL_STRINGL(&filename, value, value_len, 0); | |
3413 | +#if (PHP_MAJOR_VERSION >= 5) | |
3414 | + php_dl(&filename, MODULE_PERSISTENT, &zv, 1); | |
3415 | +#else | |
3416 | + php_dl(&filename, MODULE_PERSISTENT, &zv); | |
3417 | +#endif | |
3418 | +#endif | |
3419 | + continue; | |
3420 | + } | |
fd1be940 ER |
3421 | + |
3422 | + zend_ini_alter_master(name, name_len + 1, value, value_len, PHP_INI_STAGE_ACTIVATE); | |
3423 | + | |
c6a6bfc9 ER |
3424 | + if (!strcmp(name, "disable_functions") && *value) { |
3425 | + char *v = strdup(value); | |
3426 | +#if (PHP_MAJOR_VERSION >= 5) | |
3427 | + PG(disable_functions) = v; | |
3428 | +#endif | |
3429 | + fpm_php_disable(v, zend_disable_function); | |
3430 | + } | |
3431 | + else if (!strcmp(name, "disable_classes") && *value) { | |
3432 | + char *v = strdup(value); | |
3433 | +#if (PHP_MAJOR_VERSION >= 5) | |
3434 | + PG(disable_classes) = v; | |
3435 | +#endif | |
3436 | + fpm_php_disable(v, zend_disable_class); | |
3437 | + } | |
fd1be940 ER |
3438 | + } |
3439 | + | |
3440 | + return 0; | |
3441 | +} | |
3442 | + | |
3443 | +static int fpm_php_set_allowed_clients(struct fpm_worker_pool_s *wp) | |
3444 | +{ | |
3445 | + if (wp->listen_address_domain == FPM_AF_INET) { | |
3446 | + fcgi_set_allowed_clients(wp->config->allowed_clients); | |
3447 | + } | |
3448 | + | |
3449 | + return 0; | |
3450 | +} | |
3451 | + | |
c6a6bfc9 ER |
3452 | +char *fpm_php_script_filename() |
3453 | +{ | |
3454 | + return SG(request_info).path_translated; | |
3455 | +} | |
3456 | + | |
3457 | +char *fpm_php_request_method() | |
3458 | +{ | |
3459 | + return (char *) SG(request_info).request_method; | |
3460 | +} | |
3461 | + | |
3462 | +size_t fpm_php_content_length() | |
3463 | +{ | |
3464 | + return SG(request_info).content_length; | |
3465 | +} | |
3466 | + | |
fd1be940 ER |
3467 | +static void fpm_php_cleanup(int which, void *arg) |
3468 | +{ | |
c6a6bfc9 | 3469 | + php_module_shutdown(); |
fd1be940 ER |
3470 | + sapi_shutdown(); |
3471 | +} | |
3472 | + | |
c6a6bfc9 ER |
3473 | +void fpm_php_soft_quit() |
3474 | +{ | |
3475 | + fcgi_set_in_shutdown(1); | |
3476 | +} | |
3477 | + | |
fd1be940 ER |
3478 | +int fpm_php_init_main() |
3479 | +{ | |
3480 | + fpm_cleanup_add(FPM_CLEANUP_PARENT, fpm_php_cleanup, 0); | |
3481 | + | |
3482 | + return 0; | |
3483 | +} | |
3484 | + | |
3485 | +int fpm_php_init_child(struct fpm_worker_pool_s *wp) | |
3486 | +{ | |
3487 | + if (0 > fpm_php_apply_defines(wp) || | |
3488 | + 0 > fpm_php_set_allowed_clients(wp)) { | |
3489 | + return -1; | |
3490 | + } | |
3491 | + | |
3492 | + return 0; | |
3493 | +} | |
8c0dac15 ER |
3494 | diff -Nru php-5.2.6.vanilla/sapi/cgi/fpm/fpm_php.h php-5.2.6.fpm/sapi/cgi/fpm/fpm_php.h |
3495 | --- php-5.2.6.vanilla/sapi/cgi/fpm/fpm_php.h 1970-01-01 03:00:00.000000000 +0300 | |
3496 | +++ php-5.2.6.fpm/sapi/cgi/fpm/fpm_php.h 2008-05-24 21:38:47.000000000 +0400 | |
c6a6bfc9 | 3497 | @@ -0,0 +1,20 @@ |
fd1be940 ER |
3498 | + |
3499 | + /* $Id$ */ | |
c6a6bfc9 | 3500 | + /* (c) 2007,2008 Andrei Nigmatulin */ |
fd1be940 ER |
3501 | + |
3502 | +#ifndef FPM_PHP_H | |
3503 | +#define FPM_PHP_H 1 | |
3504 | + | |
3505 | +#include "fpm_worker_pool.h" | |
3506 | + | |
3507 | +#include "build-defs.h" /* for PHP_ defines */ | |
3508 | + | |
3509 | +int fpm_php_init_child(struct fpm_worker_pool_s *wp); | |
c6a6bfc9 ER |
3510 | +char *fpm_php_script_filename(); |
3511 | +char *fpm_php_request_method(); | |
3512 | +size_t fpm_php_content_length(); | |
3513 | +void fpm_php_soft_quit(); | |
fd1be940 ER |
3514 | +int fpm_php_init_main(); |
3515 | + | |
3516 | +#endif | |
3517 | + | |
8c0dac15 ER |
3518 | diff -Nru php-5.2.6.vanilla/sapi/cgi/fpm/fpm_php_trace.c php-5.2.6.fpm/sapi/cgi/fpm/fpm_php_trace.c |
3519 | --- php-5.2.6.vanilla/sapi/cgi/fpm/fpm_php_trace.c 1970-01-01 03:00:00.000000000 +0300 | |
3520 | +++ php-5.2.6.fpm/sapi/cgi/fpm/fpm_php_trace.c 2008-08-26 19:09:15.000000000 +0400 | |
c6a6bfc9 | 3521 | @@ -0,0 +1,170 @@ |
fd1be940 ER |
3522 | + |
3523 | + /* $Id$ */ | |
c6a6bfc9 ER |
3524 | + /* (c) 2007,2008 Andrei Nigmatulin */ |
3525 | + | |
3526 | +#include "fpm_config.h" | |
3527 | + | |
3528 | +#if HAVE_FPM_TRACE | |
3529 | + | |
3530 | +#include "php.h" | |
3531 | +#include "php_main.h" | |
3532 | + | |
3533 | +#include <stdio.h> | |
3534 | +#include <stddef.h> | |
3535 | +#include <stdint.h> | |
3536 | +#include <unistd.h> | |
3537 | +#include <sys/time.h> | |
3538 | +#include <sys/types.h> | |
3539 | +#include <errno.h> | |
3540 | + | |
3541 | +#include "fpm_trace.h" | |
3542 | +#include "fpm_php_trace.h" | |
3543 | +#include "fpm_children.h" | |
3544 | +#include "fpm_worker_pool.h" | |
3545 | +#include "fpm_process_ctl.h" | |
3546 | + | |
3547 | +#include "zlog.h" | |
3548 | + | |
3549 | + | |
3550 | +#define valid_ptr(p) ((p) && 0 == ((p) & (sizeof(long) - 1))) | |
3551 | + | |
3552 | +#if SIZEOF_LONG == 4 | |
3553 | +#define PTR_FMT "08" | |
3554 | +#elif SIZEOF_LONG == 8 | |
3555 | +#define PTR_FMT "016" | |
3556 | +#endif | |
3557 | + | |
3558 | + | |
3559 | +static int fpm_php_trace_dump(struct fpm_child_s *child, FILE *slowlog) | |
3560 | +{ | |
3561 | + int callers_limit = 20; | |
3562 | + pid_t pid = child->pid; | |
3563 | + struct timeval tv; | |
3564 | + static const int buf_size = 1024; | |
3565 | + char buf[buf_size]; | |
3566 | + long execute_data; | |
3567 | + long l; | |
3568 | + | |
3569 | + gettimeofday(&tv, 0); | |
3570 | + | |
3571 | + zlog_print_time(&tv, buf, buf_size); | |
3572 | + | |
3573 | + fprintf(slowlog, "\n%s pid %d (pool %s)\n", buf, (int) pid, child->wp->config->name); | |
3574 | + | |
3575 | + if (0 > fpm_trace_get_strz(buf, buf_size, (long) &SG(request_info).path_translated)) { | |
3576 | + return -1; | |
3577 | + } | |
3578 | + | |
3579 | + fprintf(slowlog, "script_filename = %s\n", buf); | |
3580 | + | |
3581 | + if (0 > fpm_trace_get_long((long) &EG(current_execute_data), &l)) { | |
3582 | + return -1; | |
3583 | + } | |
3584 | + | |
3585 | + execute_data = l; | |
3586 | + | |
3587 | + while (execute_data) { | |
3588 | + long function; | |
3589 | + uint lineno = 0; | |
3590 | + | |
3591 | + fprintf(slowlog, "[0x%" PTR_FMT "lx] ", execute_data); | |
3592 | + | |
3593 | + if (0 > fpm_trace_get_long(execute_data + offsetof(zend_execute_data, function_state.function), &l)) { | |
3594 | + return -1; | |
3595 | + } | |
3596 | + | |
3597 | + function = l; | |
3598 | + | |
3599 | + if (valid_ptr(function)) { | |
3600 | + if (0 > fpm_trace_get_strz(buf, buf_size, function + offsetof(zend_function, common.function_name))) { | |
3601 | + return -1; | |
3602 | + } | |
3603 | + | |
3604 | + fprintf(slowlog, "%s()", buf); | |
3605 | + } | |
3606 | + else { | |
3607 | + fprintf(slowlog, "???"); | |
3608 | + } | |
3609 | + | |
3610 | + if (0 > fpm_trace_get_long(execute_data + offsetof(zend_execute_data, op_array), &l)) { | |
3611 | + return -1; | |
3612 | + } | |
3613 | + | |
3614 | + *buf = '\0'; | |
3615 | + | |
3616 | + if (valid_ptr(l)) { | |
3617 | + long op_array = l; | |
3618 | + | |
3619 | + if (0 > fpm_trace_get_strz(buf, buf_size, op_array + offsetof(zend_op_array, filename))) { | |
3620 | + return -1; | |
3621 | + } | |
3622 | + } | |
3623 | + | |
3624 | + if (0 > fpm_trace_get_long(execute_data + offsetof(zend_execute_data, opline), &l)) { | |
3625 | + return -1; | |
3626 | + } | |
3627 | + | |
3628 | + if (valid_ptr(l)) { | |
3629 | + long opline = l; | |
3630 | + uint *lu = (uint *) &l; | |
3631 | + | |
3632 | + if (0 > fpm_trace_get_long(opline + offsetof(struct _zend_op, lineno), &l)) { | |
3633 | + return -1; | |
3634 | + } | |
3635 | + | |
3636 | + lineno = *lu; | |
3637 | + } | |
3638 | + | |
3639 | + fprintf(slowlog, " %s:%u\n", *buf ? buf : "unknown", lineno); | |
3640 | + | |
3641 | + if (0 > fpm_trace_get_long(execute_data + offsetof(zend_execute_data, prev_execute_data), &l)) { | |
3642 | + return -1; | |
3643 | + } | |
3644 | + | |
3645 | + execute_data = l; | |
3646 | + | |
3647 | + if (0 == --callers_limit) { | |
3648 | + break; | |
3649 | + } | |
3650 | + } | |
3651 | + | |
3652 | + return 0; | |
3653 | +} | |
3654 | + | |
3655 | +void fpm_php_trace(struct fpm_child_s *child) | |
3656 | +{ | |
3657 | + FILE *slowlog; | |
3658 | + | |
3659 | + zlog(ZLOG_STUFF, ZLOG_NOTICE, "about to trace %d", (int) child->pid); | |
3660 | + | |
3661 | + slowlog = fopen(child->wp->config->slowlog, "a+"); | |
3662 | + | |
3663 | + if (!slowlog) { | |
3664 | + zlog(ZLOG_STUFF, ZLOG_SYSERROR, "fopen(%s) failed", child->wp->config->slowlog); | |
3665 | + goto done0; | |
3666 | + } | |
3667 | + | |
3668 | + if (0 > fpm_trace_ready(child->pid)) { | |
3669 | + goto done1; | |
3670 | + } | |
3671 | + | |
3672 | + if (0 > fpm_php_trace_dump(child, slowlog)) { | |
3673 | + fprintf(slowlog, "+++ dump failed\n"); | |
3674 | + } | |
3675 | + | |
3676 | + if (0 > fpm_trace_close(child->pid)) { | |
3677 | + goto done1; | |
3678 | + } | |
3679 | + | |
3680 | +done1: | |
3681 | + fclose(slowlog); | |
3682 | + | |
3683 | +done0: | |
3684 | + fpm_pctl_kill(child->pid, FPM_PCTL_CONT); | |
3685 | + child->tracer = 0; | |
3686 | + | |
3687 | + zlog(ZLOG_STUFF, ZLOG_NOTICE, "finished trace of %d", (int) child->pid); | |
3688 | +} | |
3689 | + | |
3690 | +#endif | |
3691 | + | |
8c0dac15 ER |
3692 | diff -Nru php-5.2.6.vanilla/sapi/cgi/fpm/fpm_php_trace.h php-5.2.6.fpm/sapi/cgi/fpm/fpm_php_trace.h |
3693 | --- php-5.2.6.vanilla/sapi/cgi/fpm/fpm_php_trace.h 1970-01-01 03:00:00.000000000 +0300 | |
3694 | +++ php-5.2.6.fpm/sapi/cgi/fpm/fpm_php_trace.h 2008-05-24 21:38:47.000000000 +0400 | |
c6a6bfc9 ER |
3695 | @@ -0,0 +1,13 @@ |
3696 | + | |
3697 | + /* $Id$ */ | |
3698 | + /* (c) 2007,2008 Andrei Nigmatulin */ | |
3699 | + | |
3700 | +#ifndef FPM_PHP_TRACE_H | |
3701 | +#define FPM_PHP_TRACE_H 1 | |
3702 | + | |
3703 | +struct fpm_child_s; | |
3704 | + | |
3705 | +void fpm_php_trace(struct fpm_child_s *); | |
3706 | + | |
3707 | +#endif | |
3708 | + | |
8c0dac15 ER |
3709 | diff -Nru php-5.2.6.vanilla/sapi/cgi/fpm/fpm_process_ctl.c php-5.2.6.fpm/sapi/cgi/fpm/fpm_process_ctl.c |
3710 | --- php-5.2.6.vanilla/sapi/cgi/fpm/fpm_process_ctl.c 1970-01-01 03:00:00.000000000 +0300 | |
3711 | +++ php-5.2.6.fpm/sapi/cgi/fpm/fpm_process_ctl.c 2008-07-21 17:13:44.000000000 +0400 | |
c6a6bfc9 ER |
3712 | @@ -0,0 +1,352 @@ |
3713 | + | |
3714 | + /* $Id$ */ | |
3715 | + /* (c) 2007,2008 Andrei Nigmatulin */ | |
fd1be940 ER |
3716 | + |
3717 | +#include "fpm_config.h" | |
3718 | + | |
3719 | +#include <sys/types.h> | |
3720 | +#include <signal.h> | |
3721 | +#include <unistd.h> | |
3722 | +#include <stdlib.h> | |
3723 | + | |
3724 | +#include "fpm.h" | |
c6a6bfc9 | 3725 | +#include "fpm_clock.h" |
fd1be940 ER |
3726 | +#include "fpm_children.h" |
3727 | +#include "fpm_signals.h" | |
3728 | +#include "fpm_events.h" | |
3729 | +#include "fpm_process_ctl.h" | |
3730 | +#include "fpm_cleanup.h" | |
c6a6bfc9 | 3731 | +#include "fpm_request.h" |
fd1be940 ER |
3732 | +#include "fpm_worker_pool.h" |
3733 | +#include "zlog.h" | |
3734 | + | |
3735 | + | |
3736 | +static int fpm_state = FPM_PCTL_STATE_NORMAL; | |
3737 | +static int fpm_signal_sent = 0; | |
3738 | + | |
3739 | + | |
3740 | +static const char *fpm_state_names[] = { | |
3741 | + [FPM_PCTL_STATE_NORMAL] = "normal", | |
3742 | + [FPM_PCTL_STATE_RELOADING] = "reloading", | |
3743 | + [FPM_PCTL_STATE_TERMINATING] = "terminating", | |
3744 | + [FPM_PCTL_STATE_FINISHING] = "finishing" | |
3745 | +}; | |
3746 | + | |
3747 | +static int saved_argc; | |
3748 | +static char **saved_argv; | |
fd1be940 ER |
3749 | + |
3750 | +static void fpm_pctl_cleanup(int which, void *arg) | |
3751 | +{ | |
3752 | + int i; | |
3753 | + | |
3754 | + if (which != FPM_CLEANUP_PARENT_EXEC) { | |
3755 | + | |
c6a6bfc9 | 3756 | + for (i = 0; i < saved_argc; i++) { |
fd1be940 ER |
3757 | + free(saved_argv[i]); |
3758 | + } | |
3759 | + | |
3760 | + free(saved_argv); | |
3761 | + | |
3762 | + } | |
3763 | +} | |
3764 | + | |
c6a6bfc9 ER |
3765 | +static struct event pctl_event; |
3766 | + | |
3767 | +static void fpm_pctl_action(int fd, short which, void *arg) | |
3768 | +{ | |
3769 | + evtimer_del(&pctl_event); | |
3770 | + | |
3771 | + memset(&pctl_event, 0, sizeof(pctl_event)); | |
3772 | + | |
3773 | + fpm_pctl(FPM_PCTL_STATE_UNSPECIFIED, FPM_PCTL_ACTION_TIMEOUT); | |
3774 | +} | |
3775 | + | |
3776 | +static int fpm_pctl_timeout_set(int sec) | |
3777 | +{ | |
3778 | + struct timeval tv = { .tv_sec = sec, .tv_usec = 0 }; | |
3779 | + | |
3780 | + if (evtimer_initialized(&pctl_event)) { | |
3781 | + evtimer_del(&pctl_event); | |
3782 | + } | |
3783 | + | |
3784 | + evtimer_set(&pctl_event, &fpm_pctl_action, 0); | |
3785 | + | |
3786 | + evtimer_add(&pctl_event, &tv); | |
3787 | + | |
3788 | + return 0; | |
3789 | +} | |
3790 | + | |
fd1be940 ER |
3791 | +static void fpm_pctl_exit() |
3792 | +{ | |
3793 | + zlog(ZLOG_STUFF, ZLOG_NOTICE, "exiting, bye-bye!"); | |
3794 | + | |
3795 | + fpm_conf_unlink_pid(); | |
3796 | + | |
3797 | + fpm_cleanups_run(FPM_CLEANUP_PARENT_EXIT_MAIN); | |
3798 | + | |
3799 | + exit(0); | |
3800 | +} | |
3801 | + | |
3802 | +#define optional_arg(c) (saved_argc > c ? ", \"" : ""), (saved_argc > c ? saved_argv[c] : ""), (saved_argc > c ? "\"" : "") | |
3803 | + | |
3804 | +static void fpm_pctl_exec() | |
3805 | +{ | |
3806 | + | |
3807 | + zlog(ZLOG_STUFF, ZLOG_NOTICE, "reloading: execvp(\"%s\", {\"%s\"" | |
3808 | + "%s%s%s" "%s%s%s" "%s%s%s" "%s%s%s" "%s%s%s" | |
3809 | + "%s%s%s" "%s%s%s" "%s%s%s" "%s%s%s" "%s%s%s" | |
3810 | + "})", | |
3811 | + saved_argv[0], saved_argv[0], | |
3812 | + optional_arg(1), | |
3813 | + optional_arg(2), | |
3814 | + optional_arg(3), | |
3815 | + optional_arg(4), | |
3816 | + optional_arg(5), | |
3817 | + optional_arg(6), | |
3818 | + optional_arg(7), | |
3819 | + optional_arg(8), | |
3820 | + optional_arg(9), | |
3821 | + optional_arg(10) | |
3822 | + ); | |
3823 | + | |
3824 | + fpm_cleanups_run(FPM_CLEANUP_PARENT_EXEC); | |
3825 | + | |
3826 | + execvp(saved_argv[0], saved_argv); | |
3827 | + | |
3828 | + zlog(ZLOG_STUFF, ZLOG_SYSERROR, "execvp() failed"); | |
3829 | + | |
c6a6bfc9 | 3830 | + exit(1); |
fd1be940 ER |
3831 | +} |
3832 | + | |
3833 | +static void fpm_pctl_action_last() | |
3834 | +{ | |
3835 | + switch (fpm_state) { | |
3836 | + | |
3837 | + case FPM_PCTL_STATE_RELOADING : | |
3838 | + | |
3839 | + fpm_pctl_exec(); | |
3840 | + break; | |
3841 | + | |
3842 | + case FPM_PCTL_STATE_FINISHING : | |
3843 | + | |
3844 | + case FPM_PCTL_STATE_TERMINATING : | |
3845 | + | |
3846 | + fpm_pctl_exit(); | |
3847 | + break; | |
3848 | + } | |
3849 | +} | |
3850 | + | |
c6a6bfc9 ER |
3851 | +int fpm_pctl_kill(pid_t pid, int how) |
3852 | +{ | |
3853 | + int s = 0; | |
3854 | + | |
3855 | + switch (how) { | |
3856 | + case FPM_PCTL_TERM : | |
3857 | + s = SIGTERM; | |
3858 | + break; | |
3859 | + case FPM_PCTL_STOP : | |
3860 | + s = SIGSTOP; | |
3861 | + break; | |
3862 | + case FPM_PCTL_CONT : | |
3863 | + s = SIGCONT; | |
3864 | + break; | |
3865 | + default : | |
3866 | + break; | |
3867 | + } | |
3868 | + | |
3869 | + return kill(pid, s); | |
3870 | +} | |
3871 | + | |
fd1be940 ER |
3872 | +static void fpm_pctl_kill_all(int signo) |
3873 | +{ | |
3874 | + struct fpm_worker_pool_s *wp; | |
3875 | + int alive_children = 0; | |
3876 | + | |
3877 | + for (wp = fpm_worker_all_pools; wp; wp = wp->next) { | |
3878 | + struct fpm_child_s *child; | |
3879 | + | |
3880 | + for (child = wp->children; child; child = child->next) { | |
3881 | + | |
3882 | + int res = kill(child->pid, signo); | |
3883 | + | |
3884 | + zlog(ZLOG_STUFF, ZLOG_NOTICE, "sending signal %d %s to child %d (pool %s)", signo, | |
3885 | + fpm_signal_names[signo] ? fpm_signal_names[signo] : "", | |
3886 | + (int) child->pid, child->wp->config->name); | |
3887 | + | |
3888 | + if (res == 0) ++alive_children; | |
3889 | + } | |
3890 | + } | |
3891 | + | |
3892 | + if (alive_children) { | |
3893 | + zlog(ZLOG_STUFF, ZLOG_NOTICE, "%d %s still alive", alive_children, alive_children == 1 ? "child is" : "children are"); | |
3894 | + } | |
3895 | +} | |
3896 | + | |
3897 | +static void fpm_pctl_action_next() | |
3898 | +{ | |
3899 | + int sig, timeout; | |
3900 | + | |
3901 | + if (!fpm_globals.running_children) fpm_pctl_action_last(); | |
3902 | + | |
3903 | + if (fpm_signal_sent == 0) { | |
3904 | + if (fpm_state == FPM_PCTL_STATE_TERMINATING) { | |
3905 | + sig = SIGTERM; | |
3906 | + } | |
3907 | + else { | |
3908 | + sig = SIGQUIT; | |
3909 | + } | |
3910 | + timeout = fpm_global_options.process_control_timeout; | |
3911 | + } | |
3912 | + else { | |
3913 | + if (fpm_signal_sent == SIGQUIT) { | |
3914 | + sig = SIGTERM; | |
3915 | + } | |
3916 | + else { | |
3917 | + sig = SIGKILL; | |
3918 | + } | |
3919 | + timeout = 1; | |
3920 | + } | |
3921 | + | |
3922 | + fpm_pctl_kill_all(sig); | |
3923 | + | |
3924 | + fpm_signal_sent = sig; | |
3925 | + | |
c6a6bfc9 | 3926 | + fpm_pctl_timeout_set(timeout); |
fd1be940 ER |
3927 | +} |
3928 | + | |
3929 | +void fpm_pctl(int new_state, int action) | |
3930 | +{ | |
3931 | + switch (action) { | |
3932 | + | |
3933 | + case FPM_PCTL_ACTION_SET : | |
3934 | + | |
3935 | + if (fpm_state == new_state) { /* already in progress - just ignore duplicate signal */ | |
3936 | + return; | |
3937 | + } | |
3938 | + | |
3939 | + switch (fpm_state) { /* check which states can be overridden */ | |
3940 | + | |
3941 | + case FPM_PCTL_STATE_NORMAL : | |
3942 | + | |
3943 | + /* 'normal' can be overridden by any other state */ | |
3944 | + break; | |
3945 | + | |
3946 | + case FPM_PCTL_STATE_RELOADING : | |
3947 | + | |
3948 | + /* 'reloading' can be overridden by 'finishing' */ | |
3949 | + if (new_state == FPM_PCTL_STATE_FINISHING) break; | |
3950 | + | |
3951 | + case FPM_PCTL_STATE_FINISHING : | |
3952 | + | |
3953 | + /* 'reloading' and 'finishing' can be overridden by 'terminating' */ | |
3954 | + if (new_state == FPM_PCTL_STATE_TERMINATING) break; | |
3955 | + | |
3956 | + case FPM_PCTL_STATE_TERMINATING : | |
3957 | + | |
3958 | + /* nothing can override 'terminating' state */ | |
3959 | + zlog(ZLOG_STUFF, ZLOG_NOTICE, "not switching to '%s' state, because already in '%s' state", | |
3960 | + fpm_state_names[new_state], fpm_state_names[fpm_state]); | |
3961 | + | |
3962 | + return; | |
3963 | + } | |
3964 | + | |
3965 | + fpm_signal_sent = 0; | |
3966 | + fpm_state = new_state; | |
3967 | + | |
3968 | + zlog(ZLOG_STUFF, ZLOG_NOTICE, "switching to '%s' state", fpm_state_names[fpm_state]); | |
3969 | + | |
3970 | + /* fall down */ | |
3971 | + | |
3972 | + case FPM_PCTL_ACTION_TIMEOUT : | |
3973 | + | |
3974 | + fpm_pctl_action_next(); | |
3975 | + | |
3976 | + break; | |
3977 | + | |
3978 | + case FPM_PCTL_ACTION_LAST_CHILD_EXITED : | |
3979 | + | |
3980 | + fpm_pctl_action_last(); | |
3981 | + | |
3982 | + break; | |
3983 | + | |
3984 | + } | |
3985 | +} | |
3986 | + | |
3987 | +int fpm_pctl_can_spawn_children() | |
3988 | +{ | |
3989 | + return fpm_state == FPM_PCTL_STATE_NORMAL; | |
3990 | +} | |
3991 | + | |
3992 | +int fpm_pctl_child_exited() | |
3993 | +{ | |
3994 | + if (fpm_state == FPM_PCTL_STATE_NORMAL) return 0; | |
3995 | + | |
3996 | + if (!fpm_globals.running_children) { | |
3997 | + fpm_pctl(FPM_PCTL_STATE_UNSPECIFIED, FPM_PCTL_ACTION_LAST_CHILD_EXITED); | |
3998 | + } | |
3999 | + | |
4000 | + return 0; | |
4001 | +} | |
4002 | + | |
c6a6bfc9 | 4003 | +int fpm_pctl_init_main() |
fd1be940 | 4004 | +{ |
c6a6bfc9 | 4005 | + int i; |
fd1be940 | 4006 | + |
c6a6bfc9 | 4007 | + saved_argc = fpm_globals.argc; |
fd1be940 | 4008 | + |
c6a6bfc9 | 4009 | + saved_argv = malloc(sizeof(char *) * (saved_argc + 1)); |
fd1be940 | 4010 | + |
c6a6bfc9 ER |
4011 | + if (!saved_argv) { |
4012 | + return -1; | |
4013 | + } | |
fd1be940 | 4014 | + |
c6a6bfc9 ER |
4015 | + for (i = 0; i < saved_argc; i++) { |
4016 | + saved_argv[i] = strdup(fpm_globals.argv[i]); | |
fd1be940 | 4017 | + |
c6a6bfc9 ER |
4018 | + if (!saved_argv[i]) { |
4019 | + return -1; | |
4020 | + } | |
fd1be940 ER |
4021 | + } |
4022 | + | |
c6a6bfc9 | 4023 | + saved_argv[i] = 0; |
fd1be940 ER |
4024 | + |
4025 | + fpm_cleanup_add(FPM_CLEANUP_ALL, fpm_pctl_cleanup, 0); | |
4026 | + | |
4027 | + return 0; | |
4028 | +} | |
4029 | + | |
c6a6bfc9 ER |
4030 | +static void fpm_pctl_check_request_timeout(struct timeval *now) |
4031 | +{ | |
4032 | + struct fpm_worker_pool_s *wp; | |
4033 | + | |
4034 | + for (wp = fpm_worker_all_pools; wp; wp = wp->next) { | |
4035 | + int terminate_timeout = wp->config->request_terminate_timeout; | |
4036 | + int slowlog_timeout = wp->config->request_slowlog_timeout; | |
4037 | + struct fpm_child_s *child; | |
4038 | + | |
4039 | + if (terminate_timeout || slowlog_timeout) { | |
4040 | + for (child = wp->children; child; child = child->next) { | |
4041 | + fpm_request_check_timed_out(child, now, terminate_timeout, slowlog_timeout); | |
4042 | + } | |
4043 | + } | |
4044 | + } | |
4045 | + | |
4046 | +} | |
4047 | + | |
4048 | +void fpm_pctl_heartbeat(int fd, short which, void *arg) | |
4049 | +{ | |
4050 | + static struct event heartbeat; | |
4051 | + struct timeval tv = { .tv_sec = 0, .tv_usec = 130000 }; | |
4052 | + struct timeval now; | |
4053 | + | |
4054 | + if (which == EV_TIMEOUT) { | |
4055 | + evtimer_del(&heartbeat); | |
4056 | + fpm_clock_get(&now); | |
4057 | + fpm_pctl_check_request_timeout(&now); | |
4058 | + } | |
4059 | + | |
4060 | + evtimer_set(&heartbeat, &fpm_pctl_heartbeat, 0); | |
4061 | + | |
4062 | + evtimer_add(&heartbeat, &tv); | |
4063 | +} | |
4064 | + | |
8c0dac15 ER |
4065 | diff -Nru php-5.2.6.vanilla/sapi/cgi/fpm/fpm_process_ctl.h php-5.2.6.fpm/sapi/cgi/fpm/fpm_process_ctl.h |
4066 | --- php-5.2.6.vanilla/sapi/cgi/fpm/fpm_process_ctl.h 1970-01-01 03:00:00.000000000 +0300 | |
4067 | +++ php-5.2.6.fpm/sapi/cgi/fpm/fpm_process_ctl.h 2008-07-21 01:33:10.000000000 +0400 | |
c6a6bfc9 | 4068 | @@ -0,0 +1,39 @@ |
fd1be940 ER |
4069 | + |
4070 | + /* $Id$ */ | |
c6a6bfc9 | 4071 | + /* (c) 2007,2008 Andrei Nigmatulin */ |
fd1be940 ER |
4072 | + |
4073 | +#ifndef FPM_PROCESS_CTL_H | |
4074 | +#define FPM_PROCESS_CTL_H 1 | |
4075 | + | |
c6a6bfc9 ER |
4076 | +struct fpm_child_s; |
4077 | + | |
fd1be940 ER |
4078 | +void fpm_pctl(int new_state, int action); |
4079 | +int fpm_pctl_can_spawn_children(); | |
c6a6bfc9 ER |
4080 | +int fpm_pctl_kill(pid_t pid, int how); |
4081 | +void fpm_pctl_heartbeat(int fd, short which, void *arg); | |
fd1be940 | 4082 | +int fpm_pctl_child_exited(); |
c6a6bfc9 | 4083 | +int fpm_pctl_init_main(); |
fd1be940 ER |
4084 | + |
4085 | + | |
4086 | +enum { | |
4087 | + FPM_PCTL_STATE_UNSPECIFIED, | |
4088 | + FPM_PCTL_STATE_NORMAL, | |
4089 | + FPM_PCTL_STATE_RELOADING, | |
4090 | + FPM_PCTL_STATE_TERMINATING, | |
4091 | + FPM_PCTL_STATE_FINISHING | |
4092 | +}; | |
4093 | + | |
4094 | +enum { | |
4095 | + FPM_PCTL_ACTION_SET, | |
4096 | + FPM_PCTL_ACTION_TIMEOUT, | |
4097 | + FPM_PCTL_ACTION_LAST_CHILD_EXITED | |
4098 | +}; | |
4099 | + | |
c6a6bfc9 ER |
4100 | +enum { |
4101 | + FPM_PCTL_TERM, | |
4102 | + FPM_PCTL_STOP, | |
4103 | + FPM_PCTL_CONT | |
4104 | +}; | |
fd1be940 ER |
4105 | + |
4106 | +#endif | |
4107 | + | |
8c0dac15 ER |
4108 | diff -Nru php-5.2.6.vanilla/sapi/cgi/fpm/fpm_request.c php-5.2.6.fpm/sapi/cgi/fpm/fpm_request.c |
4109 | --- php-5.2.6.vanilla/sapi/cgi/fpm/fpm_request.c 1970-01-01 03:00:00.000000000 +0300 | |
4110 | +++ php-5.2.6.fpm/sapi/cgi/fpm/fpm_request.c 2008-09-01 03:34:36.000000000 +0400 | |
c6a6bfc9 | 4111 | @@ -0,0 +1,163 @@ |
fd1be940 ER |
4112 | + |
4113 | + /* $Id$ */ | |
c6a6bfc9 ER |
4114 | + /* (c) 2007,2008 Andrei Nigmatulin */ |
4115 | + | |
4116 | +#include "fpm_config.h" | |
4117 | + | |
4118 | +#include "fpm_php.h" | |
4119 | +#include "fpm_str.h" | |
4120 | +#include "fpm_clock.h" | |
4121 | +#include "fpm_conf.h" | |
4122 | +#include "fpm_trace.h" | |
4123 | +#include "fpm_php_trace.h" | |
4124 | +#include "fpm_process_ctl.h" | |
4125 | +#include "fpm_children.h" | |
4126 | +#include "fpm_shm_slots.h" | |
4127 | +#include "fpm_request.h" | |
fd1be940 | 4128 | + |
c6a6bfc9 ER |
4129 | +#include "zlog.h" |
4130 | + | |
4131 | +void fpm_request_accepting() | |
4132 | +{ | |
4133 | + struct fpm_shm_slot_s *slot; | |
4134 | + | |
4135 | + slot = fpm_shm_slots_acquire(0, 0); | |
4136 | + | |
4137 | + slot->request_stage = FPM_REQUEST_ACCEPTING; | |
4138 | + | |
4139 | + fpm_clock_get(&slot->tv); | |
4140 | + memset(slot->request_method, 0, sizeof(slot->request_method)); | |
4141 | + slot->content_length = 0; | |
4142 | + memset(slot->script_filename, 0, sizeof(slot->script_filename)); | |
4143 | + | |
4144 | + fpm_shm_slots_release(slot); | |
4145 | +} | |
4146 | + | |
4147 | +void fpm_request_reading_headers() | |
4148 | +{ | |
4149 | + struct fpm_shm_slot_s *slot; | |
4150 | + | |
4151 | + slot = fpm_shm_slots_acquire(0, 0); | |
4152 | + | |
4153 | + slot->request_stage = FPM_REQUEST_READING_HEADERS; | |
4154 | + | |
4155 | + fpm_clock_get(&slot->tv); | |
4156 | + slot->accepted = slot->tv; | |
4157 | + | |
4158 | + fpm_shm_slots_release(slot); | |
4159 | +} | |
4160 | + | |
4161 | +void fpm_request_info() | |
4162 | +{ | |
4163 | + struct fpm_shm_slot_s *slot; | |
4164 | + char *request_method = fpm_php_request_method(); | |
4165 | + char *script_filename = fpm_php_script_filename(); | |
4166 | + | |
4167 | + slot = fpm_shm_slots_acquire(0, 0); | |
4168 | + | |
4169 | + slot->request_stage = FPM_REQUEST_INFO; | |
4170 | + | |
4171 | + fpm_clock_get(&slot->tv); | |
4172 | + | |
4173 | + if (request_method) { | |
4174 | + cpystrn(slot->request_method, request_method, sizeof(slot->request_method)); | |
4175 | + } | |
4176 | + | |
4177 | + slot->content_length = fpm_php_content_length(); | |
4178 | + | |
4179 | + /* if cgi.fix_pathinfo is set to "1" and script cannot be found (404) | |
4180 | + the sapi_globals.request_info.path_translated is set to NULL */ | |
4181 | + if (script_filename) { | |
4182 | + cpystrn(slot->script_filename, script_filename, sizeof(slot->script_filename)); | |
4183 | + } | |
4184 | + | |
4185 | + fpm_shm_slots_release(slot); | |
4186 | +} | |
4187 | + | |
4188 | +void fpm_request_executing() | |
4189 | +{ | |
4190 | + struct fpm_shm_slot_s *slot; | |
4191 | + | |
4192 | + slot = fpm_shm_slots_acquire(0, 0); | |
4193 | + | |
4194 | + slot->request_stage = FPM_REQUEST_EXECUTING; | |
4195 | + | |
4196 | + fpm_clock_get(&slot->tv); | |
4197 | + | |
4198 | + fpm_shm_slots_release(slot); | |
4199 | +} | |
4200 | + | |
4201 | +void fpm_request_finished() | |
4202 | +{ | |
4203 | + struct fpm_shm_slot_s *slot; | |
4204 | + | |
4205 | + slot = fpm_shm_slots_acquire(0, 0); | |
4206 | + | |
4207 | + slot->request_stage = FPM_REQUEST_FINISHED; | |
4208 | + | |
4209 | + fpm_clock_get(&slot->tv); | |
4210 | + memset(&slot->accepted, 0, sizeof(slot->accepted)); | |
4211 | + | |
4212 | + fpm_shm_slots_release(slot); | |
4213 | +} | |
4214 | + | |
4215 | +void fpm_request_check_timed_out(struct fpm_child_s *child, struct timeval *now, int terminate_timeout, int slowlog_timeout) | |
4216 | +{ | |
4217 | + struct fpm_shm_slot_s *slot; | |
4218 | + struct fpm_shm_slot_s slot_c; | |
4219 | + | |
4220 | + slot = fpm_shm_slot(child); | |
4221 | + | |
4222 | + if (!fpm_shm_slots_acquire(slot, 1)) { | |
4223 | + return; | |
4224 | + } | |
4225 | + | |
4226 | + slot_c = *slot; | |
4227 | + | |
4228 | + fpm_shm_slots_release(slot); | |
4229 | + | |
4230 | +#if HAVE_FPM_TRACE | |
4231 | + if (child->slow_logged.tv_sec) { | |
4232 | + if (child->slow_logged.tv_sec != slot_c.accepted.tv_sec || child->slow_logged.tv_usec != slot_c.accepted.tv_usec) { | |
4233 | + child->slow_logged.tv_sec = 0; | |
4234 | + child->slow_logged.tv_usec = 0; | |
4235 | + } | |
4236 | + } | |
4237 | +#endif | |
4238 | + | |
4239 | + if (slot_c.request_stage > FPM_REQUEST_ACCEPTING && slot_c.request_stage < FPM_REQUEST_FINISHED) { | |
4240 | + char purified_script_filename[sizeof(slot_c.script_filename)]; | |
4241 | + struct timeval tv; | |
4242 | + | |
4243 | + timersub(now, &slot_c.accepted, &tv); | |
4244 | + | |
4245 | +#if HAVE_FPM_TRACE | |
4246 | + if (child->slow_logged.tv_sec == 0 && slowlog_timeout && | |
4247 | + slot_c.request_stage == FPM_REQUEST_EXECUTING && tv.tv_sec >= slowlog_timeout) { | |
4248 | + | |
4249 | + str_purify_filename(purified_script_filename, slot_c.script_filename, sizeof(slot_c.script_filename)); | |
4250 | + | |
4251 | + child->slow_logged = slot_c.accepted; | |
4252 | + child->tracer = fpm_php_trace; | |
4253 | + | |
4254 | + fpm_trace_signal(child->pid); | |
4255 | + | |
4256 | + zlog(ZLOG_STUFF, ZLOG_WARNING, "child %d, script '%s' (pool %s) executing too slow (%d.%06d sec), logging", | |
4257 | + (int) child->pid, purified_script_filename, child->wp->config->name, (int) tv.tv_sec, (int) tv.tv_usec); | |
4258 | + } | |
4259 | + | |
4260 | + else | |
4261 | +#endif | |
4262 | + if (terminate_timeout && tv.tv_sec >= terminate_timeout) { | |
4263 | + | |
4264 | + str_purify_filename(purified_script_filename, slot_c.script_filename, sizeof(slot_c.script_filename)); | |
4265 | + | |
4266 | + fpm_pctl_kill(child->pid, FPM_PCTL_TERM); | |
4267 | + | |
4268 | + zlog(ZLOG_STUFF, ZLOG_WARNING, "child %d, script '%s' (pool %s) execution timed out (%d.%06d sec), terminating", | |
4269 | + (int) child->pid, purified_script_filename, child->wp->config->name, (int) tv.tv_sec, (int) tv.tv_usec); | |
4270 | + } | |
4271 | + } | |
4272 | + | |
4273 | +} | |
4274 | + | |
8c0dac15 ER |
4275 | diff -Nru php-5.2.6.vanilla/sapi/cgi/fpm/fpm_request.h php-5.2.6.fpm/sapi/cgi/fpm/fpm_request.h |
4276 | --- php-5.2.6.vanilla/sapi/cgi/fpm/fpm_request.h 1970-01-01 03:00:00.000000000 +0300 | |
4277 | +++ php-5.2.6.fpm/sapi/cgi/fpm/fpm_request.h 2008-07-20 05:47:16.000000000 +0400 | |
c6a6bfc9 | 4278 | @@ -0,0 +1,27 @@ |
fd1be940 ER |
4279 | + |
4280 | + /* $Id$ */ | |
c6a6bfc9 ER |
4281 | + /* (c) 2007,2008 Andrei Nigmatulin */ |
4282 | + | |
4283 | +#ifndef FPM_REQUEST_H | |
4284 | +#define FPM_REQUEST_H 1 | |
4285 | + | |
4286 | +void fpm_request_accepting(); /* hanging in accept() */ | |
4287 | +void fpm_request_reading_headers(); /* start reading fastcgi request from very first byte */ | |
4288 | +void fpm_request_info(); /* not a stage really but a point in the php code, where all request params have become known to sapi */ | |
4289 | +void fpm_request_executing(); /* the script is executing */ | |
4290 | +void fpm_request_finished(); /* request processed: script response have been sent to web server */ | |
4291 | + | |
4292 | +struct fpm_child_s; | |
4293 | +struct timeval; | |
4294 | + | |
4295 | +void fpm_request_check_timed_out(struct fpm_child_s *child, struct timeval *tv, int terminate_timeout, int slowlog_timeout); | |
4296 | + | |
4297 | +enum fpm_request_stage_e { | |
4298 | + FPM_REQUEST_ACCEPTING = 1, | |
4299 | + FPM_REQUEST_READING_HEADERS, | |
4300 | + FPM_REQUEST_INFO, | |
4301 | + FPM_REQUEST_EXECUTING, | |
4302 | + FPM_REQUEST_FINISHED | |
4303 | +}; | |
4304 | + | |
4305 | +#endif | |
8c0dac15 ER |
4306 | diff -Nru php-5.2.6.vanilla/sapi/cgi/fpm/fpm_shm.c php-5.2.6.fpm/sapi/cgi/fpm/fpm_shm.c |
4307 | --- php-5.2.6.vanilla/sapi/cgi/fpm/fpm_shm.c 1970-01-01 03:00:00.000000000 +0300 | |
4308 | +++ php-5.2.6.fpm/sapi/cgi/fpm/fpm_shm.c 2008-05-24 21:38:47.000000000 +0400 | |
c6a6bfc9 ER |
4309 | @@ -0,0 +1,100 @@ |
4310 | + | |
4311 | + /* $Id$ */ | |
4312 | + /* (c) 2007,2008 Andrei Nigmatulin */ | |
4313 | + | |
4314 | +#include "fpm_config.h" | |
4315 | + | |
4316 | +#include <unistd.h> | |
4317 | +#include <sys/mman.h> | |
4318 | +#include <stdlib.h> | |
4319 | + | |
4320 | +#include "fpm_shm.h" | |
4321 | +#include "zlog.h" | |
4322 | + | |
4323 | + | |
4324 | +/* MAP_ANON is depricated, but not in macosx */ | |
4325 | +#if defined(MAP_ANON) && !defined(MAP_ANONYMOUS) | |
4326 | +#define MAP_ANONYMOUS MAP_ANON | |
4327 | +#endif | |
4328 | + | |
4329 | + | |
4330 | +struct fpm_shm_s *fpm_shm_alloc(size_t sz) | |
4331 | +{ | |
4332 | + struct fpm_shm_s *shm; | |
4333 | + | |
4334 | + shm = malloc(sizeof(*shm)); | |
4335 | + | |
4336 | + if (!shm) { | |
4337 | + return 0; | |
4338 | + } | |
4339 | + | |
4340 | + shm->mem = mmap(0, sz, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED, -1, 0); | |
4341 | + | |
4342 | + if (!shm->mem) { | |
4343 | + zlog(ZLOG_STUFF, ZLOG_SYSERROR, "mmap(MAP_ANONYMOUS | MAP_SHARED) failed"); | |
4344 | + free(shm); | |
4345 | + return 0; | |
4346 | + } | |
4347 | + | |
4348 | + shm->used = 0; | |
4349 | + shm->sz = sz; | |
4350 | + | |
4351 | + return shm; | |
4352 | +} | |
4353 | + | |
4354 | +static void fpm_shm_free(struct fpm_shm_s *shm, int do_unmap) | |
4355 | +{ | |
4356 | + if (do_unmap) { | |
4357 | + munmap(shm->mem, shm->sz); | |
4358 | + } | |
4359 | + | |
4360 | + free(shm); | |
4361 | +} | |
4362 | + | |
4363 | +void fpm_shm_free_list(struct fpm_shm_s *shm, void *mem) | |
4364 | +{ | |
4365 | + struct fpm_shm_s *next; | |
4366 | + | |
4367 | + for (; shm; shm = next) { | |
4368 | + next = shm->next; | |
4369 | + | |
4370 | + fpm_shm_free(shm, mem != shm->mem); | |
4371 | + } | |
4372 | +} | |
4373 | + | |
4374 | +void *fpm_shm_alloc_chunk(struct fpm_shm_s **head, size_t sz, void **mem) | |
4375 | +{ | |
4376 | + size_t pagesize = getpagesize(); | |
4377 | + static const size_t cache_line_size = 16; | |
4378 | + size_t aligned_sz; | |
4379 | + struct fpm_shm_s *shm; | |
4380 | + void *ret; | |
4381 | + | |
4382 | + sz = (sz + cache_line_size - 1) & -cache_line_size; | |
4383 | + | |
4384 | + shm = *head; | |
4385 | + | |
4386 | + if (0 == shm || shm->sz - shm->used < sz) { | |
4387 | + /* allocate one more shm segment */ | |
4388 | + | |
4389 | + aligned_sz = (sz + pagesize - 1) & -pagesize; | |
4390 | + | |
4391 | + shm = fpm_shm_alloc(aligned_sz); | |
4392 | + | |
4393 | + if (!shm) { | |
4394 | + return 0; | |
4395 | + } | |
4396 | + | |
4397 | + shm->next = *head; | |
4398 | + if (shm->next) shm->next->prev = shm; | |
4399 | + shm->prev = 0; | |
4400 | + *head = shm; | |
4401 | + } | |
4402 | + | |
4403 | + *mem = shm->mem; | |
4404 | + ret = (char *) shm->mem + shm->used; | |
4405 | + shm->used += sz; | |
4406 | + | |
4407 | + return ret; | |
4408 | +} | |
4409 | + | |
8c0dac15 ER |
4410 | diff -Nru php-5.2.6.vanilla/sapi/cgi/fpm/fpm_shm.h php-5.2.6.fpm/sapi/cgi/fpm/fpm_shm.h |
4411 | --- php-5.2.6.vanilla/sapi/cgi/fpm/fpm_shm.h 1970-01-01 03:00:00.000000000 +0300 | |
4412 | +++ php-5.2.6.fpm/sapi/cgi/fpm/fpm_shm.h 2008-05-24 21:38:47.000000000 +0400 | |
c6a6bfc9 ER |
4413 | @@ -0,0 +1,22 @@ |
4414 | + | |
4415 | + /* $Id$ */ | |
4416 | + /* (c) 2007,2008 Andrei Nigmatulin */ | |
fd1be940 ER |
4417 | + |
4418 | +#ifndef FPM_SHM_H | |
4419 | +#define FPM_SHM_H 1 | |
4420 | + | |
c6a6bfc9 | 4421 | +struct fpm_shm_s; |
fd1be940 | 4422 | + |
c6a6bfc9 ER |
4423 | +struct fpm_shm_s { |
4424 | + struct fpm_shm_s *prev, *next; | |
4425 | + void *mem; | |
4426 | + size_t sz; | |
4427 | + size_t used; | |
4428 | +}; | |
4429 | + | |
4430 | +struct fpm_shm_s *fpm_shm_alloc(size_t sz); | |
4431 | +void fpm_shm_free_list(struct fpm_shm_s *, void *); | |
4432 | +void *fpm_shm_alloc_chunk(struct fpm_shm_s **head, size_t sz, void **mem); | |
fd1be940 ER |
4433 | + |
4434 | +#endif | |
4435 | + | |
8c0dac15 ER |
4436 | diff -Nru php-5.2.6.vanilla/sapi/cgi/fpm/fpm_shm_slots.c php-5.2.6.fpm/sapi/cgi/fpm/fpm_shm_slots.c |
4437 | --- php-5.2.6.vanilla/sapi/cgi/fpm/fpm_shm_slots.c 1970-01-01 03:00:00.000000000 +0300 | |
4438 | +++ php-5.2.6.fpm/sapi/cgi/fpm/fpm_shm_slots.c 2008-05-24 21:38:47.000000000 +0400 | |
c6a6bfc9 ER |
4439 | @@ -0,0 +1,127 @@ |
4440 | + | |
4441 | + /* $Id$ */ | |
4442 | + /* (c) 2007,2008 Andrei Nigmatulin */ | |
4443 | + | |
4444 | +#include "fpm_config.h" | |
4445 | + | |
4446 | +#include "fpm_atomic.h" | |
4447 | +#include "fpm_worker_pool.h" | |
4448 | +#include "fpm_children.h" | |
4449 | +#include "fpm_shm.h" | |
4450 | +#include "fpm_shm_slots.h" | |
4451 | +#include "zlog.h" | |
4452 | + | |
4453 | +static void *shm_mem; | |
4454 | +static struct fpm_shm_slot_s *shm_slot; | |
4455 | + | |
4456 | +int fpm_shm_slots_prepare_slot(struct fpm_child_s *child) | |
4457 | +{ | |
4458 | + struct fpm_worker_pool_s *wp = child->wp; | |
4459 | + struct fpm_shm_slot_ptr_s *shm_slot_ptr; | |
4460 | + | |
4461 | + child->shm_slot_i = wp->slots_used.used; | |
4462 | + | |
4463 | + shm_slot_ptr = fpm_array_push(&wp->slots_used); | |
4464 | + | |
4465 | + if (0 == shm_slot_ptr) { | |
4466 | + return -1; | |
4467 | + } | |
4468 | + | |
4469 | + if (0 == wp->slots_free.used) { | |
4470 | + shm_slot_ptr->shm_slot = fpm_shm_alloc_chunk(&wp->shm_list, sizeof(struct fpm_shm_slot_s), &shm_slot_ptr->mem); | |
4471 | + | |
4472 | + if (!shm_slot_ptr->shm_slot) { | |
4473 | + return -1; | |
4474 | + } | |
4475 | + } | |
4476 | + else { | |
4477 | + *shm_slot_ptr = *(struct fpm_shm_slot_ptr_s *) fpm_array_item_last(&wp->slots_free); | |
4478 | + | |
4479 | + --wp->slots_free.used; | |
4480 | + } | |
4481 | + | |
4482 | + memset(shm_slot_ptr->shm_slot, 0, sizeof(struct fpm_shm_slot_s)); | |
4483 | + | |
4484 | + shm_slot_ptr->child = child; | |
4485 | + | |
4486 | + return 0; | |
4487 | +} | |
4488 | + | |
4489 | +void fpm_shm_slots_discard_slot(struct fpm_child_s *child) | |
4490 | +{ | |
4491 | + struct fpm_shm_slot_ptr_s *shm_slot_ptr; | |
4492 | + struct fpm_worker_pool_s *wp = child->wp; | |
4493 | + int n; | |
4494 | + | |
4495 | + shm_slot_ptr = fpm_array_push(&wp->slots_free); | |
4496 | + | |
4497 | + if (shm_slot_ptr) { | |
4498 | + | |
4499 | + struct fpm_shm_slot_ptr_s *shm_slot_ptr_used; | |
4500 | + | |
4501 | + shm_slot_ptr_used = fpm_array_item(&wp->slots_used, child->shm_slot_i); | |
4502 | + | |
4503 | + *shm_slot_ptr = *shm_slot_ptr_used; | |
4504 | + | |
4505 | + shm_slot_ptr->child = 0; | |
4506 | + | |
4507 | + } | |
4508 | + | |
4509 | + n = fpm_array_item_remove(&wp->slots_used, child->shm_slot_i); | |
4510 | + | |
4511 | + if (n > -1) { | |
4512 | + shm_slot_ptr = fpm_array_item(&wp->slots_used, n); | |
4513 | + | |
4514 | + shm_slot_ptr->child->shm_slot_i = n; | |
4515 | + } | |
4516 | +} | |
4517 | + | |
4518 | +void fpm_shm_slots_child_use_slot(struct fpm_child_s *child) | |
4519 | +{ | |
4520 | + struct fpm_shm_slot_ptr_s *shm_slot_ptr; | |
4521 | + struct fpm_worker_pool_s *wp = child->wp; | |
4522 | + | |
4523 | + shm_slot_ptr = fpm_array_item(&wp->slots_used, child->shm_slot_i); | |
4524 | + | |
4525 | + shm_slot = shm_slot_ptr->shm_slot; | |
4526 | + shm_mem = shm_slot_ptr->mem; | |
4527 | +} | |
4528 | + | |
4529 | +void fpm_shm_slots_parent_use_slot(struct fpm_child_s *child) | |
4530 | +{ | |
4531 | + /* nothing to do */ | |
4532 | +} | |
4533 | + | |
4534 | +void *fpm_shm_slots_mem() | |
4535 | +{ | |
4536 | + return shm_mem; | |
4537 | +} | |
4538 | + | |
4539 | +struct fpm_shm_slot_s *fpm_shm_slot(struct fpm_child_s *child) | |
4540 | +{ | |
4541 | + struct fpm_shm_slot_ptr_s *shm_slot_ptr; | |
4542 | + struct fpm_worker_pool_s *wp = child->wp; | |
4543 | + | |
4544 | + shm_slot_ptr = fpm_array_item(&wp->slots_used, child->shm_slot_i); | |
4545 | + | |
4546 | + return shm_slot_ptr->shm_slot; | |
4547 | +} | |
4548 | + | |
4549 | +struct fpm_shm_slot_s *fpm_shm_slots_acquire(struct fpm_shm_slot_s *s, int nohang) | |
4550 | +{ | |
4551 | + if (s == 0) { | |
4552 | + s = shm_slot; | |
4553 | + } | |
4554 | + | |
4555 | + if (0 > fpm_spinlock(&s->lock, nohang)) { | |
4556 | + return 0; | |
4557 | + } | |
4558 | + | |
4559 | + return s; | |
4560 | +} | |
4561 | + | |
4562 | +void fpm_shm_slots_release(struct fpm_shm_slot_s *s) | |
4563 | +{ | |
4564 | + s->lock = 0; | |
4565 | +} | |
4566 | + | |
8c0dac15 ER |
4567 | diff -Nru php-5.2.6.vanilla/sapi/cgi/fpm/fpm_shm_slots.h php-5.2.6.fpm/sapi/cgi/fpm/fpm_shm_slots.h |
4568 | --- php-5.2.6.vanilla/sapi/cgi/fpm/fpm_shm_slots.h 1970-01-01 03:00:00.000000000 +0300 | |
4569 | +++ php-5.2.6.fpm/sapi/cgi/fpm/fpm_shm_slots.h 2008-05-24 21:38:47.000000000 +0400 | |
c6a6bfc9 | 4570 | @@ -0,0 +1,43 @@ |
fd1be940 ER |
4571 | + |
4572 | + /* $Id$ */ | |
c6a6bfc9 ER |
4573 | + /* (c) 2007,2008 Andrei Nigmatulin */ |
4574 | + | |
4575 | +#ifndef FPM_SHM_SLOTS_H | |
4576 | +#define FPM_SHM_SLOTS_H 1 | |
4577 | + | |
4578 | +#include "fpm_atomic.h" | |
4579 | +#include "fpm_worker_pool.h" | |
4580 | +#include "fpm_request.h" | |
4581 | + | |
4582 | +struct fpm_child_s; | |
4583 | + | |
4584 | +struct fpm_shm_slot_s { | |
4585 | + union { | |
4586 | + atomic_t lock; | |
4587 | + char dummy[16]; | |
4588 | + }; | |
4589 | + enum fpm_request_stage_e request_stage; | |
4590 | + struct timeval accepted; | |
4591 | + struct timeval tv; | |
4592 | + char request_method[16]; | |
4593 | + size_t content_length; /* used with POST only */ | |
4594 | + char script_filename[256]; | |
4595 | +}; | |
4596 | + | |
4597 | +struct fpm_shm_slot_ptr_s { | |
4598 | + void *mem; | |
4599 | + struct fpm_shm_slot_s *shm_slot; | |
4600 | + struct fpm_child_s *child; | |
4601 | +}; | |
4602 | + | |
4603 | +int fpm_shm_slots_prepare_slot(struct fpm_child_s *child); | |
4604 | +void fpm_shm_slots_discard_slot(struct fpm_child_s *child); | |
4605 | +void fpm_shm_slots_child_use_slot(struct fpm_child_s *child); | |
4606 | +void fpm_shm_slots_parent_use_slot(struct fpm_child_s *child); | |
4607 | +void *fpm_shm_slots_mem(); | |
4608 | +struct fpm_shm_slot_s *fpm_shm_slot(struct fpm_child_s *child); | |
4609 | +struct fpm_shm_slot_s *fpm_shm_slots_acquire(struct fpm_shm_slot_s *, int nohang); | |
4610 | +void fpm_shm_slots_release(struct fpm_shm_slot_s *); | |
4611 | + | |
4612 | +#endif | |
4613 | + | |
8c0dac15 ER |
4614 | diff -Nru php-5.2.6.vanilla/sapi/cgi/fpm/fpm_signals.c php-5.2.6.fpm/sapi/cgi/fpm/fpm_signals.c |
4615 | --- php-5.2.6.vanilla/sapi/cgi/fpm/fpm_signals.c 1970-01-01 03:00:00.000000000 +0300 | |
4616 | +++ php-5.2.6.fpm/sapi/cgi/fpm/fpm_signals.c 2008-08-26 19:09:15.000000000 +0400 | |
c6a6bfc9 ER |
4617 | @@ -0,0 +1,252 @@ |
4618 | + | |
4619 | + /* $Id$ */ | |
4620 | + /* (c) 2007,2008 Andrei Nigmatulin */ | |
fd1be940 ER |
4621 | + |
4622 | +#include "fpm_config.h" | |
4623 | + | |
4624 | +#include <signal.h> | |
4625 | +#include <stdio.h> | |
4626 | +#include <sys/types.h> | |
4627 | +#include <sys/socket.h> | |
4628 | +#include <stdlib.h> | |
4629 | +#include <string.h> | |
4630 | +#include <fcntl.h> | |
4631 | +#include <unistd.h> | |
4632 | +#include <errno.h> | |
4633 | + | |
c6a6bfc9 | 4634 | +#include "fpm.h" |
fd1be940 ER |
4635 | +#include "fpm_signals.h" |
4636 | +#include "fpm_sockets.h" | |
c6a6bfc9 | 4637 | +#include "fpm_php.h" |
fd1be940 ER |
4638 | +#include "zlog.h" |
4639 | + | |
4640 | +static int sp[2]; | |
4641 | + | |
fd1be940 ER |
4642 | +const char *fpm_signal_names[NSIG + 1] = { |
4643 | +#ifdef SIGHUP | |
4644 | + [SIGHUP] = "SIGHUP", | |
4645 | +#endif | |
4646 | +#ifdef SIGINT | |
4647 | + [SIGINT] = "SIGINT", | |
4648 | +#endif | |
4649 | +#ifdef SIGQUIT | |
4650 | + [SIGQUIT] = "SIGQUIT", | |
4651 | +#endif | |
4652 | +#ifdef SIGILL | |
4653 | + [SIGILL] = "SIGILL", | |
4654 | +#endif | |
4655 | +#ifdef SIGTRAP | |
4656 | + [SIGTRAP] = "SIGTRAP", | |
4657 | +#endif | |
4658 | +#ifdef SIGABRT | |
4659 | + [SIGABRT] = "SIGABRT", | |
4660 | +#endif | |
4661 | +#ifdef SIGEMT | |
4662 | + [SIGEMT] = "SIGEMT", | |
4663 | +#endif | |
4664 | +#ifdef SIGBUS | |
4665 | + [SIGBUS] = "SIGBUS", | |
4666 | +#endif | |
4667 | +#ifdef SIGFPE | |
4668 | + [SIGFPE] = "SIGFPE", | |
4669 | +#endif | |
4670 | +#ifdef SIGKILL | |
4671 | + [SIGKILL] = "SIGKILL", | |
4672 | +#endif | |
4673 | +#ifdef SIGUSR1 | |
4674 | + [SIGUSR1] = "SIGUSR1", | |
4675 | +#endif | |
4676 | +#ifdef SIGSEGV | |
4677 | + [SIGSEGV] = "SIGSEGV", | |
4678 | +#endif | |
4679 | +#ifdef SIGUSR2 | |
4680 | + [SIGUSR2] = "SIGUSR2", | |
4681 | +#endif | |
4682 | +#ifdef SIGPIPE | |
4683 | + [SIGPIPE] = "SIGPIPE", | |
4684 | +#endif | |
4685 | +#ifdef SIGALRM | |
4686 | + [SIGALRM] = "SIGALRM", | |
4687 | +#endif | |
4688 | +#ifdef SIGTERM | |
4689 | + [SIGTERM] = "SIGTERM", | |
4690 | +#endif | |
4691 | +#ifdef SIGCHLD | |
4692 | + [SIGCHLD] = "SIGCHLD", | |
4693 | +#endif | |
4694 | +#ifdef SIGCONT | |
4695 | + [SIGCONT] = "SIGCONT", | |
4696 | +#endif | |
4697 | +#ifdef SIGSTOP | |
4698 | + [SIGSTOP] = "SIGSTOP", | |
4699 | +#endif | |
4700 | +#ifdef SIGTSTP | |
4701 | + [SIGTSTP] = "SIGTSTP", | |
4702 | +#endif | |
4703 | +#ifdef SIGTTIN | |
4704 | + [SIGTTIN] = "SIGTTIN", | |
4705 | +#endif | |
4706 | +#ifdef SIGTTOU | |
4707 | + [SIGTTOU] = "SIGTTOU", | |
4708 | +#endif | |
4709 | +#ifdef SIGURG | |
4710 | + [SIGURG] = "SIGURG", | |
4711 | +#endif | |
4712 | +#ifdef SIGXCPU | |
4713 | + [SIGXCPU] = "SIGXCPU", | |
4714 | +#endif | |
4715 | +#ifdef SIGXFSZ | |
4716 | + [SIGXFSZ] = "SIGXFSZ", | |
4717 | +#endif | |
4718 | +#ifdef SIGVTALRM | |
4719 | + [SIGVTALRM] = "SIGVTALRM", | |
4720 | +#endif | |
4721 | +#ifdef SIGPROF | |
4722 | + [SIGPROF] = "SIGPROF", | |
4723 | +#endif | |
4724 | +#ifdef SIGWINCH | |
4725 | + [SIGWINCH] = "SIGWINCH", | |
4726 | +#endif | |
4727 | +#ifdef SIGINFO | |
4728 | + [SIGINFO] = "SIGINFO", | |
4729 | +#endif | |
4730 | +#ifdef SIGIO | |
4731 | + [SIGIO] = "SIGIO", | |
4732 | +#endif | |
4733 | +#ifdef SIGPWR | |
4734 | + [SIGPWR] = "SIGPWR", | |
4735 | +#endif | |
4736 | +#ifdef SIGSYS | |
4737 | + [SIGSYS] = "SIGSYS", | |
4738 | +#endif | |
4739 | +#ifdef SIGWAITING | |
4740 | + [SIGWAITING] = "SIGWAITING", | |
4741 | +#endif | |
4742 | +#ifdef SIGLWP | |
4743 | + [SIGLWP] = "SIGLWP", | |
4744 | +#endif | |
4745 | +#ifdef SIGFREEZE | |
4746 | + [SIGFREEZE] = "SIGFREEZE", | |
4747 | +#endif | |
4748 | +#ifdef SIGTHAW | |
4749 | + [SIGTHAW] = "SIGTHAW", | |
4750 | +#endif | |
4751 | +#ifdef SIGCANCEL | |
4752 | + [SIGCANCEL] = "SIGCANCEL", | |
4753 | +#endif | |
4754 | +#ifdef SIGLOST | |
4755 | + [SIGLOST] = "SIGLOST", | |
4756 | +#endif | |
4757 | +}; | |
4758 | + | |
4759 | +static void sig_soft_quit(int signo) | |
4760 | +{ | |
c6a6bfc9 ER |
4761 | + int saved_errno = errno; |
4762 | + | |
fd1be940 ER |
4763 | + /* closing fastcgi listening socket will force fcgi_accept() exit immediately */ |
4764 | + close(0); | |
4765 | + socket(AF_UNIX, SOCK_STREAM, 0); | |
c6a6bfc9 ER |
4766 | + |
4767 | + fpm_php_soft_quit(); | |
4768 | + | |
4769 | + errno = saved_errno; | |
fd1be940 ER |
4770 | +} |
4771 | + | |
4772 | +static void sig_handler(int signo) | |
4773 | +{ | |
c6a6bfc9 | 4774 | + static const char sig_chars[NSIG + 1] = { |
fd1be940 ER |
4775 | + [SIGTERM] = 'T', |
4776 | + [SIGINT] = 'I', | |
c6a6bfc9 | 4777 | + [SIGUSR1] = '1', |
fd1be940 ER |
4778 | + [SIGUSR2] = '2', |
4779 | + [SIGQUIT] = 'Q', | |
4780 | + [SIGCHLD] = 'C' | |
4781 | + }; | |
c6a6bfc9 ER |
4782 | + char s; |
4783 | + int saved_errno; | |
fd1be940 | 4784 | + |
c6a6bfc9 ER |
4785 | + if (fpm_globals.parent_pid != getpid()) { |
4786 | + /* prevent a signal race condition when child process | |
4787 | + have not set up it's own signal handler yet */ | |
4788 | + return; | |
fd1be940 ER |
4789 | + } |
4790 | + | |
c6a6bfc9 ER |
4791 | + saved_errno = errno; |
4792 | + | |
4793 | + s = sig_chars[signo]; | |
4794 | + | |
4795 | + write(sp[1], &s, sizeof(s)); | |
4796 | + | |
fd1be940 ER |
4797 | + errno = saved_errno; |
4798 | +} | |
4799 | + | |
4800 | +int fpm_signals_init_main() | |
4801 | +{ | |
4802 | + struct sigaction act; | |
4803 | + | |
4804 | + if (0 > socketpair(AF_UNIX, SOCK_STREAM, 0, sp)) { | |
4805 | + zlog(ZLOG_STUFF, ZLOG_SYSERROR, "socketpair() failed"); | |
4806 | + return -1; | |
4807 | + } | |
4808 | + | |
4809 | + if (0 > fd_set_blocked(sp[0], 0) || 0 > fd_set_blocked(sp[1], 0)) { | |
4810 | + zlog(ZLOG_STUFF, ZLOG_SYSERROR, "fd_set_blocked() failed"); | |
4811 | + return -1; | |
4812 | + } | |
4813 | + | |
4814 | + if (0 > fcntl(sp[0], F_SETFD, FD_CLOEXEC) || 0 > fcntl(sp[1], F_SETFD, FD_CLOEXEC)) { | |
4815 | + zlog(ZLOG_STUFF, ZLOG_SYSERROR, "fcntl(F_SETFD, FD_CLOEXEC) failed"); | |
4816 | + return -1; | |
4817 | + } | |
4818 | + | |
4819 | + memset(&act, 0, sizeof(act)); | |
c6a6bfc9 | 4820 | + act.sa_handler = sig_handler; |
fd1be940 ER |
4821 | + sigfillset(&act.sa_mask); |
4822 | + | |
4823 | + if (0 > sigaction(SIGTERM, &act, 0) || | |
4824 | + 0 > sigaction(SIGINT, &act, 0) || | |
c6a6bfc9 | 4825 | + 0 > sigaction(SIGUSR1, &act, 0) || |
fd1be940 ER |
4826 | + 0 > sigaction(SIGUSR2, &act, 0) || |
4827 | + 0 > sigaction(SIGCHLD, &act, 0) || | |
4828 | + 0 > sigaction(SIGQUIT, &act, 0)) { | |
4829 | + | |
4830 | + zlog(ZLOG_STUFF, ZLOG_SYSERROR, "sigaction() failed"); | |
4831 | + return -1; | |
4832 | + } | |
4833 | + | |
4834 | + return 0; | |
4835 | +} | |
4836 | + | |
4837 | +int fpm_signals_init_child() | |
4838 | +{ | |
4839 | + struct sigaction act, act_dfl; | |
4840 | + | |
4841 | + memset(&act, 0, sizeof(act)); | |
4842 | + memset(&act_dfl, 0, sizeof(act_dfl)); | |
4843 | + | |
c6a6bfc9 | 4844 | + act.sa_handler = &sig_soft_quit; |
fd1be940 ER |
4845 | + act.sa_flags |= SA_RESTART; |
4846 | + | |
4847 | + act_dfl.sa_handler = SIG_DFL; | |
4848 | + | |
4849 | + close(sp[0]); | |
4850 | + close(sp[1]); | |
4851 | + | |
4852 | + if (0 > sigaction(SIGTERM, &act_dfl, 0) || | |
4853 | + 0 > sigaction(SIGINT, &act_dfl, 0) || | |
c6a6bfc9 | 4854 | + 0 > sigaction(SIGUSR1, &act_dfl, 0) || |
fd1be940 ER |
4855 | + 0 > sigaction(SIGUSR2, &act_dfl, 0) || |
4856 | + 0 > sigaction(SIGCHLD, &act_dfl, 0) || | |
4857 | + 0 > sigaction(SIGQUIT, &act, 0)) { | |
4858 | + | |
4859 | + zlog(ZLOG_STUFF, ZLOG_SYSERROR, "sigaction() failed"); | |
4860 | + return -1; | |
4861 | + } | |
4862 | + | |
4863 | + return 0; | |
4864 | +} | |
4865 | + | |
4866 | +int fpm_signals_get_fd() | |
4867 | +{ | |
4868 | + return sp[0]; | |
4869 | +} | |
8c0dac15 ER |
4870 | diff -Nru php-5.2.6.vanilla/sapi/cgi/fpm/fpm_signals.h php-5.2.6.fpm/sapi/cgi/fpm/fpm_signals.h |
4871 | --- php-5.2.6.vanilla/sapi/cgi/fpm/fpm_signals.h 1970-01-01 03:00:00.000000000 +0300 | |
4872 | +++ php-5.2.6.fpm/sapi/cgi/fpm/fpm_signals.h 2008-05-24 21:38:47.000000000 +0400 | |
fd1be940 ER |
4873 | @@ -0,0 +1,16 @@ |
4874 | + | |
4875 | + /* $Id$ */ | |
c6a6bfc9 | 4876 | + /* (c) 2007,2008 Andrei Nigmatulin */ |
fd1be940 ER |
4877 | + |
4878 | +#ifndef FPM_SIGNALS_H | |
4879 | +#define FPM_SIGNALS_H 1 | |
4880 | + | |
4881 | +#include <signal.h> | |
4882 | + | |
4883 | +int fpm_signals_init_main(); | |
4884 | +int fpm_signals_init_child(); | |
4885 | +int fpm_signals_get_fd(); | |
4886 | + | |
4887 | +extern const char *fpm_signal_names[NSIG + 1]; | |
4888 | + | |
4889 | +#endif | |
8c0dac15 ER |
4890 | diff -Nru php-5.2.6.vanilla/sapi/cgi/fpm/fpm_sockets.c php-5.2.6.fpm/sapi/cgi/fpm/fpm_sockets.c |
4891 | --- php-5.2.6.vanilla/sapi/cgi/fpm/fpm_sockets.c 1970-01-01 03:00:00.000000000 +0300 | |
4892 | +++ php-5.2.6.fpm/sapi/cgi/fpm/fpm_sockets.c 2008-08-26 19:09:15.000000000 +0400 | |
c6a6bfc9 | 4893 | @@ -0,0 +1,425 @@ |
fd1be940 ER |
4894 | + |
4895 | + /* $Id$ */ | |
c6a6bfc9 | 4896 | + /* (c) 2007,2008 Andrei Nigmatulin */ |
fd1be940 ER |
4897 | + |
4898 | +#include "fpm_config.h" | |
4899 | + | |
4900 | +#ifdef HAVE_ALLOCA_H | |
4901 | +#include <alloca.h> | |
4902 | +#endif | |
4903 | +#include <sys/types.h> | |
4904 | +#include <sys/stat.h> /* for chmod(2) */ | |
4905 | +#include <sys/socket.h> | |
4906 | +#include <netinet/in.h> | |
4907 | +#include <arpa/inet.h> | |
4908 | +#include <sys/un.h> | |
4909 | +#include <netdb.h> | |
4910 | +#include <stdio.h> | |
4911 | +#include <stdlib.h> | |
4912 | +#include <string.h> | |
4913 | +#include <errno.h> | |
4914 | +#include <unistd.h> | |
4915 | + | |
4916 | +#include "zlog.h" | |
c6a6bfc9 | 4917 | +#include "fpm_arrays.h" |
fd1be940 ER |
4918 | +#include "fpm_sockets.h" |
4919 | +#include "fpm_worker_pool.h" | |
4920 | +#include "fpm_unix.h" | |
c6a6bfc9 | 4921 | +#include "fpm_str.h" |
fd1be940 ER |
4922 | +#include "fpm_env.h" |
4923 | +#include "fpm_cleanup.h" | |
4924 | + | |
c6a6bfc9 | 4925 | +struct listening_socket_s { |
fd1be940 ER |
4926 | + int refcount; |
4927 | + int sock; | |
4928 | + int type; | |
4929 | + char *key; | |
4930 | +}; | |
4931 | + | |
c6a6bfc9 | 4932 | +static struct fpm_array_s sockets_list; |
fd1be940 ER |
4933 | + |
4934 | +static int fpm_sockets_resolve_af_inet(char *node, char *service, struct sockaddr_in *addr) | |
4935 | +{ | |
4936 | + struct addrinfo *res; | |
4937 | + struct addrinfo hints; | |
4938 | + int ret; | |
4939 | + | |
4940 | + memset(&hints, 0, sizeof(hints)); | |
4941 | + | |
4942 | + hints.ai_family = AF_INET; | |
4943 | + | |
4944 | + ret = getaddrinfo(node, service, &hints, &res); | |
4945 | + | |
4946 | + if (ret != 0) { | |
4947 | + zlog(ZLOG_STUFF, ZLOG_ERROR, "can't resolve hostname '%s%s%s': getaddrinfo said: %s%s%s\n", | |
4948 | + node, service ? ":" : "", service ? service : "", | |
4949 | + gai_strerror(ret), ret == EAI_SYSTEM ? ", system error: " : "", ret == EAI_SYSTEM ? strerror(errno) : ""); | |
4950 | + return -1; | |
4951 | + } | |
4952 | + | |
4953 | + *addr = *(struct sockaddr_in *) res->ai_addr; | |
4954 | + | |
4955 | + freeaddrinfo(res); | |
4956 | + | |
4957 | + return 0; | |
4958 | +} | |
4959 | + | |
4960 | +enum { FPM_GET_USE_SOCKET = 1, FPM_STORE_SOCKET = 2, FPM_STORE_USE_SOCKET = 3 }; | |
4961 | + | |
4962 | +static void fpm_sockets_cleanup(int which, void *arg) | |
4963 | +{ | |
4964 | + int i; | |
4965 | + char *env_value = 0; | |
4966 | + int p = 0; | |
c6a6bfc9 | 4967 | + struct listening_socket_s *ls = sockets_list.data; |
fd1be940 | 4968 | + |
c6a6bfc9 | 4969 | + for (i = 0; i < sockets_list.used; i++, ls++) { |
fd1be940 ER |
4970 | + |
4971 | + if (which != FPM_CLEANUP_PARENT_EXEC) { | |
4972 | + | |
4973 | + close(ls->sock); | |
4974 | + | |
4975 | + } | |
4976 | + else { /* on PARENT EXEC we want socket fds to be inherited through environment variable */ | |
4977 | + char fd[32]; | |
4978 | + sprintf(fd, "%d", ls->sock); | |
4979 | + env_value = realloc(env_value, p + (p ? 1 : 0) + strlen(ls->key) + 1 + strlen(fd) + 1); | |
4980 | + p += sprintf(env_value + p, "%s%s=%s", p ? "," : "", ls->key, fd); | |
4981 | + } | |
4982 | + | |
4983 | + if (which == FPM_CLEANUP_PARENT_EXIT_MAIN) { | |
4984 | + | |
4985 | + if (ls->type == FPM_AF_UNIX) { | |
4986 | + unlink(ls->key); | |
4987 | + } | |
4988 | + | |
4989 | + } | |
4990 | + | |
4991 | + free(ls->key); | |
4992 | + } | |
4993 | + | |
4994 | + if (env_value) { | |
4995 | + setenv("FPM_SOCKETS", env_value, 1); | |
c6a6bfc9 | 4996 | + free(env_value); |
fd1be940 ER |
4997 | + } |
4998 | + | |
c6a6bfc9 | 4999 | + fpm_array_free(&sockets_list); |
fd1be940 ER |
5000 | +} |
5001 | + | |
5002 | +static int fpm_sockets_hash_op(int sock, struct sockaddr *sa, char *key, int type, int op) | |
5003 | +{ | |
5004 | + | |
5005 | + if (key == NULL) { | |
5006 | + | |
5007 | + switch (type) { | |
5008 | + | |
5009 | + case FPM_AF_INET : { | |
5010 | + struct sockaddr_in *sa_in = (struct sockaddr_in *) sa; | |
5011 | + | |
5012 | + key = alloca(sizeof("xxx.xxx.xxx.xxx:ppppp")); | |
5013 | + | |
c6a6bfc9 | 5014 | + sprintf(key, "%u.%u.%u.%u:%u", IPQUAD(&sa_in->sin_addr), (unsigned int) ntohs(sa_in->sin_port)); |
fd1be940 ER |
5015 | + |
5016 | + break; | |
5017 | + } | |
5018 | + | |
5019 | + case FPM_AF_UNIX : { | |
5020 | + struct sockaddr_un *sa_un = (struct sockaddr_un *) sa; | |
5021 | + | |
5022 | + key = alloca(strlen(sa_un->sun_path) + 1); | |
5023 | + | |
5024 | + strcpy(key, sa_un->sun_path); | |
5025 | + | |
5026 | + break; | |
5027 | + } | |
5028 | + | |
5029 | + default : | |
5030 | + | |
5031 | + return -1; | |
5032 | + } | |
5033 | + | |
5034 | + } | |
5035 | + | |
5036 | + switch (op) { | |
5037 | + | |
5038 | + case FPM_GET_USE_SOCKET : | |
5039 | + { | |
5040 | + | |
5041 | + int i; | |
c6a6bfc9 | 5042 | + struct listening_socket_s *ls = sockets_list.data; |
fd1be940 | 5043 | + |
c6a6bfc9 | 5044 | + for (i = 0; i < sockets_list.used; i++, ls++) { |
fd1be940 ER |
5045 | + |
5046 | + if (!strcmp(ls->key, key)) { | |
5047 | + ++ls->refcount; | |
5048 | + return ls->sock; | |
5049 | + } | |
5050 | + } | |
5051 | + | |
5052 | + break; | |
5053 | + } | |
5054 | + | |
5055 | + case FPM_STORE_SOCKET : /* inherited socket */ | |
5056 | + case FPM_STORE_USE_SOCKET : /* just created */ | |
5057 | + { | |
5058 | + | |
c6a6bfc9 | 5059 | + struct listening_socket_s *ls; |
fd1be940 | 5060 | + |
c6a6bfc9 | 5061 | + ls = fpm_array_push(&sockets_list); |
fd1be940 | 5062 | + |
c6a6bfc9 ER |
5063 | + if (!ls) { |
5064 | + break; | |
fd1be940 ER |
5065 | + } |
5066 | + | |
fd1be940 ER |
5067 | + if (op == FPM_STORE_SOCKET) { |
5068 | + ls->refcount = 0; | |
5069 | + } | |
5070 | + else { | |
5071 | + ls->refcount = 1; | |
5072 | + } | |
5073 | + ls->type = type; | |
5074 | + ls->sock = sock; | |
5075 | + ls->key = strdup(key); | |
5076 | + | |
fd1be940 ER |
5077 | + return 0; |
5078 | + | |
5079 | + } | |
5080 | + } | |
5081 | + | |
5082 | + return -1; | |
5083 | + | |
5084 | +} | |
5085 | + | |
5086 | +static int fpm_sockets_new_listening_socket(struct fpm_worker_pool_s *wp, struct sockaddr *sa, int socklen) | |
5087 | +{ | |
5088 | + int backlog = -1; | |
5089 | + int flags = 1; | |
5090 | + int sock; | |
5091 | + mode_t saved_umask; | |
5092 | + | |
5093 | + /* we have custom backlog value */ | |
5094 | + if (wp->config->listen_options) { | |
5095 | + backlog = wp->config->listen_options->backlog; | |
5096 | + } | |
5097 | + | |
5098 | + sock = socket(sa->sa_family, SOCK_STREAM, 0); | |
5099 | + | |
5100 | + if (0 > sock) { | |
5101 | + zlog(ZLOG_STUFF, ZLOG_SYSERROR, "socket() failed"); | |
5102 | + return -1; | |
5103 | + } | |
5104 | + | |
5105 | + setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &flags, sizeof(flags)); | |
5106 | + | |
5107 | + if (wp->listen_address_domain == FPM_AF_UNIX) { | |
5108 | + unlink( ((struct sockaddr_un *) sa)->sun_path); | |
5109 | + } | |
5110 | + | |
5111 | + saved_umask = umask(0777 ^ wp->socket_mode); | |
5112 | + | |
5113 | + if (0 > bind(sock, sa, socklen)) { | |
5114 | + zlog(ZLOG_STUFF, ZLOG_SYSERROR, "bind() for address '%s' failed", wp->config->listen_address); | |
5115 | + return -1; | |
5116 | + } | |
5117 | + | |
5118 | + if (wp->listen_address_domain == FPM_AF_UNIX) { | |
5119 | + | |
5120 | + char *path = ((struct sockaddr_un *) sa)->sun_path; | |
5121 | + | |
5122 | + if (wp->socket_uid != -1 || wp->socket_gid != -1) { | |
5123 | + | |
5124 | + if (0 > chown(path, wp->socket_uid, wp->socket_gid)) { | |
5125 | + zlog(ZLOG_STUFF, ZLOG_SYSERROR, "chown() for address '%s' failed", wp->config->listen_address); | |
5126 | + return -1; | |
5127 | + } | |
5128 | + | |
5129 | + } | |
5130 | + | |
5131 | + } | |
5132 | + | |
5133 | + umask(saved_umask); | |
5134 | + | |
5135 | + if (0 > listen(sock, backlog)) { | |
5136 | + zlog(ZLOG_STUFF, ZLOG_SYSERROR, "listen() for address '%s' failed", wp->config->listen_address); | |
5137 | + return -1; | |
5138 | + } | |
5139 | + | |
5140 | + return sock; | |
5141 | +} | |
5142 | + | |
5143 | +static int fpm_sockets_get_listening_socket(struct fpm_worker_pool_s *wp, struct sockaddr *sa, int socklen) | |
5144 | +{ | |
5145 | + int sock; | |
5146 | + | |
5147 | + sock = fpm_sockets_hash_op(0, sa, 0, wp->listen_address_domain, FPM_GET_USE_SOCKET); | |
5148 | + | |
5149 | + if (sock >= 0) return sock; | |
5150 | + | |
5151 | + sock = fpm_sockets_new_listening_socket(wp, sa, socklen); | |
5152 | + | |
5153 | + fpm_sockets_hash_op(sock, sa, 0, wp->listen_address_domain, FPM_STORE_USE_SOCKET); | |
5154 | + | |
5155 | + return sock; | |
5156 | +} | |
5157 | + | |
5158 | +enum fpm_address_domain fpm_sockets_domain_from_address(char *address) | |
5159 | +{ | |
5160 | + if (strchr(address, ':')) return FPM_AF_INET; | |
5161 | + | |
5162 | + if (strlen(address) == strspn(address, "0123456789")) return FPM_AF_INET; | |
5163 | + | |
5164 | + return FPM_AF_UNIX; | |
5165 | +} | |
5166 | + | |
5167 | +static int fpm_socket_af_inet_listening_socket(struct fpm_worker_pool_s *wp) | |
5168 | +{ | |
5169 | + struct sockaddr_in sa_in; | |
5170 | + char *dup_address = strdup(wp->config->listen_address); | |
5171 | + char *port_str = strchr(dup_address, ':'); | |
5172 | + char *addr = NULL; | |
5173 | + int port = 0; | |
5174 | + | |
5175 | + if (port_str) { /* this is host:port pair */ | |
5176 | + *port_str++ = '\0'; | |
5177 | + port = atoi(port_str); | |
5178 | + addr = dup_address; | |
5179 | + } | |
5180 | + else if (strlen(dup_address) == strspn(dup_address, "0123456789")) { /* this is port */ | |
5181 | + port = atoi(dup_address); | |
5182 | + port_str = dup_address; | |
5183 | + } | |
5184 | + | |
5185 | + if (port == 0) { | |
5186 | + zlog(ZLOG_STUFF, ZLOG_ERROR, "invalid port value '%s'", port_str); | |
5187 | + return -1; | |
5188 | + } | |
5189 | + | |
5190 | + memset(&sa_in, 0, sizeof(sa_in)); | |
5191 | + | |
5192 | + if (addr) { | |
5193 | + | |
5194 | + sa_in.sin_addr.s_addr = inet_addr(addr); | |
5195 | + | |
5196 | + if (sa_in.sin_addr.s_addr == INADDR_NONE) { /* do resolve */ | |
5197 | + if (0 > fpm_sockets_resolve_af_inet(addr, NULL, &sa_in)) { | |
5198 | + return -1; | |
5199 | + } | |
5200 | + zlog(ZLOG_STUFF, ZLOG_NOTICE, "address '%s' resolved as %u.%u.%u.%u", addr, IPQUAD(&sa_in.sin_addr)); | |
5201 | + } | |
5202 | + } | |
5203 | + else { | |
5204 | + | |
5205 | + sa_in.sin_addr.s_addr = htonl(INADDR_ANY); | |
5206 | + | |
5207 | + } | |
5208 | + | |
5209 | + sa_in.sin_family = AF_INET; | |
5210 | + sa_in.sin_port = htons(port); | |
5211 | + | |
5212 | + free(dup_address); | |
5213 | + | |
5214 | + return fpm_sockets_get_listening_socket(wp, (struct sockaddr *) &sa_in, sizeof(struct sockaddr_in)); | |
5215 | +} | |
5216 | + | |
5217 | +static int fpm_socket_af_unix_listening_socket(struct fpm_worker_pool_s *wp) | |
5218 | +{ | |
5219 | + struct sockaddr_un sa_un; | |
5220 | + | |
5221 | + memset(&sa_un, 0, sizeof(sa_un)); | |
5222 | + | |
c6a6bfc9 | 5223 | + cpystrn(sa_un.sun_path, wp->config->listen_address, sizeof(sa_un.sun_path)); |
fd1be940 | 5224 | + sa_un.sun_family = AF_UNIX; |
fd1be940 ER |
5225 | + |
5226 | + return fpm_sockets_get_listening_socket(wp, (struct sockaddr *) &sa_un, sizeof(struct sockaddr_un)); | |
5227 | +} | |
5228 | + | |
5229 | +int fpm_sockets_init_main() | |
5230 | +{ | |
5231 | + int i; | |
5232 | + struct fpm_worker_pool_s *wp; | |
5233 | + char *inherited = getenv("FPM_SOCKETS"); | |
c6a6bfc9 ER |
5234 | + struct listening_socket_s *ls; |
5235 | + | |
5236 | + if (0 == fpm_array_init(&sockets_list, sizeof(struct listening_socket_s), 10)) { | |
5237 | + return -1; | |
5238 | + } | |
fd1be940 ER |
5239 | + |
5240 | + /* import inherited sockets */ | |
5241 | + while (inherited && *inherited) { | |
5242 | + char *comma = strchr(inherited, ','); | |
5243 | + int type, fd_no; | |
5244 | + char *eq; | |
5245 | + | |
5246 | + if (comma) *comma = '\0'; | |
5247 | + | |
5248 | + eq = strchr(inherited, '='); | |
5249 | + | |
5250 | + if (eq) { | |
5251 | + *eq = '\0'; | |
5252 | + | |
5253 | + fd_no = atoi(eq + 1); | |
5254 | + | |
5255 | + type = fpm_sockets_domain_from_address(inherited); | |
5256 | + | |
5257 | + zlog(ZLOG_STUFF, ZLOG_NOTICE, "using inherited socket fd=%d, \"%s\"", fd_no, inherited); | |
5258 | + | |
5259 | + fpm_sockets_hash_op(fd_no, 0, inherited, type, FPM_STORE_SOCKET); | |
5260 | + } | |
5261 | + | |
5262 | + if (comma) inherited = comma + 1; | |
5263 | + else inherited = 0; | |
5264 | + } | |
5265 | + | |
c6a6bfc9 | 5266 | + /* create all required sockets */ |
fd1be940 ER |
5267 | + for (wp = fpm_worker_all_pools; wp; wp = wp->next) { |
5268 | + | |
5269 | + if (!wp->is_template) { | |
5270 | + | |
5271 | + switch (wp->listen_address_domain) { | |
5272 | + | |
5273 | + case FPM_AF_INET : | |
5274 | + | |
5275 | + wp->listening_socket = fpm_socket_af_inet_listening_socket(wp); | |
5276 | + break; | |
5277 | + | |
5278 | + case FPM_AF_UNIX : | |
5279 | + | |
5280 | + if (0 > fpm_unix_resolve_socket_premissions(wp)) { | |
5281 | + return -1; | |
5282 | + } | |
5283 | + | |
5284 | + wp->listening_socket = fpm_socket_af_unix_listening_socket(wp); | |
5285 | + break; | |
5286 | + | |
5287 | + } | |
5288 | + | |
5289 | + if (wp->listening_socket == -1) { | |
5290 | + return -1; | |
5291 | + } | |
5292 | + } | |
5293 | + | |
5294 | + } | |
5295 | + | |
5296 | + /* close unused sockets that was inherited */ | |
c6a6bfc9 ER |
5297 | + ls = sockets_list.data; |
5298 | + | |
5299 | + for (i = 0; i < sockets_list.used; ) { | |
fd1be940 ER |
5300 | + |
5301 | + if (ls->refcount == 0) { | |
5302 | + close(ls->sock); | |
5303 | + if (ls->type == FPM_AF_UNIX) { | |
5304 | + unlink(ls->key); | |
5305 | + } | |
5306 | + free(ls->key); | |
c6a6bfc9 | 5307 | + fpm_array_item_remove(&sockets_list, i); |
fd1be940 ER |
5308 | + } |
5309 | + else { | |
5310 | + ++i; | |
c6a6bfc9 | 5311 | + ++ls; |
fd1be940 ER |
5312 | + } |
5313 | + } | |
5314 | + | |
5315 | + fpm_cleanup_add(FPM_CLEANUP_ALL, fpm_sockets_cleanup, 0); | |
5316 | + | |
5317 | + return 0; | |
5318 | +} | |
8c0dac15 ER |
5319 | diff -Nru php-5.2.6.vanilla/sapi/cgi/fpm/fpm_sockets.h php-5.2.6.fpm/sapi/cgi/fpm/fpm_sockets.h |
5320 | --- php-5.2.6.vanilla/sapi/cgi/fpm/fpm_sockets.h 1970-01-01 03:00:00.000000000 +0300 | |
5321 | +++ php-5.2.6.fpm/sapi/cgi/fpm/fpm_sockets.h 2008-08-26 19:09:15.000000000 +0400 | |
fd1be940 ER |
5322 | @@ -0,0 +1,37 @@ |
5323 | + | |
5324 | + /* $Id$ */ | |
c6a6bfc9 | 5325 | + /* (c) 2007,2008 Andrei Nigmatulin */ |
fd1be940 ER |
5326 | + |
5327 | +#ifndef FPM_MISC_H | |
5328 | +#define FPM_MISC_H 1 | |
5329 | + | |
5330 | +#include <unistd.h> | |
5331 | +#include <fcntl.h> | |
5332 | + | |
5333 | +#include "fpm_worker_pool.h" | |
5334 | + | |
5335 | +enum fpm_address_domain fpm_sockets_domain_from_address(char *addr); | |
5336 | +int fpm_sockets_init_main(); | |
5337 | + | |
5338 | + | |
5339 | +static inline int fd_set_blocked(int fd, int blocked) | |
5340 | +{ | |
5341 | + int flags = fcntl(fd, F_GETFL); | |
5342 | + | |
5343 | + if (flags < 0) return -1; | |
5344 | + | |
5345 | + if (blocked) | |
5346 | + flags &= ~O_NONBLOCK; | |
5347 | + else | |
5348 | + flags |= O_NONBLOCK; | |
5349 | + | |
5350 | + return fcntl(fd, F_SETFL, flags); | |
5351 | +} | |
5352 | + | |
5353 | +#define IPQUAD(sin_addr) \ | |
c6a6bfc9 ER |
5354 | + (unsigned int) ((unsigned char *) &(sin_addr)->s_addr)[0], \ |
5355 | + (unsigned int) ((unsigned char *) &(sin_addr)->s_addr)[1], \ | |
5356 | + (unsigned int) ((unsigned char *) &(sin_addr)->s_addr)[2], \ | |
5357 | + (unsigned int) ((unsigned char *) &(sin_addr)->s_addr)[3] | |
fd1be940 ER |
5358 | + |
5359 | +#endif | |
8c0dac15 ER |
5360 | diff -Nru php-5.2.6.vanilla/sapi/cgi/fpm/fpm_stdio.c php-5.2.6.fpm/sapi/cgi/fpm/fpm_stdio.c |
5361 | --- php-5.2.6.vanilla/sapi/cgi/fpm/fpm_stdio.c 1970-01-01 03:00:00.000000000 +0300 | |
5362 | +++ php-5.2.6.fpm/sapi/cgi/fpm/fpm_stdio.c 2008-05-24 21:38:47.000000000 +0400 | |
c6a6bfc9 | 5363 | @@ -0,0 +1,277 @@ |
fd1be940 ER |
5364 | + |
5365 | + /* $Id$ */ | |
c6a6bfc9 | 5366 | + /* (c) 2007,2008 Andrei Nigmatulin */ |
fd1be940 ER |
5367 | + |
5368 | +#include "fpm_config.h" | |
5369 | + | |
5370 | +#include <sys/types.h> | |
5371 | +#include <sys/stat.h> | |
5372 | +#include <string.h> | |
5373 | +#include <fcntl.h> | |
5374 | +#include <unistd.h> | |
5375 | +#include <errno.h> | |
5376 | + | |
5377 | +#include "fpm.h" | |
5378 | +#include "fpm_children.h" | |
5379 | +#include "fpm_events.h" | |
5380 | +#include "fpm_sockets.h" | |
5381 | +#include "fpm_stdio.h" | |
5382 | +#include "zlog.h" | |
5383 | + | |
c6a6bfc9 ER |
5384 | +static int fd_stdout[2]; |
5385 | +static int fd_stderr[2]; | |
5386 | + | |
fd1be940 ER |
5387 | +int fpm_stdio_init_main() |
5388 | +{ | |
c6a6bfc9 | 5389 | + int fd = open("/dev/null", O_RDWR); |
fd1be940 ER |
5390 | + |
5391 | + if (0 > fd) { | |
c6a6bfc9 | 5392 | + zlog(ZLOG_STUFF, ZLOG_SYSERROR, "open(\"/dev/null\") failed"); |
fd1be940 ER |
5393 | + return -1; |
5394 | + } | |
5395 | + | |
5396 | + dup2(fd, STDIN_FILENO); | |
5397 | + dup2(fd, STDOUT_FILENO); | |
5398 | + close(fd); | |
5399 | + | |
5400 | + return 0; | |
5401 | +} | |
5402 | + | |
5403 | +int fpm_stdio_init_final() | |
5404 | +{ | |
5405 | + if (fpm_global_options.daemonize) { | |
5406 | + | |
5407 | + if (fpm_globals.error_log_fd != STDERR_FILENO) { | |
c6a6bfc9 | 5408 | + /* there might be messages to stderr from libevent, we need to log them all */ |
fd1be940 ER |
5409 | + dup2(fpm_globals.error_log_fd, STDERR_FILENO); |
5410 | + } | |
5411 | + | |
c6a6bfc9 ER |
5412 | + zlog_set_level(fpm_globals.log_level); |
5413 | + | |
fd1be940 ER |
5414 | + zlog_set_fd(fpm_globals.error_log_fd); |
5415 | + } | |
5416 | + | |
5417 | + return 0; | |
5418 | +} | |
5419 | + | |
5420 | +int fpm_stdio_init_child(struct fpm_worker_pool_s *wp) | |
5421 | +{ | |
fd1be940 ER |
5422 | + close(fpm_globals.error_log_fd); |
5423 | + fpm_globals.error_log_fd = -1; | |
c6a6bfc9 | 5424 | + zlog_set_fd(-1); |
fd1be940 ER |
5425 | + |
5426 | + if (wp->listening_socket != STDIN_FILENO) { | |
5427 | + dup2(wp->listening_socket, STDIN_FILENO); | |
5428 | + } | |
5429 | + | |
5430 | + return 0; | |
5431 | +} | |
5432 | + | |
fd1be940 ER |
5433 | +static void fpm_stdio_child_said(int fd, short which, void *arg) |
5434 | +{ | |
5435 | + static const int max_buf_size = 1024; | |
5436 | + char buf[max_buf_size]; | |
5437 | + struct fpm_child_s *child = arg; | |
5438 | + int is_stdout = fd == child->fd_stdout; | |
5439 | + struct event *ev = is_stdout ? &child->ev_stdout : &child->ev_stderr; | |
5440 | + int fifo_in = 1, fifo_out = 1; | |
5441 | + int is_last_message = 0; | |
5442 | + int in_buf = 0; | |
5443 | + int res; | |
5444 | + | |
5445 | +#if 0 | |
5446 | + zlog(ZLOG_STUFF, ZLOG_DEBUG, "child %d said %s", (int) child->pid, is_stdout ? "stdout" : "stderr"); | |
5447 | +#endif | |
5448 | + | |
5449 | + while (fifo_in || fifo_out) { | |
5450 | + | |
5451 | + if (fifo_in) { | |
5452 | + | |
5453 | + res = read(fd, buf + in_buf, max_buf_size - 1 - in_buf); | |
5454 | + | |
5455 | + if (res <= 0) { /* no data */ | |
5456 | + fifo_in = 0; | |
5457 | + | |
5458 | + if (res < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) { | |
5459 | + /* just no more data ready */ | |
5460 | + } | |
5461 | + else { /* error or pipe is closed */ | |
5462 | + | |
5463 | + if (res < 0) { /* error */ | |
5464 | + zlog(ZLOG_STUFF, ZLOG_SYSERROR, "read() failed"); | |
5465 | + } | |
5466 | + | |
5467 | + fpm_event_del(ev); | |
5468 | + is_last_message = 1; | |
5469 | + | |
5470 | + if (is_stdout) { | |
5471 | + close(child->fd_stdout); | |
5472 | + child->fd_stdout = -1; | |
5473 | + } | |
5474 | + else { | |
5475 | + close(child->fd_stderr); | |
5476 | + child->fd_stderr = -1; | |
5477 | + } | |
5478 | + | |
5479 | +#if 0 | |
5480 | + if (in_buf == 0 && !fpm_globals.is_child) { | |
5481 | + zlog(ZLOG_STUFF, ZLOG_DEBUG, "child %d (pool %s) %s pipe is closed", (int) child->pid, | |
5482 | + child->wp->config->name, is_stdout ? "stdout" : "stderr"); | |
5483 | + } | |
5484 | +#endif | |
5485 | + } | |
5486 | + } | |
5487 | + else { | |
5488 | + in_buf += res; | |
5489 | + } | |
5490 | + } | |
5491 | + | |
5492 | + if (fifo_out) { | |
5493 | + if (in_buf == 0) { | |
5494 | + fifo_out = 0; | |
5495 | + } | |
5496 | + else { | |
5497 | + char *nl; | |
5498 | + int should_print = 0; | |
5499 | + buf[in_buf] = '\0'; | |
5500 | + | |
5501 | + /* FIXME: there might be binary data */ | |
5502 | + | |
5503 | + /* we should print if no more space in the buffer */ | |
5504 | + if (in_buf == max_buf_size - 1) { | |
5505 | + should_print = 1; | |
5506 | + } | |
5507 | + | |
5508 | + /* we should print if no more data to come */ | |
5509 | + if (!fifo_in) { | |
5510 | + should_print = 1; | |
5511 | + } | |
5512 | + | |
5513 | + nl = strchr(buf, '\n'); | |
5514 | + | |
5515 | + if (nl || should_print) { | |
5516 | + | |
5517 | + if (nl) { | |
5518 | + *nl = '\0'; | |
5519 | + } | |
5520 | + | |
5521 | + zlog(ZLOG_STUFF, ZLOG_WARNING, "child %d (pool %s) said into %s: \"%s\"%s", (int) child->pid, | |
5522 | + child->wp->config->name, is_stdout ? "stdout" : "stderr", buf, is_last_message ? ", pipe is closed" : ""); | |
5523 | + | |
5524 | + if (nl) { | |
5525 | + int out_buf = 1 + nl - buf; | |
5526 | + memmove(buf, buf + out_buf, in_buf - out_buf); | |
5527 | + in_buf -= out_buf; | |
5528 | + } | |
5529 | + else { | |
5530 | + in_buf = 0; | |
5531 | + } | |
5532 | + } | |
5533 | + } | |
5534 | + } | |
5535 | + } | |
5536 | + | |
5537 | +} | |
5538 | + | |
c6a6bfc9 | 5539 | +int fpm_stdio_prepare_pipes(struct fpm_child_s *child) |
fd1be940 | 5540 | +{ |
c6a6bfc9 | 5541 | + if (0 == child->wp->config->catch_workers_output) { /* not required */ |
fd1be940 ER |
5542 | + return 0; |
5543 | + } | |
5544 | + | |
c6a6bfc9 ER |
5545 | + if (0 > pipe(fd_stdout)) { |
5546 | + zlog(ZLOG_STUFF, ZLOG_SYSERROR, "pipe() failed"); | |
5547 | + return -1; | |
5548 | + } | |
5549 | + | |
5550 | + if (0 > pipe(fd_stderr)) { | |
5551 | + zlog(ZLOG_STUFF, ZLOG_SYSERROR, "pipe() failed"); | |
5552 | + close(fd_stdout[0]); close(fd_stdout[1]); | |
5553 | + return -1; | |
5554 | + } | |
fd1be940 | 5555 | + |
c6a6bfc9 ER |
5556 | + if (0 > fd_set_blocked(fd_stdout[0], 0) || 0 > fd_set_blocked(fd_stderr[0], 0)) { |
5557 | + zlog(ZLOG_STUFF, ZLOG_SYSERROR, "fd_set_blocked() failed"); | |
5558 | + close(fd_stdout[0]); close(fd_stdout[1]); | |
5559 | + close(fd_stderr[0]); close(fd_stderr[1]); | |
5560 | + return -1; | |
5561 | + } | |
fd1be940 | 5562 | + |
c6a6bfc9 ER |
5563 | + return 0; |
5564 | +} | |
5565 | + | |
5566 | +int fpm_stdio_parent_use_pipes(struct fpm_child_s *child) | |
5567 | +{ | |
5568 | + if (0 == child->wp->config->catch_workers_output) { /* not required */ | |
5569 | + return 0; | |
5570 | + } | |
5571 | + | |
5572 | + close(fd_stdout[1]); | |
5573 | + close(fd_stderr[1]); | |
5574 | + | |
5575 | + child->fd_stdout = fd_stdout[0]; | |
5576 | + child->fd_stderr = fd_stderr[0]; | |
fd1be940 ER |
5577 | + |
5578 | + fpm_event_add(child->fd_stdout, &child->ev_stdout, fpm_stdio_child_said, child); | |
5579 | + fpm_event_add(child->fd_stderr, &child->ev_stderr, fpm_stdio_child_said, child); | |
5580 | + | |
5581 | + return 0; | |
5582 | +} | |
c6a6bfc9 ER |
5583 | + |
5584 | +int fpm_stdio_discard_pipes(struct fpm_child_s *child) | |
5585 | +{ | |
5586 | + if (0 == child->wp->config->catch_workers_output) { /* not required */ | |
5587 | + return 0; | |
5588 | + } | |
5589 | + | |
5590 | + close(fd_stdout[1]); | |
5591 | + close(fd_stderr[1]); | |
5592 | + | |
5593 | + close(fd_stdout[0]); | |
5594 | + close(fd_stderr[0]); | |
5595 | + | |
5596 | + return 0; | |
5597 | +} | |
5598 | + | |
5599 | +void fpm_stdio_child_use_pipes(struct fpm_child_s *child) | |
5600 | +{ | |
5601 | + if (child->wp->config->catch_workers_output) { | |
5602 | + dup2(fd_stdout[1], STDOUT_FILENO); | |
5603 | + dup2(fd_stderr[1], STDERR_FILENO); | |
5604 | + close(fd_stdout[0]); close(fd_stdout[1]); | |
5605 | + close(fd_stderr[0]); close(fd_stderr[1]); | |
5606 | + } | |
5607 | + else { | |
5608 | + /* stdout of parent is always /dev/null */ | |
5609 | + dup2(STDOUT_FILENO, STDERR_FILENO); | |
5610 | + } | |
5611 | +} | |
5612 | + | |
5613 | +int fpm_stdio_open_error_log(int reopen) | |
5614 | +{ | |
5615 | + int fd; | |
5616 | + | |
5617 | + fd = open(fpm_global_options.error_log, O_WRONLY | O_APPEND | O_CREAT, S_IRUSR | S_IWUSR); | |
5618 | + | |
5619 | + if (0 > fd) { | |
5620 | + zlog(ZLOG_STUFF, ZLOG_SYSERROR, "open(\"%s\") failed", fpm_global_options.error_log); | |
5621 | + return -1; | |
5622 | + } | |
5623 | + | |
5624 | + if (reopen) { | |
5625 | + if (fpm_global_options.daemonize) { | |
5626 | + dup2(fd, STDERR_FILENO); | |
5627 | + } | |
5628 | + | |
5629 | + dup2(fd, fpm_globals.error_log_fd); | |
5630 | + close(fd); | |
5631 | + fd = fpm_globals.error_log_fd; /* for FD_CLOSEXEC to work */ | |
5632 | + } | |
5633 | + else { | |
5634 | + fpm_globals.error_log_fd = fd; | |
5635 | + } | |
5636 | + | |
5637 | + fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC); | |
5638 | + | |
5639 | + return 0; | |
5640 | +} | |
8c0dac15 ER |
5641 | diff -Nru php-5.2.6.vanilla/sapi/cgi/fpm/fpm_stdio.h php-5.2.6.fpm/sapi/cgi/fpm/fpm_stdio.h |
5642 | --- php-5.2.6.vanilla/sapi/cgi/fpm/fpm_stdio.h 1970-01-01 03:00:00.000000000 +0300 | |
5643 | +++ php-5.2.6.fpm/sapi/cgi/fpm/fpm_stdio.h 2008-05-24 21:38:47.000000000 +0400 | |
c6a6bfc9 | 5644 | @@ -0,0 +1,20 @@ |
fd1be940 ER |
5645 | + |
5646 | + /* $Id$ */ | |
c6a6bfc9 | 5647 | + /* (c) 2007,2008 Andrei Nigmatulin */ |
fd1be940 ER |
5648 | + |
5649 | +#ifndef FPM_STDIO_H | |
5650 | +#define FPM_STDIO_H 1 | |
5651 | + | |
5652 | +#include "fpm_worker_pool.h" | |
5653 | + | |
5654 | +int fpm_stdio_init_main(); | |
5655 | +int fpm_stdio_init_final(); | |
5656 | +int fpm_stdio_init_child(struct fpm_worker_pool_s *wp); | |
c6a6bfc9 ER |
5657 | +int fpm_stdio_prepare_pipes(struct fpm_child_s *child); |
5658 | +void fpm_stdio_child_use_pipes(struct fpm_child_s *child); | |
fd1be940 | 5659 | +int fpm_stdio_parent_use_pipes(struct fpm_child_s *child); |
c6a6bfc9 ER |
5660 | +int fpm_stdio_discard_pipes(struct fpm_child_s *child); |
5661 | +int fpm_stdio_open_error_log(int reopen); | |
5662 | + | |
5663 | +#endif | |
5664 | + | |
8c0dac15 ER |
5665 | diff -Nru php-5.2.6.vanilla/sapi/cgi/fpm/fpm_str.h php-5.2.6.fpm/sapi/cgi/fpm/fpm_str.h |
5666 | --- php-5.2.6.vanilla/sapi/cgi/fpm/fpm_str.h 1970-01-01 03:00:00.000000000 +0300 | |
5667 | +++ php-5.2.6.fpm/sapi/cgi/fpm/fpm_str.h 2008-05-24 21:38:47.000000000 +0400 | |
c6a6bfc9 ER |
5668 | @@ -0,0 +1,49 @@ |
5669 | + | |
5670 | + /* $Id$ */ | |
5671 | + /* (c) 2007,2008 Andrei Nigmatulin */ | |
5672 | + | |
5673 | +#ifndef FPM_STR_H | |
5674 | +#define FPM_STR_H 1 | |
5675 | + | |
5676 | +static inline char *cpystrn(char *dst, const char *src, size_t dst_size) | |
5677 | +{ | |
5678 | + char *d, *end; | |
5679 | + | |
5680 | + if (!dst_size) return dst; | |
5681 | + | |
5682 | + d = dst; | |
5683 | + end = dst + dst_size - 1; | |
5684 | + | |
5685 | + for (; d < end; ++d, ++src) { | |
5686 | + if (!(*d = *src)) { | |
5687 | + return d; | |
5688 | + } | |
5689 | + } | |
5690 | + | |
5691 | + *d = '\0'; | |
5692 | + | |
5693 | + return d; | |
5694 | +} | |
5695 | + | |
5696 | +static inline char *str_purify_filename(char *dst, char *src, size_t size) | |
5697 | +{ | |
5698 | + char *d, *end; | |
5699 | + | |
5700 | + d = dst; | |
5701 | + end = dst + size - 1; | |
5702 | + | |
5703 | + for (; d < end && *src; ++d, ++src) { | |
5704 | + if (* (unsigned char *) src < ' ' || * (unsigned char *) src > '\x7f') { | |
5705 | + *d = '.'; | |
5706 | + } | |
5707 | + else { | |
5708 | + *d = *src; | |
5709 | + } | |
5710 | + } | |
5711 | + | |
5712 | + *d = '\0'; | |
5713 | + | |
5714 | + return d; | |
5715 | +} | |
5716 | + | |
5717 | +#endif | |
8c0dac15 ER |
5718 | diff -Nru php-5.2.6.vanilla/sapi/cgi/fpm/fpm_trace.c php-5.2.6.fpm/sapi/cgi/fpm/fpm_trace.c |
5719 | --- php-5.2.6.vanilla/sapi/cgi/fpm/fpm_trace.c 1970-01-01 03:00:00.000000000 +0300 | |
5720 | +++ php-5.2.6.fpm/sapi/cgi/fpm/fpm_trace.c 2008-07-21 00:59:00.000000000 +0400 | |
c6a6bfc9 ER |
5721 | @@ -0,0 +1,46 @@ |
5722 | + | |
5723 | + /* $Id$ */ | |
5724 | + /* (c) 2007,2008 Andrei Nigmatulin */ | |
5725 | + | |
5726 | +#include "fpm_config.h" | |
5727 | + | |
5728 | +#include <sys/types.h> | |
5729 | + | |
5730 | +#include "fpm_trace.h" | |
5731 | + | |
5732 | +int fpm_trace_get_strz(char *buf, size_t sz, long addr) | |
5733 | +{ | |
5734 | + int i; | |
5735 | + long l; | |
5736 | + char *lc = (char *) &l; | |
5737 | + | |
5738 | + if (0 > fpm_trace_get_long(addr, &l)) { | |
5739 | + return -1; | |
5740 | + } | |
5741 | + | |
5742 | + i = l % SIZEOF_LONG; | |
5743 | + | |
5744 | + l -= i; | |
5745 | + | |
5746 | + for (addr = l; ; addr += SIZEOF_LONG) { | |
5747 | + | |
5748 | + if (0 > fpm_trace_get_long(addr, &l)) { | |
5749 | + return -1; | |
5750 | + } | |
5751 | + | |
5752 | + for ( ; i < SIZEOF_LONG; i++) { | |
5753 | + --sz; | |
5754 | + | |
5755 | + if (sz && lc[i]) { | |
5756 | + *buf++ = lc[i]; | |
5757 | + continue; | |
5758 | + } | |
5759 | + | |
5760 | + *buf = '\0'; | |
5761 | + return 0; | |
5762 | + } | |
5763 | + | |
5764 | + i = 0; | |
5765 | + } | |
5766 | +} | |
5767 | + | |
8c0dac15 ER |
5768 | diff -Nru php-5.2.6.vanilla/sapi/cgi/fpm/fpm_trace.h php-5.2.6.fpm/sapi/cgi/fpm/fpm_trace.h |
5769 | --- php-5.2.6.vanilla/sapi/cgi/fpm/fpm_trace.h 1970-01-01 03:00:00.000000000 +0300 | |
5770 | +++ php-5.2.6.fpm/sapi/cgi/fpm/fpm_trace.h 2008-07-21 07:04:25.000000000 +0400 | |
c6a6bfc9 ER |
5771 | @@ -0,0 +1,17 @@ |
5772 | + | |
5773 | + /* $Id$ */ | |
5774 | + /* (c) 2007,2008 Andrei Nigmatulin */ | |
5775 | + | |
5776 | +#ifndef FPM_TRACE_H | |
5777 | +#define FPM_TRACE_H 1 | |
5778 | + | |
5779 | +#include <unistd.h> | |
5780 | + | |
5781 | +int fpm_trace_signal(pid_t pid); | |
5782 | +int fpm_trace_ready(pid_t pid); | |
5783 | +int fpm_trace_close(pid_t pid); | |
5784 | +int fpm_trace_get_long(long addr, long *data); | |
5785 | +int fpm_trace_get_strz(char *buf, size_t sz, long addr); | |
fd1be940 ER |
5786 | + |
5787 | +#endif | |
5788 | + | |
8c0dac15 ER |
5789 | diff -Nru php-5.2.6.vanilla/sapi/cgi/fpm/fpm_trace_mach.c php-5.2.6.fpm/sapi/cgi/fpm/fpm_trace_mach.c |
5790 | --- php-5.2.6.vanilla/sapi/cgi/fpm/fpm_trace_mach.c 1970-01-01 03:00:00.000000000 +0300 | |
5791 | +++ php-5.2.6.fpm/sapi/cgi/fpm/fpm_trace_mach.c 2008-08-26 19:09:15.000000000 +0400 | |
c6a6bfc9 ER |
5792 | @@ -0,0 +1,102 @@ |
5793 | + | |
5794 | + /* $Id$ */ | |
5795 | + /* (c) 2007,2008 Andrei Nigmatulin */ | |
5796 | + | |
5797 | +#include "fpm_config.h" | |
5798 | + | |
5799 | +#include <mach/mach.h> | |
5800 | +#include <mach/mach_vm.h> | |
5801 | + | |
5802 | +#include <unistd.h> | |
5803 | + | |
5804 | +#include "fpm_trace.h" | |
5805 | +#include "fpm_process_ctl.h" | |
5806 | +#include "fpm_unix.h" | |
5807 | +#include "zlog.h" | |
5808 | + | |
5809 | + | |
5810 | +static mach_port_name_t target; | |
5811 | +static vm_offset_t target_page_base; | |
5812 | +static vm_offset_t local_page; | |
5813 | +static mach_msg_type_number_t local_size; | |
5814 | + | |
5815 | +static void fpm_mach_vm_deallocate() | |
5816 | +{ | |
5817 | + if (local_page) { | |
5818 | + mach_vm_deallocate(mach_task_self(), local_page, local_size); | |
5819 | + target_page_base = 0; | |
5820 | + local_page = 0; | |
5821 | + local_size = 0; | |
5822 | + } | |
5823 | +} | |
5824 | + | |
5825 | +static int fpm_mach_vm_read_page(vm_offset_t page) | |
5826 | +{ | |
5827 | + kern_return_t kr; | |
5828 | + | |
5829 | + kr = mach_vm_read(target, page, fpm_pagesize, &local_page, &local_size); | |
5830 | + | |
5831 | + if (kr != KERN_SUCCESS) { | |
5832 | + zlog(ZLOG_STUFF, ZLOG_ERROR, "mach_vm_read() failed: %s (%d)", mach_error_string(kr), kr); | |
5833 | + return -1; | |
5834 | + } | |
5835 | + | |
5836 | + return 0; | |
5837 | +} | |
5838 | + | |
5839 | +int fpm_trace_signal(pid_t pid) | |
5840 | +{ | |
5841 | + if (0 > fpm_pctl_kill(pid, FPM_PCTL_STOP)) { | |
5842 | + zlog(ZLOG_STUFF, ZLOG_SYSERROR, "kill(SIGSTOP) failed"); | |
5843 | + return -1; | |
5844 | + } | |
5845 | + | |
5846 | + return 0; | |
5847 | +} | |
5848 | + | |
5849 | +int fpm_trace_ready(pid_t pid) | |
5850 | +{ | |
5851 | + kern_return_t kr; | |
5852 | + | |
5853 | + kr = task_for_pid(mach_task_self(), pid, &target); | |
5854 | + | |
5855 | + if (kr != KERN_SUCCESS) { | |
5856 | + char *msg = ""; | |
5857 | + | |
5858 | + if (kr == KERN_FAILURE) { | |
5859 | + msg = " It seems that master process does not have enough privileges to trace processes."; | |
5860 | + } | |
5861 | + | |
5862 | + zlog(ZLOG_STUFF, ZLOG_ERROR, "task_for_pid() failed: %s (%d)%s", mach_error_string(kr), kr, msg); | |
5863 | + return -1; | |
5864 | + } | |
5865 | + | |
5866 | + return 0; | |
5867 | +} | |
5868 | + | |
5869 | +int fpm_trace_close(pid_t pid) | |
5870 | +{ | |
5871 | + fpm_mach_vm_deallocate(); | |
5872 | + | |
5873 | + target = 0; | |
5874 | + | |
5875 | + return 0; | |
5876 | +} | |
5877 | + | |
5878 | +int fpm_trace_get_long(long addr, long *data) | |
5879 | +{ | |
5880 | + size_t offset = ((uintptr_t) (addr) % fpm_pagesize); | |
5881 | + vm_offset_t base = (uintptr_t) (addr) - offset; | |
5882 | + | |
5883 | + if (base != target_page_base) { | |
5884 | + fpm_mach_vm_deallocate(); | |
5885 | + if (0 > fpm_mach_vm_read_page(base)) { | |
5886 | + return -1; | |
5887 | + } | |
5888 | + } | |
5889 | + | |
5890 | + *data = * (long *) (local_page + offset); | |
5891 | + | |
5892 | + return 0; | |
5893 | +} | |
5894 | + | |
8c0dac15 ER |
5895 | diff -Nru php-5.2.6.vanilla/sapi/cgi/fpm/fpm_trace_pread.c php-5.2.6.fpm/sapi/cgi/fpm/fpm_trace_pread.c |
5896 | --- php-5.2.6.vanilla/sapi/cgi/fpm/fpm_trace_pread.c 1970-01-01 03:00:00.000000000 +0300 | |
5897 | +++ php-5.2.6.fpm/sapi/cgi/fpm/fpm_trace_pread.c 2008-08-26 19:09:15.000000000 +0400 | |
c6a6bfc9 | 5898 | @@ -0,0 +1,67 @@ |
fd1be940 ER |
5899 | + |
5900 | + /* $Id$ */ | |
c6a6bfc9 ER |
5901 | + /* (c) 2007,2008 Andrei Nigmatulin */ |
5902 | + | |
5903 | +#define _GNU_SOURCE | |
5904 | +#define _FILE_OFFSET_BITS 64 | |
5905 | + | |
5906 | +#include "fpm_config.h" | |
5907 | + | |
5908 | +#include <unistd.h> | |
5909 | + | |
5910 | +#include <fcntl.h> | |
5911 | +#include <stdio.h> | |
5912 | +#include <stdint.h> | |
5913 | + | |
5914 | +#include "fpm_trace.h" | |
5915 | +#include "fpm_process_ctl.h" | |
5916 | +#include "zlog.h" | |
5917 | + | |
5918 | + | |
5919 | +static int mem_file = -1; | |
5920 | + | |
5921 | +int fpm_trace_signal(pid_t pid) | |
5922 | +{ | |
5923 | + if (0 > fpm_pctl_kill(pid, FPM_PCTL_STOP)) { | |
5924 | + zlog(ZLOG_STUFF, ZLOG_SYSERROR, "kill(SIGSTOP) failed"); | |
5925 | + return -1; | |
5926 | + } | |
5927 | + | |
5928 | + return 0; | |
5929 | +} | |
5930 | + | |
5931 | +int fpm_trace_ready(pid_t pid) | |
5932 | +{ | |
5933 | + char buf[128]; | |
5934 | + | |
5935 | + sprintf(buf, "/proc/%d/" PROC_MEM_FILE, (int) pid); | |
5936 | + | |
5937 | + mem_file = open(buf, O_RDONLY); | |
5938 | + | |
5939 | + if (0 > mem_file) { | |
5940 | + zlog(ZLOG_STUFF, ZLOG_SYSERROR, "open(%s) failed", buf); | |
5941 | + return -1; | |
5942 | + } | |
5943 | + | |
5944 | + return 0; | |
5945 | +} | |
5946 | + | |
5947 | +int fpm_trace_close(pid_t pid) | |
5948 | +{ | |
5949 | + close(mem_file); | |
5950 | + | |
5951 | + mem_file = -1; | |
5952 | + | |
5953 | + return 0; | |
5954 | +} | |
5955 | + | |
5956 | +int fpm_trace_get_long(long addr, long *data) | |
5957 | +{ | |
5958 | + if (sizeof(*data) != pread(mem_file, (void *) data, sizeof(*data), (uintptr_t) addr)) { | |
5959 | + zlog(ZLOG_STUFF, ZLOG_SYSERROR, "pread() failed"); | |
5960 | + return -1; | |
5961 | + } | |
5962 | + | |
5963 | + return 0; | |
5964 | +} | |
5965 | + | |
8c0dac15 ER |
5966 | diff -Nru php-5.2.6.vanilla/sapi/cgi/fpm/fpm_trace_ptrace.c php-5.2.6.fpm/sapi/cgi/fpm/fpm_trace_ptrace.c |
5967 | --- php-5.2.6.vanilla/sapi/cgi/fpm/fpm_trace_ptrace.c 1970-01-01 03:00:00.000000000 +0300 | |
5968 | +++ php-5.2.6.fpm/sapi/cgi/fpm/fpm_trace_ptrace.c 2008-09-19 03:34:11.000000000 +0400 | |
c6a6bfc9 ER |
5969 | @@ -0,0 +1,85 @@ |
5970 | + | |
5971 | + /* $Id$ */ | |
5972 | + /* (c) 2007,2008 Andrei Nigmatulin */ | |
5973 | + | |
5974 | +#include "fpm_config.h" | |
5975 | + | |
5976 | +#include <sys/wait.h> | |
5977 | +#include <sys/ptrace.h> | |
5978 | +#include <unistd.h> | |
5979 | +#include <errno.h> | |
5980 | + | |
5981 | +#if defined(PT_ATTACH) && !defined(PTRACE_ATTACH) | |
5982 | +#define PTRACE_ATTACH PT_ATTACH | |
5983 | +#endif | |
5984 | + | |
5985 | +#if defined(PT_DETACH) && !defined(PTRACE_DETACH) | |
5986 | +#define PTRACE_DETACH PT_DETACH | |
5987 | +#endif | |
5988 | + | |
5989 | +#if defined(PT_READ_D) && !defined(PTRACE_PEEKDATA) | |
5990 | +#define PTRACE_PEEKDATA PT_READ_D | |
5991 | +#endif | |
5992 | + | |
5993 | +#include "fpm_trace.h" | |
5994 | +#include "zlog.h" | |
5995 | + | |
5996 | +static pid_t traced_pid; | |
5997 | + | |
5998 | +int fpm_trace_signal(pid_t pid) | |
5999 | +{ | |
6000 | + if (0 > ptrace(PTRACE_ATTACH, pid, 0, 0)) { | |
6001 | + zlog(ZLOG_STUFF, ZLOG_SYSERROR, "ptrace(ATTACH) failed"); | |
6002 | + return -1; | |
6003 | + } | |
6004 | + | |
6005 | + return 0; | |
6006 | +} | |
6007 | + | |
6008 | +int fpm_trace_ready(pid_t pid) | |
6009 | +{ | |
6010 | + traced_pid = pid; | |
6011 | + | |
6012 | + return 0; | |
6013 | +} | |
6014 | + | |
6015 | +int fpm_trace_close(pid_t pid) | |
6016 | +{ | |
6017 | + if (0 > ptrace(PTRACE_DETACH, pid, (void *) 1, 0)) { | |
6018 | + zlog(ZLOG_STUFF, ZLOG_SYSERROR, "ptrace(DETACH) failed"); | |
6019 | + return -1; | |
6020 | + } | |
6021 | + | |
6022 | + traced_pid = 0; | |
6023 | + | |
6024 | + return 0; | |
6025 | +} | |
6026 | + | |
6027 | +int fpm_trace_get_long(long addr, long *data) | |
6028 | +{ | |
6029 | +#ifdef PT_IO | |
6030 | + struct ptrace_io_desc ptio = { | |
6031 | + .piod_op = PIOD_READ_D, | |
6032 | + .piod_offs = (void *) addr, | |
6033 | + .piod_addr = (void *) data, | |
6034 | + .piod_len = sizeof(long) | |
6035 | + }; | |
6036 | + | |
6037 | + if (0 > ptrace(PT_IO, traced_pid, (void *) &ptio, 0)) { | |
6038 | + zlog(ZLOG_STUFF, ZLOG_SYSERROR, "ptrace(PT_IO) failed"); | |
6039 | + return -1; | |
6040 | + } | |
6041 | +#else | |
6042 | + errno = 0; | |
6043 | + | |
6044 | + *data = ptrace(PTRACE_PEEKDATA, traced_pid, (void *) addr, 0); | |
6045 | + | |
6046 | + if (errno) { | |
6047 | + zlog(ZLOG_STUFF, ZLOG_SYSERROR, "ptrace(PEEKDATA) failed"); | |
6048 | + return -1; | |
6049 | + } | |
6050 | +#endif | |
6051 | + | |
6052 | + return 0; | |
6053 | +} | |
6054 | + | |
8c0dac15 ER |
6055 | diff -Nru php-5.2.6.vanilla/sapi/cgi/fpm/fpm_unix.c php-5.2.6.fpm/sapi/cgi/fpm/fpm_unix.c |
6056 | --- php-5.2.6.vanilla/sapi/cgi/fpm/fpm_unix.c 1970-01-01 03:00:00.000000000 +0300 | |
6057 | +++ php-5.2.6.fpm/sapi/cgi/fpm/fpm_unix.c 2008-09-19 03:19:59.000000000 +0400 | |
c6a6bfc9 ER |
6058 | @@ -0,0 +1,289 @@ |
6059 | + | |
6060 | + /* $Id$ */ | |
6061 | + /* (c) 2007,2008 Andrei Nigmatulin */ | |
fd1be940 ER |
6062 | + |
6063 | +#include "fpm_config.h" | |
6064 | + | |
6065 | +#include <string.h> | |
6066 | +#include <sys/time.h> | |
6067 | +#include <sys/resource.h> | |
6068 | +#include <stdlib.h> | |
6069 | +#include <unistd.h> | |
6070 | +#include <sys/types.h> | |
6071 | +#include <pwd.h> | |
6072 | +#include <grp.h> | |
6073 | + | |
c6a6bfc9 | 6074 | +#ifdef HAVE_PRCTL |
fd1be940 ER |
6075 | +#include <sys/prctl.h> |
6076 | +#endif | |
6077 | + | |
c6a6bfc9 | 6078 | +#include "fpm.h" |
fd1be940 ER |
6079 | +#include "fpm_conf.h" |
6080 | +#include "fpm_cleanup.h" | |
c6a6bfc9 | 6081 | +#include "fpm_clock.h" |
fd1be940 ER |
6082 | +#include "fpm_stdio.h" |
6083 | +#include "fpm_unix.h" | |
6084 | +#include "zlog.h" | |
6085 | + | |
c6a6bfc9 ER |
6086 | +size_t fpm_pagesize; |
6087 | + | |
fd1be940 ER |
6088 | +int fpm_unix_resolve_socket_premissions(struct fpm_worker_pool_s *wp) |
6089 | +{ | |
6090 | + struct fpm_listen_options_s *lo = wp->config->listen_options; | |
6091 | + | |
6092 | + /* uninitialized */ | |
6093 | + wp->socket_uid = -1; | |
6094 | + wp->socket_gid = -1; | |
6095 | + wp->socket_mode = 0666; | |
6096 | + | |
6097 | + if (!lo) return 0; | |
6098 | + | |
6099 | + if (lo->owner && *lo->owner) { | |
6100 | + struct passwd *pwd; | |
6101 | + | |
6102 | + pwd = getpwnam(lo->owner); | |
6103 | + | |
6104 | + if (!pwd) { | |
6105 | + zlog(ZLOG_STUFF, ZLOG_SYSERROR, "cannot get uid for user '%s', pool '%s'", lo->owner, wp->config->name); | |
6106 | + return -1; | |
6107 | + } | |
6108 | + | |
6109 | + wp->socket_uid = pwd->pw_uid; | |
6110 | + wp->socket_gid = pwd->pw_gid; | |
6111 | + } | |
6112 | + | |
6113 | + if (lo->group && *lo->group) { | |
6114 | + struct group *grp; | |
6115 | + | |
6116 | + grp = getgrnam(lo->group); | |
6117 | + | |
6118 | + if (!grp) { | |
6119 | + zlog(ZLOG_STUFF, ZLOG_SYSERROR, "cannot get gid for group '%s', pool '%s'", lo->group, wp->config->name); | |
6120 | + return -1; | |
6121 | + } | |
6122 | + | |
6123 | + wp->socket_gid = grp->gr_gid; | |
6124 | + } | |
6125 | + | |
6126 | + if (lo->mode && *lo->mode) { | |
6127 | + wp->socket_mode = strtoul(lo->mode, 0, 8); | |
6128 | + } | |
6129 | + | |
6130 | + return 0; | |
6131 | +} | |
6132 | + | |
6133 | +static int fpm_unix_conf_wp(struct fpm_worker_pool_s *wp) | |
6134 | +{ | |
6135 | + int is_root = !geteuid(); | |
6136 | + | |
6137 | + if (is_root) { | |
6138 | + if (wp->config->user && *wp->config->user) { | |
fd1be940 | 6139 | + |
c6a6bfc9 ER |
6140 | + if (strlen(wp->config->user) == strspn(wp->config->user, "0123456789")) { |
6141 | + wp->set_uid = strtoul(wp->config->user, 0, 10); | |
fd1be940 | 6142 | + } |
c6a6bfc9 ER |
6143 | + else { |
6144 | + struct passwd *pwd; | |
fd1be940 | 6145 | + |
c6a6bfc9 | 6146 | + pwd = getpwnam(wp->config->user); |
fd1be940 | 6147 | + |
c6a6bfc9 ER |
6148 | + if (!pwd) { |
6149 | + zlog(ZLOG_STUFF, ZLOG_ERROR, "cannot get uid for user '%s', pool '%s'", wp->config->user, wp->config->name); | |
6150 | + return -1; | |
6151 | + } | |
6152 | + | |
6153 | + wp->set_uid = pwd->pw_uid; | |
6154 | + wp->set_gid = pwd->pw_gid; | |
6155 | + | |
6156 | + wp->user = strdup(pwd->pw_name); | |
6157 | + wp->home = strdup(pwd->pw_dir); | |
6158 | + } | |
fd1be940 ER |
6159 | + } |
6160 | + | |
6161 | + if (wp->config->group && *wp->config->group) { | |
fd1be940 | 6162 | + |
c6a6bfc9 ER |
6163 | + if (strlen(wp->config->group) == strspn(wp->config->group, "0123456789")) { |
6164 | + wp->set_gid = strtoul(wp->config->group, 0, 10); | |
fd1be940 | 6165 | + } |
c6a6bfc9 ER |
6166 | + else { |
6167 | + struct group *grp; | |
6168 | + | |
6169 | + grp = getgrnam(wp->config->group); | |
fd1be940 | 6170 | + |
c6a6bfc9 ER |
6171 | + if (!grp) { |
6172 | + zlog(ZLOG_STUFF, ZLOG_ERROR, "cannot get gid for group '%s', pool '%s'", wp->config->group, wp->config->name); | |
6173 | + return -1; | |
6174 | + } | |
6175 | + | |
6176 | + wp->set_gid = grp->gr_gid; | |
6177 | + } | |
fd1be940 ER |
6178 | + } |
6179 | + | |
6180 | +#ifndef I_REALLY_WANT_ROOT_PHP | |
6181 | + if (wp->set_uid == 0 || wp->set_gid == 0) { | |
6182 | + zlog(ZLOG_STUFF, ZLOG_ERROR, "please specify user and group other than root, pool '%s'", wp->config->name); | |
6183 | + return -1; | |
6184 | + } | |
6185 | +#endif | |
6186 | + } | |
6187 | + else { /* not root */ | |
6188 | + if (wp->config->user && *wp->config->user) { | |
6189 | + zlog(ZLOG_STUFF, ZLOG_WARNING, "'user' directive is ignored, pool '%s'", wp->config->name); | |
6190 | + } | |
6191 | + if (wp->config->group && *wp->config->group) { | |
6192 | + zlog(ZLOG_STUFF, ZLOG_WARNING, "'group' directive is ignored, pool '%s'", wp->config->name); | |
6193 | + } | |
6194 | + if (wp->config->chroot && *wp->config->chroot) { | |
6195 | + zlog(ZLOG_STUFF, ZLOG_WARNING, "'chroot' directive is ignored, pool '%s'", wp->config->name); | |
6196 | + } | |
6197 | + | |
6198 | + { /* set up HOME and USER anyway */ | |
6199 | + struct passwd *pwd; | |
6200 | + | |
6201 | + pwd = getpwuid(getuid()); | |
6202 | + | |
6203 | + if (pwd) { | |
6204 | + wp->user = strdup(pwd->pw_name); | |
6205 | + wp->home = strdup(pwd->pw_dir); | |
6206 | + } | |
6207 | + } | |
6208 | + } | |
6209 | + | |
6210 | + return 0; | |
6211 | +} | |
6212 | + | |
6213 | +int fpm_unix_init_child(struct fpm_worker_pool_s *wp) | |
6214 | +{ | |
6215 | + int is_root = !geteuid(); | |
6216 | + int made_chroot = 0; | |
6217 | + | |
6218 | + if (wp->config->rlimit_files) { | |
6219 | + struct rlimit r; | |
6220 | + | |
6221 | + getrlimit(RLIMIT_NOFILE, &r); | |
6222 | + | |
6223 | + r.rlim_cur = (rlim_t) wp->config->rlimit_files; | |
6224 | + | |
6225 | + if (0 > setrlimit(RLIMIT_NOFILE, &r)) { | |
6226 | + zlog(ZLOG_STUFF, ZLOG_SYSERROR, "setrlimit(RLIMIT_NOFILE) failed"); | |
6227 | + } | |
6228 | + } | |
6229 | + | |
6230 | + if (wp->config->rlimit_core) { | |
6231 | + struct rlimit r; | |
6232 | + | |
6233 | + getrlimit(RLIMIT_CORE, &r); | |
6234 | + | |
6235 | + r.rlim_cur = wp->config->rlimit_core == -1 ? (rlim_t) RLIM_INFINITY : (rlim_t) wp->config->rlimit_core; | |
6236 | + | |
6237 | + if (0 > setrlimit(RLIMIT_CORE, &r)) { | |
6238 | + zlog(ZLOG_STUFF, ZLOG_SYSERROR, "setrlimit(RLIMIT_CORE) failed"); | |
6239 | + } | |
6240 | + } | |
6241 | + | |
6242 | + if (is_root && wp->config->chroot && *wp->config->chroot) { | |
6243 | + if (0 > chroot(wp->config->chroot)) { | |
6244 | + zlog(ZLOG_STUFF, ZLOG_SYSERROR, "chroot(%s) failed", wp->config->chroot); | |
6245 | + return -1; | |
6246 | + } | |
6247 | + made_chroot = 1; | |
6248 | + } | |
6249 | + | |
6250 | + if (wp->config->chdir && *wp->config->chdir) { | |
6251 | + if (0 > chdir(wp->config->chdir)) { | |
6252 | + zlog(ZLOG_STUFF, ZLOG_SYSERROR, "chdir(%s) failed", wp->config->chdir); | |
6253 | + return -1; | |
6254 | + } | |
6255 | + } | |
6256 | + else if (made_chroot) { | |
6257 | + chdir("/"); | |
6258 | + } | |
6259 | + | |
6260 | + if (is_root) { | |
6261 | + if (wp->set_gid) { | |
c6a6bfc9 ER |
6262 | + if (0 > setgid(wp->set_gid)) { |
6263 | + zlog(ZLOG_STUFF, ZLOG_SYSERROR, "setgid(%d) failed", wp->set_gid); | |
6264 | + return -1; | |
6265 | + } | |
fd1be940 ER |
6266 | + } |
6267 | + if (wp->set_uid) { | |
c6a6bfc9 ER |
6268 | + if (0 > initgroups(wp->config->user, wp->set_gid)) { |
6269 | + zlog(ZLOG_STUFF, ZLOG_SYSERROR, "initgroups(%s, %d) failed", wp->config->user, wp->set_gid); | |
6270 | + return -1; | |
6271 | + } | |
6272 | + if (0 > setuid(wp->set_uid)) { | |
6273 | + zlog(ZLOG_STUFF, ZLOG_SYSERROR, "setuid(%d) failed", wp->set_uid); | |
6274 | + return -1; | |
6275 | + } | |
fd1be940 ER |
6276 | + } |
6277 | + } | |
6278 | + | |
c6a6bfc9 | 6279 | +#ifdef HAVE_PRCTL |
fd1be940 ER |
6280 | + if (0 > prctl(PR_SET_DUMPABLE, 1, 0, 0, 0)) { |
6281 | + zlog(ZLOG_STUFF, ZLOG_SYSERROR, "prctl(PR_SET_DUMPABLE) failed"); | |
6282 | + } | |
6283 | +#endif | |
6284 | + | |
c6a6bfc9 ER |
6285 | + if (0 > fpm_clock_init()) { |
6286 | + return -1; | |
6287 | + } | |
6288 | + | |
fd1be940 ER |
6289 | + return 0; |
6290 | +} | |
6291 | + | |
6292 | +int fpm_unix_init_main() | |
6293 | +{ | |
6294 | + struct fpm_worker_pool_s *wp; | |
6295 | + | |
c6a6bfc9 ER |
6296 | + fpm_pagesize = getpagesize(); |
6297 | + | |
fd1be940 ER |
6298 | + if (fpm_global_options.daemonize) { |
6299 | + | |
6300 | + switch (fork()) { | |
6301 | + | |
6302 | + case -1 : | |
6303 | + | |
6304 | + zlog(ZLOG_STUFF, ZLOG_SYSERROR, "fork() failed"); | |
6305 | + return -1; | |
6306 | + | |
6307 | + case 0 : | |
6308 | + | |
6309 | + break; | |
6310 | + | |
6311 | + default : | |
6312 | + | |
6313 | + fpm_cleanups_run(FPM_CLEANUP_PARENT_EXIT); | |
6314 | + exit(0); | |
6315 | + | |
6316 | + } | |
6317 | + | |
6318 | + } | |
6319 | + | |
6320 | + setsid(); | |
6321 | + | |
c6a6bfc9 ER |
6322 | + if (0 > fpm_clock_init()) { |
6323 | + return -1; | |
6324 | + } | |
6325 | + | |
6326 | + fpm_globals.parent_pid = getpid(); | |
6327 | + | |
fd1be940 ER |
6328 | + for (wp = fpm_worker_all_pools; wp; wp = wp->next) { |
6329 | + | |
6330 | + if (0 > fpm_unix_conf_wp(wp)) { | |
6331 | + return -1; | |
6332 | + } | |
6333 | + | |
6334 | + } | |
6335 | + | |
6336 | + fpm_stdio_init_final(); | |
6337 | + | |
c6a6bfc9 ER |
6338 | + { |
6339 | + struct rlimit r; | |
6340 | + getrlimit(RLIMIT_NOFILE, &r); | |
6341 | + | |
6342 | + zlog(ZLOG_STUFF, ZLOG_NOTICE, "getrlimit(nofile): max:%lld, cur:%lld", | |
6343 | + (long long) r.rlim_max, (long long) r.rlim_cur); | |
6344 | + } | |
6345 | + | |
fd1be940 ER |
6346 | + return 0; |
6347 | +} | |
8c0dac15 ER |
6348 | diff -Nru php-5.2.6.vanilla/sapi/cgi/fpm/fpm_unix.h php-5.2.6.fpm/sapi/cgi/fpm/fpm_unix.h |
6349 | --- php-5.2.6.vanilla/sapi/cgi/fpm/fpm_unix.h 1970-01-01 03:00:00.000000000 +0300 | |
6350 | +++ php-5.2.6.fpm/sapi/cgi/fpm/fpm_unix.h 2008-05-25 17:21:13.000000000 +0400 | |
c6a6bfc9 | 6351 | @@ -0,0 +1,17 @@ |
fd1be940 ER |
6352 | + |
6353 | + /* $Id$ */ | |
c6a6bfc9 | 6354 | + /* (c) 2007,2008 Andrei Nigmatulin */ |
fd1be940 ER |
6355 | + |
6356 | +#ifndef FPM_UNIX_H | |
6357 | +#define FPM_UNIX_H 1 | |
6358 | + | |
6359 | +#include "fpm_worker_pool.h" | |
6360 | + | |
6361 | +int fpm_unix_resolve_socket_premissions(struct fpm_worker_pool_s *wp); | |
6362 | +int fpm_unix_init_child(struct fpm_worker_pool_s *wp); | |
6363 | +int fpm_unix_init_main(); | |
6364 | + | |
c6a6bfc9 ER |
6365 | +extern size_t fpm_pagesize; |
6366 | + | |
fd1be940 ER |
6367 | +#endif |
6368 | + | |
8c0dac15 ER |
6369 | diff -Nru php-5.2.6.vanilla/sapi/cgi/fpm/fpm_worker_pool.c php-5.2.6.fpm/sapi/cgi/fpm/fpm_worker_pool.c |
6370 | --- php-5.2.6.vanilla/sapi/cgi/fpm/fpm_worker_pool.c 1970-01-01 03:00:00.000000000 +0300 | |
6371 | +++ php-5.2.6.fpm/sapi/cgi/fpm/fpm_worker_pool.c 2008-08-26 19:09:15.000000000 +0400 | |
c6a6bfc9 | 6372 | @@ -0,0 +1,67 @@ |
fd1be940 ER |
6373 | + |
6374 | + /* $Id$ */ | |
c6a6bfc9 | 6375 | + /* (c) 2007,2008 Andrei Nigmatulin */ |
fd1be940 ER |
6376 | + |
6377 | +#include "fpm_config.h" | |
6378 | + | |
6379 | +#include <string.h> | |
6380 | +#include <stdlib.h> | |
6381 | +#include <unistd.h> | |
6382 | + | |
6383 | +#include "fpm_worker_pool.h" | |
6384 | +#include "fpm_cleanup.h" | |
6385 | +#include "fpm_children.h" | |
c6a6bfc9 ER |
6386 | +#include "fpm_shm.h" |
6387 | +#include "fpm_shm_slots.h" | |
fd1be940 ER |
6388 | +#include "fpm_conf.h" |
6389 | + | |
6390 | +struct fpm_worker_pool_s *fpm_worker_all_pools; | |
6391 | + | |
c6a6bfc9 | 6392 | +static void fpm_worker_pool_cleanup(int which, void *arg) |
fd1be940 ER |
6393 | +{ |
6394 | + struct fpm_worker_pool_s *wp, *wp_next; | |
6395 | + | |
6396 | + for (wp = fpm_worker_all_pools; wp; wp = wp_next) { | |
6397 | + wp_next = wp->next; | |
6398 | + fpm_worker_pool_config_free(wp->config); | |
6399 | + fpm_children_free(wp->children); | |
c6a6bfc9 ER |
6400 | + fpm_array_free(&wp->slots_used); |
6401 | + fpm_array_free(&wp->slots_free); | |
6402 | + fpm_shm_free_list(wp->shm_list, which == FPM_CLEANUP_CHILD ? fpm_shm_slots_mem() : 0); | |
fd1be940 ER |
6403 | + free(wp->config); |
6404 | + free(wp->user); | |
6405 | + free(wp->home); | |
6406 | + free(wp); | |
6407 | + } | |
6408 | + | |
6409 | + fpm_worker_all_pools = 0; | |
6410 | +} | |
6411 | + | |
6412 | +struct fpm_worker_pool_s *fpm_worker_pool_alloc() | |
6413 | +{ | |
6414 | + struct fpm_worker_pool_s *ret; | |
6415 | + | |
6416 | + ret = malloc(sizeof(struct fpm_worker_pool_s)); | |
6417 | + | |
6418 | + if (!ret) { | |
6419 | + return 0; | |
6420 | + } | |
6421 | + | |
6422 | + memset(ret, 0, sizeof(struct fpm_worker_pool_s)); | |
6423 | + | |
6424 | + if (!fpm_worker_all_pools) { | |
6425 | + fpm_worker_all_pools = ret; | |
6426 | + } | |
6427 | + | |
c6a6bfc9 ER |
6428 | + fpm_array_init(&ret->slots_used, sizeof(struct fpm_shm_slot_ptr_s), 50); |
6429 | + fpm_array_init(&ret->slots_free, sizeof(struct fpm_shm_slot_ptr_s), 50); | |
6430 | + | |
fd1be940 ER |
6431 | + return ret; |
6432 | +} | |
6433 | + | |
6434 | +int fpm_worker_pool_init_main() | |
6435 | +{ | |
6436 | + fpm_cleanup_add(FPM_CLEANUP_ALL, fpm_worker_pool_cleanup, 0); | |
6437 | + | |
6438 | + return 0; | |
6439 | +} | |
8c0dac15 ER |
6440 | diff -Nru php-5.2.6.vanilla/sapi/cgi/fpm/fpm_worker_pool.h php-5.2.6.fpm/sapi/cgi/fpm/fpm_worker_pool.h |
6441 | --- php-5.2.6.vanilla/sapi/cgi/fpm/fpm_worker_pool.h 1970-01-01 03:00:00.000000000 +0300 | |
6442 | +++ php-5.2.6.fpm/sapi/cgi/fpm/fpm_worker_pool.h 2008-08-26 19:09:15.000000000 +0400 | |
c6a6bfc9 | 6443 | @@ -0,0 +1,46 @@ |
fd1be940 ER |
6444 | + |
6445 | + /* $Id$ */ | |
c6a6bfc9 | 6446 | + /* (c) 2007,2008 Andrei Nigmatulin */ |
fd1be940 ER |
6447 | + |
6448 | +#ifndef FPM_WORKER_POOL_H | |
6449 | +#define FPM_WORKER_POOL_H 1 | |
6450 | + | |
6451 | +#include "fpm_conf.h" | |
c6a6bfc9 | 6452 | +#include "fpm_arrays.h" |
fd1be940 ER |
6453 | + |
6454 | +struct fpm_worker_pool_s; | |
6455 | +struct fpm_child_s; | |
c6a6bfc9 ER |
6456 | +struct fpm_child_stat_s; |
6457 | +struct fpm_shm_s; | |
fd1be940 ER |
6458 | + |
6459 | +enum fpm_address_domain { | |
6460 | + FPM_AF_UNIX = 1, | |
6461 | + FPM_AF_INET = 2 | |
6462 | +}; | |
6463 | + | |
6464 | +struct fpm_worker_pool_s { | |
6465 | + struct fpm_worker_pool_s *next; | |
6466 | + struct fpm_worker_pool_config_s *config; | |
6467 | + char *user, *home; /* for setting env USER and HOME */ | |
6468 | + enum fpm_address_domain listen_address_domain; | |
6469 | + int listening_socket; | |
6470 | + int set_uid, set_gid; /* config uid and gid */ | |
c6a6bfc9 | 6471 | + unsigned is_template:1; /* just config template, no processes will be created */ |
fd1be940 ER |
6472 | + int socket_uid, socket_gid, socket_mode; |
6473 | + | |
c6a6bfc9 ER |
6474 | + struct fpm_shm_s *shm_list; |
6475 | + struct fpm_array_s slots_used; | |
6476 | + struct fpm_array_s slots_free; | |
6477 | + | |
fd1be940 ER |
6478 | + /* runtime */ |
6479 | + struct fpm_child_s *children; | |
fd1be940 ER |
6480 | + int running_children; |
6481 | +}; | |
6482 | + | |
6483 | +struct fpm_worker_pool_s *fpm_worker_pool_alloc(); | |
6484 | +int fpm_worker_pool_init_main(); | |
6485 | + | |
6486 | +extern struct fpm_worker_pool_s *fpm_worker_all_pools; | |
6487 | + | |
6488 | +#endif | |
6489 | + | |
8c0dac15 ER |
6490 | diff -Nru php-5.2.6.vanilla/sapi/cgi/fpm/init.d/php-fpm.in php-5.2.6.fpm/sapi/cgi/fpm/init.d/php-fpm.in |
6491 | --- php-5.2.6.vanilla/sapi/cgi/fpm/init.d/php-fpm.in 1970-01-01 03:00:00.000000000 +0300 | |
6492 | +++ php-5.2.6.fpm/sapi/cgi/fpm/init.d/php-fpm.in 2008-08-05 20:31:27.000000000 +0400 | |
c6a6bfc9 ER |
6493 | @@ -0,0 +1,139 @@ |
6494 | +#! /bin/sh | |
6495 | + | |
6496 | +php_fpm_BIN=@prefix@/bin/php-cgi | |
6497 | +php_fpm_CONF=@php_fpm_conf_path@ | |
6498 | +php_fpm_PID=@php_fpm_pid_path@ | |
6499 | + | |
6500 | + | |
6501 | +php_opts="--fpm-config $php_fpm_CONF" | |
6502 | + | |
6503 | + | |
6504 | +wait_for_pid () { | |
6505 | + try=0 | |
6506 | + | |
6507 | + while test $try -lt 35 ; do | |
6508 | + | |
6509 | + case "$1" in | |
6510 | + 'created') | |
6511 | + if [ -f "$2" ] ; then | |
6512 | + try='' | |
6513 | + break | |
6514 | + fi | |
6515 | + ;; | |
6516 | + | |
6517 | + 'removed') | |
6518 | + if [ ! -f "$2" ] ; then | |
6519 | + try='' | |
6520 | + break | |
6521 | + fi | |
6522 | + ;; | |
6523 | + esac | |
6524 | + | |
6525 | + echo -n . | |
6526 | + try=`expr $try + 1` | |
6527 | + sleep 1 | |
6528 | + | |
6529 | + done | |
6530 | + | |
6531 | +} | |
6532 | + | |
6533 | +case "$1" in | |
6534 | + start) | |
6535 | + echo -n "Starting php_fpm " | |
6536 | + | |
6537 | + $php_fpm_BIN --fpm $php_opts | |
6538 | + | |
6539 | + if [ "$?" != 0 ] ; then | |
6540 | + echo " failed" | |
6541 | + exit 1 | |
6542 | + fi | |
6543 | + | |
6544 | + wait_for_pid created $php_fpm_PID | |
6545 | + | |
6546 | + if [ -n "$try" ] ; then | |
6547 | + echo " failed" | |
6548 | + exit 1 | |
6549 | + else | |
6550 | + echo " done" | |
6551 | + fi | |
6552 | + ;; | |
6553 | + | |
6554 | + stop) | |
6555 | + echo -n "Shutting down php_fpm " | |
6556 | + | |
6557 | + if [ ! -r $php_fpm_PID ] ; then | |
6558 | + echo "warning, no pid file found - php-fpm is not running ?" | |
6559 | + exit 1 | |
6560 | + fi | |
6561 | + | |
6562 | + kill -TERM `cat $php_fpm_PID` | |
6563 | + | |
6564 | + wait_for_pid removed $php_fpm_PID | |
6565 | + | |
6566 | + if [ -n "$try" ] ; then | |
6567 | + echo " failed" | |
6568 | + exit 1 | |
6569 | + else | |
6570 | + echo " done" | |
6571 | + fi | |
6572 | + ;; | |
6573 | + | |
6574 | + quit) | |
6575 | + echo -n "Gracefully shutting down php_fpm " | |
fd1be940 | 6576 | + |
c6a6bfc9 ER |
6577 | + if [ ! -r $php_fpm_PID ] ; then |
6578 | + echo "warning, no pid file found - php-fpm is not running ?" | |
6579 | + exit 1 | |
6580 | + fi | |
6581 | + | |
6582 | + kill -QUIT `cat $php_fpm_PID` | |
6583 | + | |
6584 | + wait_for_pid removed $php_fpm_PID | |
6585 | + | |
6586 | + if [ -n "$try" ] ; then | |
6587 | + echo " failed" | |
6588 | + exit 1 | |
6589 | + else | |
6590 | + echo " done" | |
6591 | + fi | |
6592 | + ;; | |
6593 | + | |
6594 | + restart) | |
6595 | + $0 stop | |
6596 | + $0 start | |
6597 | + ;; | |
6598 | + | |
6599 | + reload) | |
6600 | + | |
6601 | + echo -n "Reload service php-fpm " | |
6602 | + | |
6603 | + if [ ! -r $php_fpm_PID ] ; then | |
6604 | + echo "warning, no pid file found - php-fpm is not running ?" | |
6605 | + exit 1 | |
6606 | + fi | |
6607 | + | |
6608 | + kill -USR2 `cat $php_fpm_PID` | |
6609 | + | |
6610 | + echo " done" | |
6611 | + ;; | |
6612 | + | |
6613 | + logrotate) | |
6614 | + | |
6615 | + echo -n "Re-opening php-fpm log file " | |
6616 | + | |
6617 | + if [ ! -r $php_fpm_PID ] ; then | |
6618 | + echo "warning, no pid file found - php-fpm is not running ?" | |
6619 | + exit 1 | |
6620 | + fi | |
6621 | + | |
6622 | + kill -USR1 `cat $php_fpm_PID` | |
6623 | + | |
6624 | + echo " done" | |
6625 | + ;; | |
6626 | + | |
6627 | + *) | |
6628 | + echo "Usage: $0 {start|stop|quit|restart|reload|logrotate}" | |
6629 | + exit 1 | |
6630 | + ;; | |
6631 | + | |
6632 | +esac | |
8c0dac15 ER |
6633 | diff -Nru php-5.2.6.vanilla/sapi/cgi/fpm/Makefile.frag php-5.2.6.fpm/sapi/cgi/fpm/Makefile.frag |
6634 | --- php-5.2.6.vanilla/sapi/cgi/fpm/Makefile.frag 1970-01-01 03:00:00.000000000 +0300 | |
6635 | +++ php-5.2.6.fpm/sapi/cgi/fpm/Makefile.frag 2008-03-28 16:51:22.000000000 +0300 | |
c6a6bfc9 ER |
6636 | @@ -0,0 +1,21 @@ |
6637 | + | |
8c0dac15 | 6638 | +install-fpm: sapi/cgi/fpm/php-fpm.conf sapi/cgi/fpm/php-fpm |
c6a6bfc9 ER |
6639 | + @echo "Installing FPM config: $(INSTALL_ROOT)$(php_fpm_conf_path)" |
6640 | + -@$(mkinstalldirs) \ | |
6641 | + $(INSTALL_ROOT)$(prefix)/sbin \ | |
6642 | + `dirname "$(INSTALL_ROOT)$(php_fpm_conf_path)"` \ | |
6643 | + `dirname "$(INSTALL_ROOT)$(php_fpm_log_path)"` \ | |
6644 | + `dirname "$(INSTALL_ROOT)$(php_fpm_pid_path)"` | |
6645 | + -@if test -r "$(INSTALL_ROOT)$(php_fpm_conf_path)" ; then \ | |
6646 | + dest=`basename "$(php_fpm_conf_path)"`.default ; \ | |
6647 | + echo " (installing as $$dest)" ; \ | |
fd1be940 | 6648 | + else \ |
c6a6bfc9 | 6649 | + dest=`basename "$(php_fpm_conf_path)"` ; \ |
fd1be940 | 6650 | + fi ; \ |
8c0dac15 | 6651 | + $(INSTALL_DATA) $(top_builddir)/sapi/cgi/fpm/php-fpm.conf $(INSTALL_ROOT)`dirname "$(php_fpm_conf_path)"`/$$dest |
c6a6bfc9 | 6652 | + @echo "Installing init.d script: $(INSTALL_ROOT)$(prefix)/sbin/php-fpm" |
8c0dac15 | 6653 | + -@$(INSTALL) -m 0755 $(top_builddir)/sapi/cgi/fpm/php-fpm $(INSTALL_ROOT)$(prefix)/sbin/php-fpm |
fd1be940 | 6654 | + |
c6a6bfc9 ER |
6655 | +$(top_builddir)/libevent/libevent.a: $(top_builddir)/libevent/Makefile |
6656 | + cd $(top_builddir)/libevent && $(MAKE) libevent.a | |
fd1be940 | 6657 | + |
8c0dac15 ER |
6658 | diff -Nru php-5.2.6.vanilla/sapi/cgi/fpm/xml_config.c php-5.2.6.fpm/sapi/cgi/fpm/xml_config.c |
6659 | --- php-5.2.6.vanilla/sapi/cgi/fpm/xml_config.c 1970-01-01 03:00:00.000000000 +0300 | |
6660 | +++ php-5.2.6.fpm/sapi/cgi/fpm/xml_config.c 2008-08-26 19:09:15.000000000 +0400 | |
fd1be940 ER |
6661 | @@ -0,0 +1,278 @@ |
6662 | + | |
6663 | + /* $Id$ */ | |
6664 | + /* (c) 2004-2007 Andrei Nigmatulin */ | |
6665 | + | |
6666 | +#include "fpm_config.h" | |
6667 | + | |
6668 | +#ifdef HAVE_ALLOCA_H | |
6669 | +#include <alloca.h> | |
6670 | +#endif | |
6671 | +#include <string.h> | |
6672 | +#include <stdio.h> | |
6673 | +#include <stddef.h> | |
6674 | +#include <stdlib.h> | |
6675 | + | |
6676 | +#include <libxml/parser.h> | |
6677 | +#include <libxml/tree.h> | |
6678 | + | |
6679 | +#include "xml_config.h" | |
6680 | + | |
6681 | +static struct xml_conf_section **xml_conf_sections = 0; | |
6682 | +static int xml_conf_sections_allocated = 0; | |
6683 | +static int xml_conf_sections_used = 0; | |
6684 | + | |
6685 | +char *xml_conf_set_slot_boolean(void **conf, char *name, void *vv, intptr_t offset) | |
6686 | +{ | |
6687 | + char *value = vv; | |
6688 | + long value_y = !strcasecmp(value, "yes") || !strcmp(value, "1") || !strcasecmp(value, "on"); | |
6689 | + long value_n = !strcasecmp(value, "no") || !strcmp(value, "0") || !strcasecmp(value, "off"); | |
6690 | + | |
6691 | + if (!value_y && !value_n) { | |
6692 | + return "xml_conf_set_slot(): invalid boolean value"; | |
6693 | + } | |
6694 | + | |
6695 | +#ifdef XML_CONF_DEBUG | |
6696 | + fprintf(stderr, "setting boolean '%s' => %s\n", name, value_y ? "TRUE" : "FALSE"); | |
6697 | +#endif | |
6698 | + | |
6699 | + * (int *) ((char *) *conf + offset) = value_y ? 1 : 0; | |
6700 | + | |
6701 | + return NULL; | |
6702 | +} | |
6703 | + | |
6704 | +char *xml_conf_set_slot_string(void **conf, char *name, void *vv, intptr_t offset) | |
6705 | +{ | |
6706 | + char *value = vv; | |
6707 | + char *v = strdup(value); | |
6708 | + | |
6709 | + if (!v) return "xml_conf_set_slot_string(): strdup() failed"; | |
6710 | + | |
6711 | +#ifdef XML_CONF_DEBUG | |
6712 | + fprintf(stderr, "setting string '%s' => '%s'\n", name, v); | |
6713 | +#endif | |
6714 | + | |
6715 | + * (char **) ((char *) *conf + offset) = v; | |
6716 | + | |
6717 | + return NULL; | |
6718 | +} | |
6719 | + | |
6720 | +char *xml_conf_set_slot_integer(void **conf, char *name, void *vv, intptr_t offset) | |
6721 | +{ | |
6722 | + char *value = vv; | |
6723 | + int v = atoi(value); | |
6724 | + | |
6725 | + * (int *) ((char *) *conf + offset) = v; | |
6726 | + | |
6727 | +#ifdef XML_CONF_DEBUG | |
6728 | + fprintf(stderr, "setting integer '%s' => %d\n", name, v); | |
6729 | +#endif | |
6730 | + | |
6731 | + return NULL; | |
6732 | +} | |
6733 | + | |
6734 | +char *xml_conf_set_slot_time(void **conf, char *name, void *vv, intptr_t offset) | |
6735 | +{ | |
6736 | + char *value = vv; | |
6737 | + int len = strlen(value); | |
6738 | + char suffix; | |
6739 | + int seconds; | |
6740 | + | |
6741 | + if (!len) return "xml_conf_set_slot_timeval(): invalid timeval value"; | |
6742 | + | |
6743 | + suffix = value[len-1]; | |
6744 | + | |
6745 | + value[len-1] = '\0'; | |
6746 | + | |
6747 | + switch (suffix) { | |
6748 | + case 's' : | |
6749 | + seconds = atoi(value); | |
6750 | + break; | |
6751 | + case 'm' : | |
6752 | + seconds = 60 * atoi(value); | |
6753 | + break; | |
6754 | + case 'h' : | |
6755 | + seconds = 60 * 60 * atoi(value); | |
6756 | + break; | |
6757 | + case 'd' : | |
6758 | + seconds = 24 * 60 * 60 * atoi(value); | |
6759 | + break; | |
6760 | + default : | |
6761 | + return "xml_conf_set_slot_timeval(): unknown suffix used in timeval value"; | |
6762 | + } | |
6763 | + | |
6764 | + * (int *) ((char *) *conf + offset) = seconds; | |
6765 | + | |
6766 | +#ifdef XML_CONF_DEBUG | |
6767 | + fprintf(stderr, "setting time '%s' => %d:%02d:%02d:%02d\n", name, expand_dhms(seconds)); | |
6768 | +#endif | |
6769 | + | |
6770 | + return NULL; | |
6771 | +} | |
6772 | + | |
6773 | +char *xml_conf_parse_section(void **conf, struct xml_conf_section *section, void *xml_node) | |
6774 | +{ | |
6775 | + xmlNode *element = xml_node; | |
6776 | + char *ret = 0; | |
6777 | + | |
6778 | +#ifdef XML_CONF_DEBUG | |
6779 | + fprintf(stderr, "processing a section %s\n", section->path); | |
6780 | +#endif | |
6781 | + | |
6782 | + for ( ; element; element = element->next) { | |
6783 | + if (element->type == XML_ELEMENT_NODE && !strcmp((const char *) element->name, "value") && element->children) { | |
6784 | + xmlChar *name = xmlGetProp(element, (unsigned char *) "name"); | |
6785 | + | |
6786 | + if (name) { | |
6787 | + int i; | |
6788 | + | |
6789 | +#ifdef XML_CONF_DEBUG | |
6790 | + fprintf(stderr, "found a value: %s\n", name); | |
6791 | +#endif | |
6792 | + for (i = 0; section->parsers[i].parser; i++) { | |
6793 | + if (!section->parsers[i].name || !strcmp(section->parsers[i].name, (char *) name)) { | |
6794 | + break; | |
6795 | + } | |
6796 | + } | |
6797 | + | |
6798 | + if (section->parsers[i].parser) { | |
6799 | + if (section->parsers[i].type == XML_CONF_SCALAR) { | |
6800 | + if (element->children->type == XML_TEXT_NODE) { | |
6801 | + ret = section->parsers[i].parser(conf, (char *) name, element->children->content, section->parsers[i].offset); | |
6802 | + } | |
6803 | + else { | |
6804 | + ret = "XML_TEXT_NODE is expected, something different is given"; | |
6805 | + } | |
6806 | + } | |
6807 | + else { | |
6808 | + ret = section->parsers[i].parser(conf, (char *) name, element->children, section->parsers[i].offset); | |
6809 | + } | |
6810 | + | |
6811 | + xmlFree(name); | |
6812 | + if (ret) return ret; | |
6813 | + else continue; | |
6814 | + } | |
6815 | + | |
c6a6bfc9 | 6816 | + fprintf(stderr, "Warning, unknown setting '%s' in section '%s'\n", (char *) name, section->path); |
fd1be940 ER |
6817 | + |
6818 | + xmlFree(name); | |
6819 | + } | |
6820 | + } | |
6821 | + } | |
6822 | + | |
6823 | + return NULL; | |
6824 | +} | |
6825 | + | |
6826 | +static char *xml_conf_parse_file(xmlNode *element) | |
6827 | +{ | |
6828 | + char *ret = 0; | |
6829 | + | |
6830 | + for ( ; element; element = element->next) { | |
6831 | + | |
6832 | + if (element->parent && element->type == XML_ELEMENT_NODE && !strcmp((const char *) element->name, "section")) { | |
6833 | + xmlChar *name = xmlGetProp(element, (unsigned char *) "name"); | |
6834 | + | |
6835 | + if (name) { | |
6836 | + char *parent_name = (char *) xmlGetNodePath(element->parent); | |
6837 | + char *full_name; | |
6838 | + int i; | |
6839 | + struct xml_conf_section *section = NULL; | |
6840 | + | |
6841 | +#ifdef XML_CONF_DEBUG | |
6842 | + fprintf(stderr, "got a section: %s/%s\n", parent_name, name); | |
6843 | +#endif | |
6844 | + full_name = alloca(strlen(parent_name) + strlen((char *) name) + 1 + 1); | |
6845 | + | |
c6a6bfc9 | 6846 | + sprintf(full_name, "%s/%s", parent_name, (char *) name); |
fd1be940 ER |
6847 | + |
6848 | + xmlFree(parent_name); | |
6849 | + xmlFree(name); | |
6850 | + | |
6851 | + for (i = 0; i < xml_conf_sections_used; i++) { | |
6852 | + if (!strcmp(xml_conf_sections[i]->path, full_name)) { | |
6853 | + section = xml_conf_sections[i]; | |
6854 | + } | |
6855 | + } | |
6856 | + | |
6857 | + if (section) { /* found a registered section */ | |
6858 | + void *conf = section->conf(); | |
6859 | + ret = xml_conf_parse_section(&conf, section, element->children); | |
6860 | + if (ret) break; | |
6861 | + } | |
6862 | + | |
6863 | + } | |
6864 | + } | |
6865 | + | |
6866 | + if (element->children) { | |
6867 | + ret = xml_conf_parse_file(element->children); | |
6868 | + if (ret) break; | |
6869 | + } | |
6870 | + } | |
6871 | + | |
6872 | + return ret; | |
6873 | +} | |
6874 | + | |
6875 | +char *xml_conf_load_file(char *file) | |
6876 | +{ | |
6877 | + char *ret = 0; | |
6878 | + xmlDoc *doc; | |
6879 | + | |
6880 | + LIBXML_TEST_VERSION | |
6881 | + | |
6882 | + doc = xmlParseFile(file); | |
6883 | + | |
6884 | + if (doc) { | |
6885 | + ret = xml_conf_parse_file(doc->children); | |
6886 | + xmlFreeDoc(doc); | |
6887 | + } | |
6888 | + else { | |
6889 | + ret = "failed to parse conf file"; | |
6890 | + } | |
6891 | + | |
6892 | + xmlCleanupParser(); | |
6893 | + return ret; | |
6894 | +} | |
6895 | + | |
6896 | +int xml_conf_init() | |
6897 | +{ | |
6898 | + return 0; | |
6899 | +} | |
6900 | + | |
6901 | +void xml_conf_clean() | |
6902 | +{ | |
6903 | + if (xml_conf_sections) { | |
6904 | + free(xml_conf_sections); | |
6905 | + } | |
6906 | +} | |
6907 | + | |
6908 | +int xml_conf_section_register(struct xml_conf_section *section) | |
6909 | +{ | |
6910 | + if (xml_conf_sections_allocated == xml_conf_sections_used) { | |
6911 | + int new_size = xml_conf_sections_used + 10; | |
6912 | + void *new_ptr = realloc(xml_conf_sections, sizeof(struct xml_conf_section *) * new_size); | |
6913 | + | |
6914 | + if (new_ptr) { | |
6915 | + xml_conf_sections = new_ptr; | |
6916 | + xml_conf_sections_allocated = new_size; | |
6917 | + } | |
6918 | + else { | |
6919 | + fprintf(stderr, "xml_conf_section_register(): out of memory\n"); | |
6920 | + return -1; | |
6921 | + } | |
6922 | + } | |
6923 | + | |
6924 | + xml_conf_sections[xml_conf_sections_used++] = section; | |
6925 | + | |
6926 | + return 0; | |
6927 | +} | |
6928 | + | |
6929 | +int xml_conf_sections_register(struct xml_conf_section *sections[]) | |
6930 | +{ | |
6931 | + for ( ; sections && *sections; sections++) { | |
6932 | + if (0 > xml_conf_section_register(*sections)) { | |
6933 | + return -1; | |
6934 | + } | |
6935 | + } | |
6936 | + | |
6937 | + return 0; | |
6938 | +} | |
6939 | + | |
8c0dac15 ER |
6940 | diff -Nru php-5.2.6.vanilla/sapi/cgi/fpm/xml_config.h php-5.2.6.fpm/sapi/cgi/fpm/xml_config.h |
6941 | --- php-5.2.6.vanilla/sapi/cgi/fpm/xml_config.h 1970-01-01 03:00:00.000000000 +0300 | |
6942 | +++ php-5.2.6.fpm/sapi/cgi/fpm/xml_config.h 2008-09-19 03:02:58.000000000 +0400 | |
fd1be940 ER |
6943 | @@ -0,0 +1,43 @@ |
6944 | + | |
6945 | + /* $Id$ */ | |
6946 | + /* (c) 2004-2007 Andrei Nigmatulin */ | |
6947 | + | |
6948 | +#ifndef XML_CONFIG_H | |
6949 | +#define XML_CONFIG_H 1 | |
6950 | + | |
6951 | +#include <stdint.h> | |
6952 | + | |
6953 | +struct xml_value_parser; | |
6954 | + | |
6955 | +struct xml_value_parser { | |
6956 | + int type; | |
6957 | + char *name; | |
6958 | + char *(*parser)(void **, char *, void *, intptr_t offset); | |
6959 | + intptr_t offset; | |
6960 | +}; | |
6961 | + | |
6962 | +struct xml_conf_section { | |
6963 | + void *(*conf)(); | |
6964 | + char *path; | |
c6a6bfc9 | 6965 | + struct xml_value_parser *parsers; |
fd1be940 ER |
6966 | +}; |
6967 | + | |
6968 | +char *xml_conf_set_slot_boolean(void **conf, char *name, void *value, intptr_t offset); | |
6969 | +char *xml_conf_set_slot_string(void **conf, char *name, void *value, intptr_t offset); | |
6970 | +char *xml_conf_set_slot_integer(void **conf, char *name, void *value, intptr_t offset); | |
6971 | +char *xml_conf_set_slot_time(void **conf, char *name, void *value, intptr_t offset); | |
6972 | + | |
6973 | +int xml_conf_init(); | |
6974 | +void xml_conf_clean(); | |
6975 | +char *xml_conf_load_file(char *file); | |
6976 | +char *xml_conf_parse_section(void **conf, struct xml_conf_section *section, void *ve); | |
6977 | +int xml_conf_section_register(struct xml_conf_section *section); | |
6978 | +int xml_conf_sections_register(struct xml_conf_section *sections[]); | |
6979 | + | |
6980 | +#define expand_hms(value) (value) / 3600, ((value) % 3600) / 60, (value) % 60 | |
6981 | + | |
6982 | +#define expand_dhms(value) (value) / 86400, ((value) % 86400) / 3600, ((value) % 3600) / 60, (value) % 60 | |
6983 | + | |
6984 | +enum { XML_CONF_SCALAR = 1, XML_CONF_SUBSECTION = 2 }; | |
6985 | + | |
6986 | +#endif | |
8c0dac15 ER |
6987 | diff -Nru php-5.2.6.vanilla/sapi/cgi/fpm/zlog.c php-5.2.6.fpm/sapi/cgi/fpm/zlog.c |
6988 | --- php-5.2.6.vanilla/sapi/cgi/fpm/zlog.c 1970-01-01 03:00:00.000000000 +0300 | |
6989 | +++ php-5.2.6.fpm/sapi/cgi/fpm/zlog.c 2008-05-23 01:08:32.000000000 +0400 | |
c6a6bfc9 | 6990 | @@ -0,0 +1,113 @@ |
fd1be940 ER |
6991 | + |
6992 | + /* $Id$ */ | |
6993 | + /* (c) 2004-2007 Andrei Nigmatulin */ | |
6994 | + | |
6995 | +#include "fpm_config.h" | |
6996 | + | |
6997 | +#include <stdio.h> | |
6998 | +#include <unistd.h> | |
6999 | +#include <time.h> | |
7000 | +#include <string.h> | |
7001 | +#include <stdarg.h> | |
7002 | +#include <sys/time.h> | |
7003 | +#include <errno.h> | |
7004 | + | |
7005 | +#include "zlog.h" | |
7006 | + | |
7007 | +#define MAX_LINE_LENGTH 1024 | |
7008 | + | |
7009 | +static int zlog_fd = -1; | |
c6a6bfc9 | 7010 | +static int zlog_level = ZLOG_NOTICE; |
fd1be940 ER |
7011 | + |
7012 | +static const char *level_names[] = { | |
7013 | + [ZLOG_DEBUG] = "DEBUG", | |
7014 | + [ZLOG_NOTICE] = "NOTICE", | |
7015 | + [ZLOG_WARNING] = "WARNING", | |
7016 | + [ZLOG_ERROR] = "ERROR", | |
7017 | + [ZLOG_ALERT] = "ALERT", | |
7018 | +}; | |
7019 | + | |
c6a6bfc9 | 7020 | +size_t zlog_print_time(struct timeval *tv, char *timebuf, size_t timebuf_len) |
fd1be940 | 7021 | +{ |
fd1be940 ER |
7022 | + struct tm t; |
7023 | + size_t len; | |
7024 | + | |
c6a6bfc9 ER |
7025 | + len = strftime(timebuf, timebuf_len, "%b %d %H:%M:%S", localtime_r((const time_t *) &tv->tv_sec, &t)); |
7026 | + len += snprintf(timebuf + len, timebuf_len - len, ".%06d", (int) tv->tv_usec); | |
fd1be940 ER |
7027 | + |
7028 | + return len; | |
7029 | +} | |
7030 | + | |
7031 | +int zlog_set_fd(int new_fd) | |
7032 | +{ | |
7033 | + int old_fd = zlog_fd; | |
7034 | + zlog_fd = new_fd; | |
7035 | + | |
7036 | + return old_fd; | |
7037 | +} | |
7038 | + | |
c6a6bfc9 ER |
7039 | +int zlog_set_level(int new_value) |
7040 | +{ | |
7041 | + int old_value = zlog_level; | |
7042 | + | |
7043 | + zlog_level = new_value; | |
7044 | + | |
7045 | + return old_value; | |
7046 | +} | |
7047 | + | |
fd1be940 ER |
7048 | +void zlog(const char *function, int line, int flags, const char *fmt, ...) |
7049 | +{ | |
c6a6bfc9 | 7050 | + struct timeval tv; |
fd1be940 ER |
7051 | + char buf[MAX_LINE_LENGTH]; |
7052 | + const size_t buf_size = MAX_LINE_LENGTH; | |
7053 | + va_list args; | |
7054 | + size_t len; | |
7055 | + int truncated = 0; | |
c6a6bfc9 | 7056 | + int saved_errno; |
fd1be940 | 7057 | + |
c6a6bfc9 ER |
7058 | + if ((flags & ZLOG_LEVEL_MASK) < zlog_level) { |
7059 | + return; | |
7060 | + } | |
7061 | + | |
7062 | + saved_errno = errno; | |
7063 | + | |
7064 | + gettimeofday(&tv, 0); | |
7065 | + | |
7066 | + len = zlog_print_time(&tv, buf, buf_size); | |
fd1be940 ER |
7067 | + |
7068 | + len += snprintf(buf + len, buf_size - len, " [%s] %s(), line %d: ", level_names[flags & ZLOG_LEVEL_MASK], function, line); | |
7069 | + | |
7070 | + if (len > buf_size - 1) { | |
7071 | + truncated = 1; | |
7072 | + } | |
7073 | + | |
7074 | + if (!truncated) { | |
7075 | + va_start(args, fmt); | |
7076 | + | |
7077 | + len += vsnprintf(buf + len, buf_size - len, fmt, args); | |
7078 | + | |
7079 | + va_end(args); | |
7080 | + | |
7081 | + if (len >= buf_size) { | |
7082 | + truncated = 1; | |
7083 | + } | |
7084 | + } | |
7085 | + | |
7086 | + if (!truncated) { | |
7087 | + if (flags & ZLOG_HAVE_ERRNO) { | |
7088 | + len += snprintf(buf + len, buf_size - len, ": %s (%d)", strerror(saved_errno), saved_errno); | |
7089 | + if (len >= buf_size) { | |
7090 | + truncated = 1; | |
7091 | + } | |
7092 | + } | |
7093 | + } | |
7094 | + | |
7095 | + if (truncated) { | |
7096 | + memcpy(buf + buf_size - sizeof("..."), "...", sizeof("...") - 1); | |
7097 | + len = buf_size - 1; | |
7098 | + } | |
7099 | + | |
7100 | + buf[len++] = '\n'; | |
7101 | + | |
7102 | + write(zlog_fd > -1 ? zlog_fd : STDERR_FILENO, buf, len); | |
7103 | +} | |
8c0dac15 ER |
7104 | diff -Nru php-5.2.6.vanilla/sapi/cgi/fpm/zlog.h php-5.2.6.fpm/sapi/cgi/fpm/zlog.h |
7105 | --- php-5.2.6.vanilla/sapi/cgi/fpm/zlog.h 1970-01-01 03:00:00.000000000 +0300 | |
7106 | +++ php-5.2.6.fpm/sapi/cgi/fpm/zlog.h 2008-05-23 01:08:32.000000000 +0400 | |
c6a6bfc9 | 7107 | @@ -0,0 +1,34 @@ |
fd1be940 ER |
7108 | + |
7109 | + /* $Id$ */ | |
7110 | + /* (c) 2004-2007 Andrei Nigmatulin */ | |
7111 | + | |
7112 | +#ifndef ZLOG_H | |
7113 | +#define ZLOG_H 1 | |
7114 | + | |
7115 | +#define ZLOG_STUFF __func__, __LINE__ | |
7116 | + | |
c6a6bfc9 ER |
7117 | +struct timeval; |
7118 | + | |
fd1be940 | 7119 | +int zlog_set_fd(int new_fd); |
c6a6bfc9 ER |
7120 | +int zlog_set_level(int new_value); |
7121 | + | |
7122 | +size_t zlog_print_time(struct timeval *tv, char *timebuf, size_t timebuf_len); | |
fd1be940 ER |
7123 | + |
7124 | +void zlog(const char *function, int line, int flags, const char *fmt, ...) | |
7125 | + __attribute__ ((format(printf,4,5))); | |
7126 | + | |
7127 | +enum { | |
7128 | + ZLOG_DEBUG = 1, | |
7129 | + ZLOG_NOTICE = 2, | |
7130 | + ZLOG_WARNING = 3, | |
7131 | + ZLOG_ERROR = 4, | |
7132 | + ZLOG_ALERT = 5, | |
7133 | +}; | |
7134 | + | |
7135 | +#define ZLOG_LEVEL_MASK 7 | |
7136 | + | |
7137 | +#define ZLOG_HAVE_ERRNO 0x100 | |
7138 | + | |
7139 | +#define ZLOG_SYSERROR (ZLOG_ERROR | ZLOG_HAVE_ERRNO) | |
7140 | + | |
7141 | +#endif | |
75ddaf45 ER |
7142 | --- php-5.2.6/sapi/cgi/Makefile.frag~ 2008-11-03 19:29:12.000000000 +0200 |
7143 | +++ php-5.2.6/sapi/cgi/Makefile.frag 2008-11-03 19:31:19.361921087 +0200 | |
fd1be940 | 7144 | @@ -1,2 +1,2 @@ |
75ddaf45 ER |
7145 | -$(SAPI_CGI_PATH): libphp_common.la $(PHP_SAPI_OBJS) |
7146 | +$(SAPI_CGI_PATH): libphp_common.la $(PHP_SAPI_OBJS) $(SAPI_EXTRA_DEPS) | |
fd1be940 | 7147 | $(BUILD_CGI) |