xref: /PHP-7.4/sapi/embed/php_embed.c (revision 2d3bc71e)
1 /*
2    +----------------------------------------------------------------------+
3    | PHP Version 7                                                        |
4    +----------------------------------------------------------------------+
5    | Copyright (c) The PHP Group                                          |
6    +----------------------------------------------------------------------+
7    | This source file is subject to version 3.01 of the PHP license,      |
8    | that is bundled with this package in the file LICENSE, and is        |
9    | available through the world-wide-web at the following url:           |
10    | http://www.php.net/license/3_01.txt                                  |
11    | If you did not receive a copy of the PHP license and are unable to   |
12    | obtain it through the world-wide-web, please send a note to          |
13    | license@php.net so we can mail you a copy immediately.               |
14    +----------------------------------------------------------------------+
15    | Author: Edin Kadribasic <edink@php.net>                              |
16    +----------------------------------------------------------------------+
17 */
18 
19 #include "php_embed.h"
20 #include "ext/standard/php_standard.h"
21 
22 #ifdef PHP_WIN32
23 #include <io.h>
24 #include <fcntl.h>
25 #endif
26 
27 const char HARDCODED_INI[] =
28 	"html_errors=0\n"
29 	"register_argc_argv=1\n"
30 	"implicit_flush=1\n"
31 	"output_buffering=0\n"
32 	"max_execution_time=0\n"
33 	"max_input_time=-1\n\0";
34 
35 #if defined(PHP_WIN32) && defined(ZTS)
ZEND_TSRMLS_CACHE_DEFINE()36 ZEND_TSRMLS_CACHE_DEFINE()
37 #endif
38 
39 static char* php_embed_read_cookies(void)
40 {
41 	return NULL;
42 }
43 
php_embed_deactivate(void)44 static int php_embed_deactivate(void)
45 {
46 	fflush(stdout);
47 	return SUCCESS;
48 }
49 
php_embed_single_write(const char * str,size_t str_length)50 static inline size_t php_embed_single_write(const char *str, size_t str_length)
51 {
52 #ifdef PHP_WRITE_STDOUT
53 	zend_long ret;
54 
55 	ret = write(STDOUT_FILENO, str, str_length);
56 	if (ret <= 0) return 0;
57 	return ret;
58 #else
59 	size_t ret;
60 
61 	ret = fwrite(str, 1, MIN(str_length, 16384), stdout);
62 	return ret;
63 #endif
64 }
65 
66 
php_embed_ub_write(const char * str,size_t str_length)67 static size_t php_embed_ub_write(const char *str, size_t str_length)
68 {
69 	const char *ptr = str;
70 	size_t remaining = str_length;
71 	size_t ret;
72 
73 	while (remaining > 0) {
74 		ret = php_embed_single_write(ptr, remaining);
75 		if (!ret) {
76 			php_handle_aborted_connection();
77 		}
78 		ptr += ret;
79 		remaining -= ret;
80 	}
81 
82 	return str_length;
83 }
84 
php_embed_flush(void * server_context)85 static void php_embed_flush(void *server_context)
86 {
87 	if (fflush(stdout)==EOF) {
88 		php_handle_aborted_connection();
89 	}
90 }
91 
php_embed_send_header(sapi_header_struct * sapi_header,void * server_context)92 static void php_embed_send_header(sapi_header_struct *sapi_header, void *server_context)
93 {
94 }
95 
php_embed_log_message(char * message,int syslog_type_int)96 static void php_embed_log_message(char *message, int syslog_type_int)
97 {
98 	fprintf (stderr, "%s\n", message);
99 }
100 
php_embed_register_variables(zval * track_vars_array)101 static void php_embed_register_variables(zval *track_vars_array)
102 {
103 	php_import_environment_variables(track_vars_array);
104 }
105 
php_embed_startup(sapi_module_struct * sapi_module)106 static int php_embed_startup(sapi_module_struct *sapi_module)
107 {
108 	if (php_module_startup(sapi_module, NULL, 0)==FAILURE) {
109 		return FAILURE;
110 	}
111 	return SUCCESS;
112 }
113 
114 EMBED_SAPI_API sapi_module_struct php_embed_module = {
115 	"embed",                       /* name */
116 	"PHP Embedded Library",        /* pretty name */
117 
118 	php_embed_startup,              /* startup */
119 	php_module_shutdown_wrapper,   /* shutdown */
120 
121 	NULL,                          /* activate */
122 	php_embed_deactivate,           /* deactivate */
123 
124 	php_embed_ub_write,             /* unbuffered write */
125 	php_embed_flush,                /* flush */
126 	NULL,                          /* get uid */
127 	NULL,                          /* getenv */
128 
129 	php_error,                     /* error handler */
130 
131 	NULL,                          /* header handler */
132 	NULL,                          /* send headers handler */
133 	php_embed_send_header,          /* send header handler */
134 
135 	NULL,                          /* read POST data */
136 	php_embed_read_cookies,         /* read Cookies */
137 
138 	php_embed_register_variables,   /* register server variables */
139 	php_embed_log_message,          /* Log message */
140 	NULL,							/* Get request time */
141 	NULL,							/* Child terminate */
142 
143 	STANDARD_SAPI_MODULE_PROPERTIES
144 };
145 /* }}} */
146 
147 /* {{{ arginfo ext/standard/dl.c */
148 ZEND_BEGIN_ARG_INFO(arginfo_dl, 0)
149 	ZEND_ARG_INFO(0, extension_filename)
150 ZEND_END_ARG_INFO()
151 /* }}} */
152 
153 static const zend_function_entry additional_functions[] = {
154 	ZEND_FE(dl, arginfo_dl)
155 	{NULL, NULL, NULL}
156 };
157 
php_embed_init(int argc,char ** argv)158 EMBED_SAPI_API int php_embed_init(int argc, char **argv)
159 {
160 	zend_llist global_vars;
161 
162 #if defined(SIGPIPE) && defined(SIG_IGN)
163 	signal(SIGPIPE, SIG_IGN); /* ignore SIGPIPE in standalone mode so
164 								 that sockets created via fsockopen()
165 								 don't kill PHP if the remote site
166 								 closes it.  in apache|apxs mode apache
167 								 does that for us!  thies@thieso.net
168 								 20000419 */
169 #endif
170 
171 #ifdef ZTS
172   php_tsrm_startup();
173 # ifdef PHP_WIN32
174   ZEND_TSRMLS_CACHE_UPDATE();
175 # endif
176 #endif
177 
178 	zend_signal_startup();
179 
180   sapi_startup(&php_embed_module);
181 
182 #ifdef PHP_WIN32
183   _fmode = _O_BINARY;			/*sets default for file streams to binary */
184   setmode(_fileno(stdin), O_BINARY);		/* make the stdio mode be binary */
185   setmode(_fileno(stdout), O_BINARY);		/* make the stdio mode be binary */
186   setmode(_fileno(stderr), O_BINARY);		/* make the stdio mode be binary */
187 #endif
188 
189   php_embed_module.ini_entries = malloc(sizeof(HARDCODED_INI));
190   memcpy(php_embed_module.ini_entries, HARDCODED_INI, sizeof(HARDCODED_INI));
191 
192   php_embed_module.additional_functions = additional_functions;
193 
194   if (argv) {
195 	php_embed_module.executable_location = argv[0];
196   }
197 
198   if (php_embed_module.startup(&php_embed_module)==FAILURE) {
199 	  return FAILURE;
200   }
201 
202   zend_llist_init(&global_vars, sizeof(char *), NULL, 0);
203 
204   /* Set some Embedded PHP defaults */
205   SG(options) |= SAPI_OPTION_NO_CHDIR;
206   SG(request_info).argc=argc;
207   SG(request_info).argv=argv;
208 
209   if (php_request_startup()==FAILURE) {
210 	  php_module_shutdown();
211 	  return FAILURE;
212   }
213 
214   SG(headers_sent) = 1;
215   SG(request_info).no_headers = 1;
216   php_register_variable("PHP_SELF", "-", NULL);
217 
218   return SUCCESS;
219 }
220 
php_embed_shutdown(void)221 EMBED_SAPI_API void php_embed_shutdown(void)
222 {
223 	php_request_shutdown((void *) 0);
224 	php_module_shutdown();
225 	sapi_shutdown();
226 #ifdef ZTS
227     tsrm_shutdown();
228 #endif
229 	if (php_embed_module.ini_entries) {
230 		free(php_embed_module.ini_entries);
231 		php_embed_module.ini_entries = NULL;
232 	}
233 }
234