123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275 |
- /*
- +----------------------------------------------------------------------+
- | Copyright (c) The PHP Group |
- +----------------------------------------------------------------------+
- | This source file is subject to version 3.01 of the PHP license, |
- | that is bundled with this package in the file LICENSE, and is |
- | available through the world-wide-web at the following url: |
- | https://www.php.net/license/3_01.txt |
- | If you did not receive a copy of the PHP license and are unable to |
- | obtain it through the world-wide-web, please send a note to |
- | license@php.net so we can mail you a copy immediately. |
- +----------------------------------------------------------------------+
- | Author: Edin Kadribasic <edink@php.net> |
- +----------------------------------------------------------------------+
- */
- #include "php_embed.h"
- #include "ext/standard/php_standard.h"
- #include "ext/standard/dl_arginfo.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";
- #if defined(PHP_WIN32) && defined(ZTS)
- ZEND_TSRMLS_CACHE_DEFINE()
- #endif
- static char* php_embed_read_cookies(void)
- {
- return NULL;
- }
- static int php_embed_deactivate(void)
- {
- fflush(stdout);
- return SUCCESS;
- }
- /* Here we prefer to use write(), which is unbuffered, over fwrite(), which is
- * buffered. Using an unbuffered write operation to stdout will ensure PHP's
- * output buffering feature does not compete with a SAPI output buffer and
- * therefore we avoid situations wherein flushing the output buffer results in
- * nondeterministic behavior.
- */
- static inline size_t php_embed_single_write(const char *str, size_t str_length)
- {
- #ifdef PHP_WRITE_STDOUT
- zend_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
- }
- /* SAPIs only have unbuffered write operations. This is because PHP's output
- * buffering feature will handle any buffering of the output and invoke the
- * SAPI unbuffered write operation when it flushes the buffer.
- */
- static size_t php_embed_ub_write(const char *str, size_t str_length)
- {
- const char *ptr = str;
- size_t 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)
- {
- }
- /* The SAPI error logger that is called when the 'error_log' INI setting is not
- * set.
- *
- * https://www.php.net/manual/en/errorfunc.configuration.php#ini.error-log
- */
- static void php_embed_log_message(const char *message, int syslog_type_int)
- {
- fprintf(stderr, "%s\n", message);
- }
- static void php_embed_register_variables(zval *track_vars_array)
- {
- php_import_environment_variables(track_vars_array);
- }
- /* Module initialization (MINIT) */
- static int php_embed_startup(sapi_module_struct *sapi_module)
- {
- if (php_module_startup(sapi_module, NULL, 0) == FAILURE) {
- return FAILURE;
- }
- return SUCCESS;
- }
- EMBED_SAPI_API sapi_module_struct php_embed_module = {
- "embed", /* name */
- "PHP Embedded Library", /* pretty name */
- php_embed_startup, /* startup */
- php_module_shutdown_wrapper, /* shutdown */
- NULL, /* activate */
- php_embed_deactivate, /* deactivate */
- php_embed_ub_write, /* unbuffered write */
- php_embed_flush, /* flush */
- NULL, /* get uid */
- NULL, /* getenv */
- php_error, /* error handler */
- NULL, /* header handler */
- NULL, /* send headers handler */
- php_embed_send_header, /* send header handler */
- NULL, /* read POST data */
- php_embed_read_cookies, /* read Cookies */
- php_embed_register_variables, /* register server variables */
- php_embed_log_message, /* Log message */
- NULL, /* Get request time */
- NULL, /* Child terminate */
- STANDARD_SAPI_MODULE_PROPERTIES
- };
- /* }}} */
- static const zend_function_entry additional_functions[] = {
- ZEND_FE(dl, arginfo_dl)
- ZEND_FE_END
- };
- EMBED_SAPI_API int php_embed_init(int argc, char **argv)
- {
- #if defined(SIGPIPE) && defined(SIG_IGN)
- signal(SIGPIPE, SIG_IGN); /* ignore SIGPIPE in standalone mode so
- that sockets created via fsockopen()
- don't kill PHP if the remote site
- closes it. in apache|apxs mode apache
- does that for us! thies@thieso.net
- 20000419 */
- #endif
- #ifdef ZTS
- php_tsrm_startup();
- # ifdef PHP_WIN32
- ZEND_TSRMLS_CACHE_UPDATE();
- # endif
- #endif
- zend_signal_startup();
- /* SAPI initialization (SINIT)
- *
- * Initialize the SAPI globals (memset to 0). After this point we can set
- * SAPI globals via the SG() macro.
- *
- * Reentrancy startup.
- *
- * This also sets 'php_embed_module.ini_entries = NULL' so we cannot
- * allocate the INI entries until after this call.
- */
- sapi_startup(&php_embed_module);
- #ifdef PHP_WIN32
- _fmode = _O_BINARY; /*sets default for file streams to binary */
- setmode(_fileno(stdin), O_BINARY); /* make the stdio mode be binary */
- setmode(_fileno(stdout), O_BINARY); /* make the stdio mode be binary */
- setmode(_fileno(stderr), O_BINARY); /* make the stdio mode be binary */
- #endif
- /* This hard-coded string of INI settings is parsed and read into PHP's
- * configuration hash table at the very end of php_init_config(). This
- * means these settings will overwrite any INI settings that were set from
- * an INI file.
- *
- * To provide overwritable INI defaults, hook the ini_defaults function
- * pointer that is part of the sapi_module_struct
- * (php_embed_module.ini_defaults).
- *
- * void (*ini_defaults)(HashTable *configuration_hash);
- *
- * This callback is invoked as soon as the configuration hash table is
- * allocated so any INI settings added via this callback will have the
- * lowest precedence and will allow INI files to overwrite them.
- */
- php_embed_module.ini_entries = malloc(sizeof(HARDCODED_INI));
- memcpy(php_embed_module.ini_entries, HARDCODED_INI, sizeof(HARDCODED_INI));
- /* SAPI-provided functions. */
- php_embed_module.additional_functions = additional_functions;
- if (argv) {
- php_embed_module.executable_location = argv[0];
- }
- /* Module initialization (MINIT) */
- if (php_embed_module.startup(&php_embed_module) == FAILURE) {
- return FAILURE;
- }
- /* Do not chdir to the script's directory. This is akin to calling the CGI
- * SAPI with '-C'.
- */
- SG(options) |= SAPI_OPTION_NO_CHDIR;
- SG(request_info).argc=argc;
- SG(request_info).argv=argv;
- /* Request initialization (RINIT) */
- if (php_request_startup() == FAILURE) {
- php_module_shutdown();
- return FAILURE;
- }
- SG(headers_sent) = 1;
- SG(request_info).no_headers = 1;
- php_register_variable("PHP_SELF", "-", NULL);
- return SUCCESS;
- }
- EMBED_SAPI_API void php_embed_shutdown(void)
- {
- /* Request shutdown (RSHUTDOWN) */
- php_request_shutdown((void *) 0);
- /* Module shutdown (MSHUTDOWN) */
- php_module_shutdown();
- /* SAPI shutdown (SSHUTDOWN) */
- 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;
- }
- }
|