PTHREADS_FLAGS
fi
+if test "$PHP_ENABLE_FASTCGI" = "yes"; then
+ PHP_CONFIGURE_PART(Running FastCGI checks)
+ sinclude(sapi/cgi/libfcgi/acinclude.m4)
+ sinclude(sapi/cgi/libfcgi/libfcgi.m4)
+fi
divert(3)
Credits:
Ben Mansell, Stephen Landamore, Daniel Silverstone, Shane Caraveo
+Building PHP
+------------
+
+You must add '--enable-fastcgi' to the configure command on Linux or
+OSX based systems to get fastcgi support in the php-cgi binary. You
+also must not use '--enable-discard-path'.
+
Running the FastCGI PHP module
------------------------------
Now, we'll create a fcgi-bin directory, just like you would do with normal
CGI scripts. You'll need to create a directory somewhere to store your
FastCGI binaries. We'll use /space/fcgi-bin/ for this example. Remember to
-copy the FastCGI-PHP binary in there. (named just 'php')
+copy the FastCGI-PHP binary in there. (named 'php-cgi') This sets up
+php to run under mod_fastcgi as a dynamic server.
ScriptAlias /fcgi-bin/ /space/fcgi-bin/
<Location /fcgi-bin/>
SetHandler fastcgi-script
</Location>
-To have mod_fastcgi manage your php fastcgi processes for you, use the
-configuration directive FCGIServer (see mod_fastcgi docs for more
-configuration information):
+To setup a specific static configuration for php, you have to use
+the FastCgiServer configuration for mod_fastcgi. For this, do not
+use the above configuration, but rather the following.
+(see mod_fastcgi docs for more configuration information):
- FastCgiServer /fcgi-bin/php-cgi -processes 5
+ Alias /fcgi-bin/ /space/fcgi-bin/
+ FastCgiServer /path/to/php-cgi -processes 5
-Next, we need to tell Apache to use the FastCGI binary /fcgi-bin/php to
-deliver PHP pages. All that is needed is:
+For either of the above configurations, we need to tell Apache to
+use the FastCGI binary /fcgi-bin/php to deliver PHP pages.
+All that is needed is:
AddType application/x-httpd-fastphp .php
Action application/x-httpd-fastphp /fcgi-bin/php-cgi
#include "php_getopt.h"
-#ifdef PHP_FASTCGI
+#if PHP_FASTCGI
#include "fcgi_config.h"
#include "fcgiapp.h"
/* don't want to include fcgios.h, causes conflicts */
#ifdef PHP_WIN32
extern int OS_SetImpersonate(void);
+#else
+/* XXX this will need to change later when threaded fastcgi is
+ implemented. shane */
+struct sigaction act, old_term, old_quit, old_int;
#endif
static void (*php_php_import_environment_variables)(zval *array_ptr TSRMLS_DC);
size_t ret;
#endif
-#ifdef PHP_FASTCGI
+#if PHP_FASTCGI
if (!FCGX_IsCGI()) {
FCGX_Request *request = (FCGX_Request *)SG(server_context);
long ret = FCGX_PutStr( str, str_length, request->out );
static void sapi_cgibin_flush(void *server_context)
{
-#ifdef PHP_FASTCGI
+#if PHP_FASTCGI
if (!FCGX_IsCGI()) {
FCGX_Request *request = (FCGX_Request *)server_context;
if(!request || FCGX_FFlush( request->out ) == -1 ) {
static int sapi_cgi_read_post(char *buffer, uint count_bytes TSRMLS_DC)
{
uint read_bytes=0, tmp_read_bytes;
-#ifdef PHP_FASTCGI
+#if PHP_FASTCGI
char *pos = buffer;
#endif
count_bytes = MIN(count_bytes, (uint)SG(request_info).content_length-SG(read_post_bytes));
while (read_bytes < count_bytes) {
-#ifdef PHP_FASTCGI
+#if PHP_FASTCGI
if (!FCGX_IsCGI()) {
FCGX_Request *request = (FCGX_Request *)SG(server_context);
tmp_read_bytes = FCGX_GetStr( pos, count_bytes-read_bytes, request->in );
static char *sapi_cgibin_getenv(char *name, size_t name_len TSRMLS_DC)
{
-#ifdef PHP_FASTCGI
+#if PHP_FASTCGI
/* when php is started by mod_fastcgi, no regular environment
is provided to PHP. It is always sent to PHP at the start
of a request. So we have to do our own lookup to get env
int cgi_env_size = 0;
FCGX_Request *request = (FCGX_Request *)SG(server_context);
while( request->envp[ cgi_env_size ] ) {
- if (strnicmp(name,request->envp[cgi_env_size],name_len) == 0) {
+ if (strncasecmp(name,request->envp[cgi_env_size],name_len) == 0) {
return (request->envp[cgi_env_size])+name_len+1;
}
cgi_env_size++;
return sapi_cgibin_getenv((char *)"HTTP_COOKIE",strlen("HTTP_COOKIE") TSRMLS_CC);
}
-#ifdef PHP_FASTCGI
+#if PHP_FASTCGI
void cgi_php_import_environment_variables(zval *array_ptr TSRMLS_DC)
{
if (!FCGX_IsCGI()) {
/* {{{ sapi_module_struct cgi_sapi_module
*/
static sapi_module_struct cgi_sapi_module = {
-#ifdef PHP_FASTCGI
+#if PHP_FASTCGI
"cgi-fcgi", /* name */
"CGI/FastCGI", /* pretty name */
#else
php_printf("Usage: %s [-q] [-h] [-s [-v] [-i] [-f <file>] \n"
" %s <file> [args...]\n"
" -a Run interactively\n"
-#ifdef PHP_FASTCGI
+#if PHP_FASTCGI
" -b <address:port>|<port> Bind Path for external FASTCGI Server mode\n"
#endif
" -C Do not chdir to the script's directory\n"
efree(*arg);
}
+#if PHP_FASTCGI
+/**
+ * Clean up child processes upon exit
+ */
+void fastcgi_cleanup(int signal)
+{
+
+#ifdef DEBUG_FASTCGI
+ fprintf( stderr, "FastCGI shutdown, pid %d\n", getpid() );
+#endif
+
+#ifndef PHP_WIN32
+ sigaction( SIGTERM, &old_term, 0 );
+
+ /* Kill all the processes in our process group */
+ kill( -pgroup, SIGTERM );
+#endif
+
+ /* We should exit at this point, but MacOSX doesn't seem to */
+ exit( 0 );
+}
+#endif
+
/* {{{ main
*/
int main(int argc, char *argv[])
void ***tsrm_ls;
#endif
-#ifdef PHP_FASTCGI
+#if PHP_FASTCGI
int max_requests = 500;
int requests = 0;
int fastcgi = !FCGX_IsCGI();
FCGX_Request request;
#ifdef PHP_WIN32
int impersonate = 0;
+#else
+ int status = 0;
#endif
#endif /* PHP_FASTCGI */
setmode(_fileno(stderr), O_BINARY); /* make the stdio mode be binary */
#endif
-#ifdef PHP_FASTCGI
+#if PHP_FASTCGI
if (!fastcgi) {
#endif
/* Make sure we detect we are a cgi - a bit redundancy here,
argv0 = NULL;
}
}
-#ifdef PHP_FASTCGI
+#if PHP_FASTCGI
}
#endif
if (!cgi
-#ifdef PHP_FASTCGI
+#if PHP_FASTCGI
/* allow ini override for fastcgi */
#endif
) {
ap_php_optarg = orig_optarg;
}
-#ifdef PHP_FASTCGI
+#if PHP_FASTCGI
if (!cgi && !fastcgi) {
/* if we're started on command line, check to see if
we are being started as an 'external' fastcgi
}
#endif /* FORCE_CGI_REDIRECT */
-#ifdef PHP_FASTCGI
+#if PHP_FASTCGI
if (bindpath) {
/* Pass on the arg to the FastCGI library, with one exception.
* If just a port is specified, then we prepend a ':' onto the
zend_first_try {
if (!cgi
-#ifdef PHP_FASTCGI
+#if PHP_FASTCGI
&& !fastcgi
#endif
) {
ap_php_optarg = orig_optarg;
}
-#ifdef PHP_FASTCGI
+#if PHP_FASTCGI
/* start of FAST CGI loop */
/* Initialise FastCGI request structure */
|| FCGX_Accept_r( &request ) >= 0) {
#endif
-#ifdef PHP_FASTCGI
+#if PHP_FASTCGI
SG(server_context) = (void *) &request;
#else
SG(server_context) = (void *) 1; /* avoid server_context==NULL checks */
zend_llist_init(&global_vars, sizeof(char *), NULL, 0);
if (!cgi
-#ifdef PHP_FASTCGI
+#if PHP_FASTCGI
&& !fastcgi
#endif
) { /* never execute the arguments if you are a CGI */
CG(interactive) = interactive;
if (!cgi
-#ifdef PHP_FASTCGI
+#if PHP_FASTCGI
&& !fastcgi
#endif
) {
php_module_shutdown(TSRMLS_C);
return FAILURE;
}
+
if (no_headers) {
SG(headers_sent) = 1;
SG(request_info).no_headers = 1;
}
-#ifdef PHP_FASTCGI
+#if PHP_FASTCGI
if (fastcgi) {
file_handle.type = ZEND_HANDLE_FILENAME;
file_handle.filename = SG(request_info).path_translated;
file_handle.filename = "-";
file_handle.type = ZEND_HANDLE_FP;
file_handle.handle.fp = stdin;
-#ifdef PHP_FASTCGI
+#if PHP_FASTCGI
}
#endif
file_handle.opened_path = NULL;
zend_llist_destroy(&global_vars);
if (!cgi
-#ifdef PHP_FASTCGI
+#if PHP_FASTCGI
&& !fastcgi
#endif
) {
#else
env_path_translated = sapi_cgibin_getenv("PATH_TRANSLATED",strlen("PATH_TRANSLATED") TSRMLS_CC);
#endif
+
if(env_path_translated) {
#ifdef __riscos__
/* Convert path to unix format*/
}
}
-#ifdef PHP_FASTCGI
+#if PHP_FASTCGI
if (!fastcgi) break;
/* only fastcgi will get here */
requests++;
PHP_DISCARD_PATH=no
])
+AC_ARG_ENABLE(fastcgi,
+[ --enable-fastcgi If this is enabled, the cgi module will
+ be built with support for fastcgi also.],
+[
+ PHP_ENABLE_FASTCGI=$enableval
+],[
+ PHP_ENABLE_FASTCGI=no
+])
AC_DEFUN(PHP_TEST_WRITE_STDOUT,[
AC_CACHE_CHECK(whether writing to stdout works,ac_cv_write_stdout,[
AC_DEFINE_UNQUOTED(DISCARD_PATH, $DISCARD_PATH, [ ])
AC_MSG_RESULT($PHP_DISCARD_PATH)
+ AC_MSG_CHECKING(whether to enable fastcgi support)
+ PHP_LIBFCGI_DIR="$abs_srcdir/sapi/cgi/libfcgi"
+ if test -z $PHP_LIBFCGI_DIR; then
+ echo "$PHP_LIBFCGI_DIR does not exist"
+ exit 1
+ fi
+ if test "$PHP_ENABLE_FASTCGI" = "yes"; then
+ PHP_FASTCGI=1
+ PHP_FCGI_FILES="libfcgi/fcgi_stdio.c libfcgi/fcgiapp.c libfcgi/os_unix.c"
+ PHP_FCGI_INCLUDE="$PHP_LIBFCGI_DIR/include"
+ PHP_FCGI_STATIC=1
+ else
+ PHP_FASTCGI=0
+ PHP_FCGI_FILES=""
+ PHP_FCGI_INCLUDE=""
+ PHP_FCGI_STATIC=0
+ fi
+ AC_DEFINE_UNQUOTED(PHP_FASTCGI, $PHP_FASTCGI, [ ])
+ AC_DEFINE_UNQUOTED(PHP_FCGI_STATIC, $PHP_FCGI_STATIC, [ ])
+ AC_MSG_RESULT($PHP_ENABLE_FASTCGI)
INSTALL_IT="\$(INSTALL) -m 0755 \$(SAPI_CGI_PATH) \$(INSTALL_ROOT)\$(bindir)/php-cgi"
- PHP_SELECT_SAPI(cgi, program, cgi_main.c getopt.c,,'$(SAPI_CGI_PATH)')
+ PHP_SELECT_SAPI(cgi, program, $PHP_FCGI_FILES cgi_main.c getopt.c, -I$PHP_FCGI_INCLUDE,'$(SAPI_CGI_PATH)')
case $host_alias in
*darwin*)
static int isFastCGI = -1;
static char *webServerAddressList = NULL;
static FCGX_Request the_request;
-void _FCGX_FreeStream(FCGX_Stream **streamPtr, BOOL freeData);
+void _FCGX_FreeStream(FCGX_Stream **streamPtr, int freeData);
void FCGX_ShutdownPending(void)
{
_FCGX_FreeStream(streamPtr, TRUE);
}
-void _FCGX_FreeStream(FCGX_Stream **streamPtr, BOOL freeData)
+void _FCGX_FreeStream(FCGX_Stream **streamPtr, int freeData)
{
FCGX_Stream *stream = *streamPtr;
FCGX_Stream_Data *data;
-/* fcgi_config.h. Generated automatically by configure. */
-/* fcgi_config.h.in. Generated automatically from configure.in by autoheader. */
+/* hack workaround for libfcgi configure */
+#ifdef _WIN32
+#include "fcgi_config_win32.h"
+#else
+#include "main/php_config.h"
+#endif
-/* Define if you have the <arpa/inet.h> header file. */
-#define HAVE_ARPA_INET_H 1
-
-/* Define if you have the <dlfcn.h> header file. */
-#define HAVE_DLFCN_H 1
-
-/* Define if there's a fileno() prototype in stdio.h */
-#define HAVE_FILENO_PROTO 1
-
-/* Define if the fpos_t typedef is in stdio.h */
-#define HAVE_FPOS 1
-
-/* Define if you have the <inttypes.h> header file. */
-#define HAVE_INTTYPES_H 1
-
-/* Define if you have the `dnet_stub' library (-ldnet_stub). */
-/* #undef HAVE_LIBDNET_STUB */
-
-/* Define if you have the `ieee' library (-lieee). */
-/* #undef HAVE_LIBIEEE */
-
-/* Define if you have the `nsl' library (-lnsl). */
-#define HAVE_LIBNSL 1
-
-/* Define if you have the pthread library */
-#define HAVE_LIBPTHREAD 1
-
-/* Define if you have the `resolv' library (-lresolv). */
-#define HAVE_LIBRESOLV 1
-
-/* Define if you have the `socket' library (-lsocket). */
-#define HAVE_LIBSOCKET 1
-
-/* Define if you have the <limits.h> header file. */
-#define HAVE_LIMITS_H 1
-
-/* Define if you have the <memory.h> header file. */
-#define HAVE_MEMORY_H 1
-
-/* Define if you have the <netdb.h> header file. */
-/* #define HAVE_NETDB_H 1 */
-
-/* Define if you have the <netinet/in.h> header file. */
-#define HAVE_NETINET_IN_H 1
-
-/* Define if sockaddr_un in sys/un.h contains a sun_len component */
-/* #undef HAVE_SOCKADDR_UN_SUN_LEN */
-
-/* Define if the socklen_t typedef is in sys/socket.h */
-/* #undef HAVE_SOCKLEN */
-
-/* Define if you have the <stdint.h> header file. */
-/* #undef HAVE_STDINT_H */
-
-/* Define if you have the <stdlib.h> header file. */
-#define HAVE_STDLIB_H 1
-
-/* Define if you have the `strerror' function. */
-#define HAVE_STRERROR 1
-
-/* Define if you have the <strings.h> header file. */
-#define HAVE_STRINGS_H 1
-
-/* Define if you have the <string.h> header file. */
-#define HAVE_STRING_H 1
-
-/* Define if you have the <sys/param.h> header file. */
-/* #define HAVE_SYS_PARAM_H 1 */
-
-/* Define if you have the <sys/socket.h> header file. */
-/*#define HAVE_SYS_SOCKET_H 1*/
-
-/* Define if you have the <sys/stat.h> header file. */
-#define HAVE_SYS_STAT_H 1
-
-/* Define if you have the <sys/time.h> header file. */
-/*#define HAVE_SYS_TIME_H 1*/
-
-/* Define if you have the <sys/types.h> header file. */
-#define HAVE_SYS_TYPES_H 1
-
-/* Define if you have the <unistd.h> header file. */
-/*#define HAVE_UNISTD_H 1*/
-
-/* Define if va_arg(arg, long double) crashes the compiler */
-/* #undef HAVE_VA_ARG_LONG_DOUBLE_BUG */
-
-/* Name of package */
-#define PACKAGE "fcgi"
-
-/* Define if you have the ANSI C header files. */
-#define STDC_HEADERS 1
-
-/* Define if cross-process locking is required by accept() */
-#define USE_LOCKING 1
-
-/* Version number of package */
-#define VERSION "2.2.2"
-
-/* Define to empty if `const' does not conform to ANSI C. */
-/* #undef const */
-
-/* Define as `__inline' if that's what the C compiler calls it, or to nothing
- if it is not supported. */
-/* #undef inline */
-
-/* Define to `int' if <sys/types.h> does not define. */
-#define ssize_t int
\ No newline at end of file
--- /dev/null
+/* fcgi_config.h. Generated automatically by configure. */
+/* fcgi_config.h.in. Generated automatically from configure.in by autoheader. */
+
+/* Define if you have the <arpa/inet.h> header file. */
+#define HAVE_ARPA_INET_H 1
+
+/* Define if you have the <dlfcn.h> header file. */
+#define HAVE_DLFCN_H 1
+
+/* Define if there's a fileno() prototype in stdio.h */
+#define HAVE_FILENO_PROTO 1
+
+/* Define if the fpos_t typedef is in stdio.h */
+#define HAVE_FPOS 1
+
+/* Define if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define if you have the `dnet_stub' library (-ldnet_stub). */
+/* #undef HAVE_LIBDNET_STUB */
+
+/* Define if you have the `ieee' library (-lieee). */
+/* #undef HAVE_LIBIEEE */
+
+/* Define if you have the `nsl' library (-lnsl). */
+#define HAVE_LIBNSL 1
+
+/* Define if you have the pthread library */
+#define HAVE_LIBPTHREAD 1
+
+/* Define if you have the `resolv' library (-lresolv). */
+#define HAVE_LIBRESOLV 1
+
+/* Define if you have the `socket' library (-lsocket). */
+#define HAVE_LIBSOCKET 1
+
+/* Define if you have the <limits.h> header file. */
+#define HAVE_LIMITS_H 1
+
+/* Define if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define if you have the <netdb.h> header file. */
+/* #define HAVE_NETDB_H 1 */
+
+/* Define if you have the <netinet/in.h> header file. */
+#define HAVE_NETINET_IN_H 1
+
+/* Define if sockaddr_un in sys/un.h contains a sun_len component */
+/* #undef HAVE_SOCKADDR_UN_SUN_LEN */
+
+/* Define if the socklen_t typedef is in sys/socket.h */
+/* #undef HAVE_SOCKLEN */
+
+/* Define if you have the <stdint.h> header file. */
+/* #undef HAVE_STDINT_H */
+
+/* Define if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define if you have the `strerror' function. */
+#define HAVE_STRERROR 1
+
+/* Define if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define if you have the <sys/param.h> header file. */
+/* #define HAVE_SYS_PARAM_H 1 */
+
+/* Define if you have the <sys/socket.h> header file. */
+/*#define HAVE_SYS_SOCKET_H 1*/
+
+/* Define if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define if you have the <sys/time.h> header file. */
+/*#define HAVE_SYS_TIME_H 1*/
+
+/* Define if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define if you have the <unistd.h> header file. */
+/*#define HAVE_UNISTD_H 1*/
+
+/* Define if va_arg(arg, long double) crashes the compiler */
+/* #undef HAVE_VA_ARG_LONG_DOUBLE_BUG */
+
+/* Name of package */
+#define PACKAGE "fcgi"
+
+/* Define if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Define if cross-process locking is required by accept() */
+#define USE_LOCKING 1
+
+/* Version number of package */
+#define VERSION "2.2.2"
+
+/* Define to empty if `const' does not conform to ANSI C. */
+/* #undef const */
+
+/* Define as `__inline' if that's what the C compiler calls it, or to nothing
+ if it is not supported. */
+/* #undef inline */
+
+/* Define to `int' if <sys/types.h> does not define. */
+#define ssize_t int
\ No newline at end of file
DLLAPI int OS_FcgiConnect(char *bindPath);
DLLAPI int OS_Read(int fd, char * buf, size_t len);
DLLAPI int OS_Write(int fd, char * buf, size_t len);
+#ifdef _WIN32
DLLAPI int OS_SpawnChild(char *execPath, int listenFd, PROCESS_INFORMATION *pInfo, char *env);
+#else
+DLLAPI int OS_SpawnChild(char *execPath, int listenfd);
+#endif
DLLAPI int OS_AsyncReadStdin(void *buf, int len, OS_AsyncProc procPtr,
ClientData clientData);
DLLAPI int OS_AsyncRead(int fd, int offset, void *buf, int len,
*
*----------------------------------------------------------------------
*/
-int OS_SpawnChild(char *appPath, int listenFd, PROCESS_INFORMATION *pInfo, char *env)
+int OS_SpawnChild(char *appPath, int listenFd)
{
int forkResult;