forked from php/frankenphp
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathemulate_php_cli.c
More file actions
135 lines (113 loc) · 4.09 KB
/
emulate_php_cli.c
File metadata and controls
135 lines (113 loc) · 4.09 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#include <SAPI.h>
#include <Zend/zend_alloc.h>
#include <Zend/zend_exceptions.h>
#include <Zend/zend_interfaces.h>
#include <Zend/zend_types.h>
#include <errno.h>
#include <ext/spl/spl_exceptions.h>
#include <ext/standard/head.h>
#include <inttypes.h>
#include <php.h>
#include <php_config.h>
#include <php_ini.h>
#include <php_main.h>
#include <php_output.h>
#include <php_variables.h>
#include <php_version.h>
/*
* CLI code is adapted from
* https://github.com/php/php-src/blob/master/sapi/cli/php_cli.c Copyright (c)
* The PHP Group Licensed under The PHP License Original uthors: Edin Kadribasic
* <edink@php.net>, Marcus Boerger <helly@php.net> and Johannes Schlueter
* <johannes@php.net> Parts based on CGI SAPI Module by Rasmus Lerdorf, Stig
* Bakken and Zeev Suraski
*/
static void cli_register_file_handles(bool no_close) /* {{{ */
{
php_stream *s_in, *s_out, *s_err;
php_stream_context *sc_in = NULL, *sc_out = NULL, *sc_err = NULL;
zend_constant ic, oc, ec;
s_in = php_stream_open_wrapper_ex("php://stdin", "rb", 0, NULL, sc_in);
s_out = php_stream_open_wrapper_ex("php://stdout", "wb", 0, NULL, sc_out);
s_err = php_stream_open_wrapper_ex("php://stderr", "wb", 0, NULL, sc_err);
if (s_in == NULL || s_out == NULL || s_err == NULL) {
if (s_in)
php_stream_close(s_in);
if (s_out)
php_stream_close(s_out);
if (s_err)
php_stream_close(s_err);
return;
}
if (no_close) {
s_in->flags |= PHP_STREAM_FLAG_NO_CLOSE;
s_out->flags |= PHP_STREAM_FLAG_NO_CLOSE;
s_err->flags |= PHP_STREAM_FLAG_NO_CLOSE;
}
/*s_in_process = s_in;*/
php_stream_to_zval(s_in, &ic.value);
php_stream_to_zval(s_out, &oc.value);
php_stream_to_zval(s_err, &ec.value);
ZEND_CONSTANT_SET_FLAGS(&ic, CONST_CS, 0);
ic.name = zend_string_init_interned("STDIN", sizeof("STDIN") - 1, 0);
zend_register_constant(&ic);
ZEND_CONSTANT_SET_FLAGS(&oc, CONST_CS, 0);
oc.name = zend_string_init_interned("STDOUT", sizeof("STDOUT") - 1, 0);
zend_register_constant(&oc);
ZEND_CONSTANT_SET_FLAGS(&ec, CONST_CS, 0);
ec.name = zend_string_init_interned("STDERR", sizeof("STDERR") - 1, 0);
zend_register_constant(&ec);
}
/* }}} */
static void sapi_cli_register_variables(zval *track_vars_array) /* {{{ */
{
size_t len = strlen(cli_script);
char *docroot = "";
/*
* In CGI mode, we consider the environment to be a part of the server
* variables
*/
php_import_environment_variables(track_vars_array);
/* Build the special-case PHP_SELF variable for the CLI version */
register_server_variable_filtered("PHP_SELF", &cli_script, &len,
track_vars_array);
register_server_variable_filtered("SCRIPT_NAME", &cli_script, &len,
track_vars_array);
/* filenames are empty for stdin */
register_server_variable_filtered("SCRIPT_FILENAME", &cli_script, &len,
track_vars_array);
register_server_variable_filtered("PATH_TRANSLATED", &cli_script, &len,
track_vars_array);
/* just make it available */
len = 0U;
register_server_variable_filtered("DOCUMENT_ROOT", &docroot, &len,
track_vars_array);
}
/* }}} */
void *emulate_script_cli(void *arg) {
void *exit_status;
bool eval = (bool)arg;
/*
* The SAPI name "cli" is hardcoded into too many programs... let's usurp it.
*/
php_embed_module.name = "cli";
php_embed_module.pretty_name = "PHP CLI embedded in FrankenPHP";
php_embed_module.register_server_variables = sapi_cli_register_variables;
php_embed_init(cli_argc, cli_argv);
cli_register_file_handles(false);
zend_first_try {
if (eval) {
/* evaluate the cli_script as literal PHP code (php-cli -r "...") */
zend_eval_string_ex(cli_script, NULL, "Command line code", 1);
} else {
zend_file_handle file_handle;
zend_stream_init_filename(&file_handle, cli_script);
CG(skip_shebang) = 1;
php_execute_script(&file_handle);
}
}
zend_end_try();
exit_status = (void *)(intptr_t)EG(exit_status);
php_embed_shutdown();
return exit_status;
}