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