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