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