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