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