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