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