Line data Source code
1 : /*
2 : +----------------------------------------------------------------------+
3 : | COLOPL PHP TimeShifter. |
4 : +----------------------------------------------------------------------+
5 : | Copyright (c) COLOPL, Inc. |
6 : +----------------------------------------------------------------------+
7 : | This source file is subject to the BSD-3-Clause license that is |
8 : | bundled with this package in the file LICENSE. |
9 : +----------------------------------------------------------------------+
10 : | Author: Go Kudo <g-kudo@colopl.co.jp> |
11 : +----------------------------------------------------------------------+
12 : */
13 : #ifdef HAVE_CONFIG_H
14 : # include "config.h"
15 : #endif
16 :
17 : #include "php.h"
18 : #include "ext/date/php_date.h"
19 : #include "ext/standard/info.h"
20 : #include "php_colopl_timeshifter.h"
21 : #include "colopl_timeshifter_arginfo.h"
22 :
23 : #include "shared_memory.h"
24 : #include "hook.h"
25 :
26 : /* True global */
27 : typedef struct {
28 : bool is_hooked;
29 : timelib_rel_time shift_interval;
30 : } timeshifter_global_t;
31 : sm_t timeshifter_global;
32 :
33 : /* Module global */
34 : ZEND_DECLARE_MODULE_GLOBALS(colopl_timeshifter);
35 :
36 : PHP_INI_BEGIN()
37 : STD_PHP_INI_ENTRY("colopl_timeshifter.is_hook_pdo_mysql", "1", PHP_INI_SYSTEM, OnUpdateBool, is_hook_pdo_mysql, zend_colopl_timeshifter_globals, colopl_timeshifter_globals)
38 : STD_PHP_INI_ENTRY("colopl_timeshifter.is_hook_request_time", "1", PHP_INI_SYSTEM, OnUpdateBool, is_hook_request_time, zend_colopl_timeshifter_globals, colopl_timeshifter_globals)
39 : STD_PHP_INI_ENTRY("colopl_timeshifter.usleep_sec", "1", PHP_INI_ALL, OnUpdateLong, usleep_sec, zend_colopl_timeshifter_globals, colopl_timeshifter_globals)
40 : STD_PHP_INI_ENTRY("colopl_timeshifter.is_restore_per_request", "0", PHP_INI_ALL, OnUpdateBool, is_restore_per_request, zend_colopl_timeshifter_globals, colopl_timeshifter_globals)
41 : PHP_INI_END()
42 :
43 448 : void get_shift_interval(timelib_rel_time *time) {
44 : timeshifter_global_t tg;
45 :
46 448 : sm_read(×hifter_global, &tg);
47 448 : if (tg.is_hooked) {
48 448 : memcpy(time, &tg.shift_interval, sizeof(timelib_rel_time));
49 : }
50 448 : }
51 :
52 48 : void set_is_hooked(bool flag) {
53 : timeshifter_global_t tg;
54 :
55 48 : sm_read(×hifter_global, &tg);
56 48 : if (tg.is_hooked != flag) {
57 48 : tg.is_hooked = flag;
58 48 : sm_write(×hifter_global, &tg);
59 : }
60 48 : }
61 :
62 936 : bool get_is_hooked() {
63 : timeshifter_global_t tg;
64 :
65 936 : sm_read(×hifter_global, &tg);
66 936 : return tg.is_hooked;
67 : }
68 :
69 176 : ZEND_FUNCTION(Colopl_ColoplTimeShifter_register_hook)
70 : {
71 : zval *intern;
72 : timeshifter_global_t tg;
73 :
74 176 : ZEND_PARSE_PARAMETERS_START(1, 1)
75 176 : Z_PARAM_OBJECT_OF_CLASS(intern, php_date_get_interval_ce())
76 176 : ZEND_PARSE_PARAMETERS_END();
77 :
78 : /* Copy interval. */
79 176 : sm_read(×hifter_global, &tg);
80 176 : memcpy(&tg.shift_interval, Z_PHPINTERVAL_P(intern)->diff, sizeof(timelib_rel_time));
81 176 : tg.is_hooked = true;
82 176 : if (!sm_write(×hifter_global, &tg)) {
83 0 : RETURN_FALSE;
84 : }
85 :
86 176 : if (COLOPL_TS_G(is_hook_request_time)) {
87 172 : apply_request_time_hook();
88 : }
89 :
90 176 : RETURN_TRUE;
91 : }
92 :
93 48 : ZEND_FUNCTION(Colopl_ColoplTimeShifter_unregister_hook)
94 : {
95 48 : set_is_hooked(false);
96 48 : }
97 :
98 16 : ZEND_FUNCTION(Colopl_ColoplTimeShifter_is_hooked)
99 : {
100 16 : RETURN_BOOL(get_is_hooked());
101 : }
102 :
103 164 : PHP_MINIT_FUNCTION(colopl_timeshifter)
104 : {
105 164 : REGISTER_INI_ENTRIES();
106 :
107 164 : if (COLOPL_TS_G(is_hook_pdo_mysql) == true) {
108 164 : register_pdo_hook();
109 : }
110 :
111 164 : if (!register_hooks()) {
112 0 : return FAILURE;
113 : }
114 :
115 164 : if (get_is_hooked() && COLOPL_TS_G(is_hook_request_time)) {
116 0 : apply_request_time_hook();
117 : }
118 :
119 164 : COLOPL_TS_G(pdo_mysql_orig_methods) = NULL;
120 :
121 164 : return SUCCESS;
122 : }
123 :
124 164 : PHP_MSHUTDOWN_FUNCTION(colopl_timeshifter)
125 : {
126 164 : UNREGISTER_INI_ENTRIES();
127 :
128 164 : if (!unregister_hooks()) {
129 0 : return FAILURE;
130 : }
131 :
132 164 : return SUCCESS;
133 : }
134 :
135 164 : PHP_RINIT_FUNCTION(colopl_timeshifter)
136 : {
137 : # if defined(ZTS) && defined(COMPILE_DL_COLOPL_TIMESHIFTER)
138 82 : ZEND_TSRMLS_CACHE_UPDATE();
139 : # endif
140 :
141 164 : COLOPL_TS_G(orig_request_time) = 0;
142 164 : COLOPL_TS_G(orig_request_time_float) = 0.0;
143 :
144 164 : return SUCCESS;
145 : }
146 :
147 164 : PHP_RSHUTDOWN_FUNCTION(colopl_timeshifter)
148 : {
149 164 : if (COLOPL_TS_G(is_restore_per_request) && get_is_hooked()) {
150 0 : set_is_hooked(false);
151 0 : if (!unregister_hooks()) {
152 0 : return FAILURE;
153 : }
154 : }
155 :
156 164 : return SUCCESS;
157 : }
158 :
159 4 : PHP_MINFO_FUNCTION(colopl_timeshifter)
160 : {
161 4 : php_info_print_table_start();
162 4 : php_info_print_table_header(2, "colopl_timeshifter support", "enabled");
163 4 : php_info_print_table_row(2, "timeshifter version", PHP_COLOPL_TIMESHIFTER_VERSION);
164 4 : php_info_print_table_end();
165 4 : }
166 :
167 164 : PHP_GINIT_FUNCTION(colopl_timeshifter)
168 : {
169 : timeshifter_global_t tg;
170 :
171 : # if defined(ZTS) && defined(COMPILE_DL_COLOPL_TIMESHIFTER)
172 82 : ZEND_TSRMLS_CACHE_UPDATE();
173 : # endif
174 :
175 164 : sm_init(×hifter_global, sizeof(timeshifter_global_t));
176 164 : sm_read(×hifter_global, &tg);
177 164 : tg.is_hooked = false;
178 164 : sm_write(×hifter_global, &tg);
179 164 : }
180 :
181 164 : PHP_GSHUTDOWN_FUNCTION(colopl_timeshifter)
182 : {
183 164 : sm_free(×hifter_global);
184 164 : }
185 :
186 : zend_module_entry colopl_timeshifter_module_entry = {
187 : STANDARD_MODULE_HEADER,
188 : "colopl_timeshifter",
189 : ext_functions,
190 : PHP_MINIT(colopl_timeshifter),
191 : PHP_MSHUTDOWN(colopl_timeshifter),
192 : PHP_RINIT(colopl_timeshifter),
193 : PHP_RSHUTDOWN(colopl_timeshifter),
194 : PHP_MINFO(colopl_timeshifter),
195 : PHP_COLOPL_TIMESHIFTER_VERSION,
196 : PHP_MODULE_GLOBALS(colopl_timeshifter),
197 : PHP_GINIT(colopl_timeshifter),
198 : PHP_GSHUTDOWN(colopl_timeshifter),
199 : NULL,
200 : STANDARD_MODULE_PROPERTIES_EX
201 : };
202 :
203 : #ifdef COMPILE_DL_COLOPL_TIMESHIFTER
204 : # ifdef ZTS
205 : ZEND_TSRMLS_CACHE_DEFINE()
206 : # endif
207 164 : ZEND_GET_MODULE(colopl_timeshifter)
208 : #endif
|