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