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