LCOV - code coverage report
Current view: top level - ext - colopl_timeshifter.c (source / functions) Coverage Total Hit
Test: Extension code coverage Lines: 90.5 % 74 67
Test Date: 2026-05-15 07:07:45 Functions: 100.0 % 14 14

            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(&timeshifter_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(&timeshifter_global, &tg);
      56           48 :         if (tg.is_hooked != flag) {
      57           48 :                 tg.is_hooked = flag;
      58           48 :                 sm_write(&timeshifter_global, &tg);
      59              :         }
      60           48 : }
      61              : 
      62          936 : bool get_is_hooked() {
      63              :         timeshifter_global_t tg;
      64              : 
      65          936 :         sm_read(&timeshifter_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(&timeshifter_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(&timeshifter_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(&timeshifter_global, sizeof(timeshifter_global_t));
     176          164 :         sm_read(&timeshifter_global, &tg);
     177          164 :         tg.is_hooked = false;
     178          164 :         sm_write(&timeshifter_global, &tg);
     179          164 : }
     180              : 
     181          164 : PHP_GSHUTDOWN_FUNCTION(colopl_timeshifter)
     182              : {
     183          164 :         sm_free(&timeshifter_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
        

Generated by: LCOV version 2.0-1