#include "php_embed.h"
#include "ext/standard/php_standard.h"
#ifdef PHP_WIN32
#include <io.h>
#include <fcntl.h>
#endif
const char HARDCODED_INI[] =
"html_errors=0\n"
"register_argc_argv=1\n"
"implicit_flush=1\n"
"output_buffering=0\n"
"max_execution_time=0\n"
"max_input_time=-1\n\0";
static char* php_embed_read_cookies(TSRMLS_D)
{
return NULL;
}
static int php_embed_deactivate(TSRMLS_D)
{
fflush(stdout);
return SUCCESS;
}
static inline size_t php_embed_single_write(const char *str, uint str_length)
{
#ifdef PHP_WRITE_STDOUT
long ret;
ret = write(STDOUT_FILENO, str, str_length);
if (ret <= 0) return 0;
return ret;
#else
size_t ret;
ret = fwrite(str, 1, MIN(str_length, 16384), stdout);
return ret;
#endif
}
static int php_embed_ub_write(const char *str, uint str_length TSRMLS_DC)
{
const char *ptr = str;
uint remaining = str_length;
size_t ret;
while (remaining > 0) {
ret = php_embed_single_write(ptr, remaining);
if (!ret) {
php_handle_aborted_connection();
}
ptr += ret;
remaining -= ret;
}
return str_length;
}
static void php_embed_flush(void *server_context)
{
if (fflush(stdout)==EOF) {
php_handle_aborted_connection();
}
}
static void php_embed_send_header(sapi_header_struct *sapi_header, void *server_context TSRMLS_DC)
{
}
static void php_embed_log_message(char *message TSRMLS_DC)
{
fprintf (stderr, "%s\n", message);
}
static void php_embed_register_variables(zval *track_vars_array TSRMLS_DC)
{
php_import_environment_variables(track_vars_array TSRMLS_CC);
}
static int php_embed_startup(sapi_module_struct *sapi_module)
{
if (php_module_startup(sapi_module, NULL, 0)==FAILURE) {
return FAILURE;
}
return SUCCESS;
}
extern EMBED_SAPI_API sapi_module_struct php_embed_module = {
"embed",
"PHP Embedded Library",
php_embed_startup,
php_module_shutdown_wrapper,
NULL,
php_embed_deactivate,
php_embed_ub_write,
php_embed_flush,
NULL,
NULL,
php_error,
NULL,
NULL,
php_embed_send_header,
NULL,
php_embed_read_cookies,
php_embed_register_variables,
php_embed_log_message,
NULL,
NULL,
STANDARD_SAPI_MODULE_PROPERTIES
};
ZEND_BEGIN_ARG_INFO(arginfo_dl, 0)
ZEND_ARG_INFO(0, extension_filename)
ZEND_END_ARG_INFO()
static const zend_function_entry additional_functions[] = {
ZEND_FE(dl, arginfo_dl)
{NULL, NULL, NULL}
};
EMBED_SAPI_API int php_embed_init(int argc, char **argv PTSRMLS_DC)
{
zend_llist global_vars;
#ifdef ZTS
void ***tsrm_ls = NULL;
#endif
#ifdef HAVE_SIGNAL_H
#if defined(SIGPIPE) && defined(SIG_IGN)
signal(SIGPIPE, SIG_IGN);
#endif
#endif
#ifdef ZTS
tsrm_startup(1, 1, 0, NULL);
tsrm_ls = ts_resource(0);
*ptsrm_ls = tsrm_ls;
#endif
sapi_startup(&php_embed_module);
#ifdef PHP_WIN32
_fmode = _O_BINARY;
setmode(_fileno(stdin), O_BINARY);
setmode(_fileno(stdout), O_BINARY);
setmode(_fileno(stderr), O_BINARY);
#endif
php_embed_module.ini_entries = malloc(sizeof(HARDCODED_INI));
memcpy(php_embed_module.ini_entries, HARDCODED_INI, sizeof(HARDCODED_INI));
php_embed_module.additional_functions = additional_functions;
if (argv) {
php_embed_module.executable_location = argv[0];
}
if (php_embed_module.startup(&php_embed_module)==FAILURE) {
return FAILURE;
}
zend_llist_init(&global_vars, sizeof(char *), NULL, 0);
SG(options) |= SAPI_OPTION_NO_CHDIR;
SG(request_info).argc=argc;
SG(request_info).argv=argv;
if (php_request_startup(TSRMLS_C)==FAILURE) {
php_module_shutdown(TSRMLS_C);
return FAILURE;
}
SG(headers_sent) = 1;
SG(request_info).no_headers = 1;
php_register_variable("PHP_SELF", "-", NULL TSRMLS_CC);
return SUCCESS;
}
EMBED_SAPI_API void php_embed_shutdown(TSRMLS_D)
{
php_request_shutdown((void *) 0);
php_module_shutdown(TSRMLS_C);
sapi_shutdown();
#ifdef ZTS
tsrm_shutdown();
#endif
if (php_embed_module.ini_entries) {
free(php_embed_module.ini_entries);
php_embed_module.ini_entries = NULL;
}
}