diff --git a/zend/module.h b/zend/module.h index 7902f8e9..fe10c0c0 100644 --- a/zend/module.h +++ b/zend/module.h @@ -8,15 +8,15 @@ * from an ~user directory to be able to make changes to the globalle running * apache process, and for example make changes to catch data from other websites * running on the same host. - * - * However, people who are in a position to write C++ and deploy code however, + * + * However, people who are in a position to write C++ and deploy code however, * already _ARE_ in a position to do dangerous things. For them we do not want * these safety checks. In fact, we want to offer raw access, so that they can * open modules - no matter what. So we had to make our own copy of the dl() * function, and because we're here in C++ context, we do it a little nicer * than the original C++ code. This module class is a utility class used by * our own dl() implementation. - * + * * @author Emiel Bruijntjes * @copyright 2015 Copernica BV */ @@ -25,7 +25,7 @@ * Set up namespace */ namespace Php { - + /** * Class definition */ @@ -37,13 +37,13 @@ class Module * @var void* */ void *_handle; - + /** * The module entry * @var zend_module_entry */ zend_module_entry *_entry = nullptr; - + /** * Internal helper class with persistent modules @@ -56,32 +56,32 @@ class Module * @var std::set */ std::set _handles; - + public: /** * Constructor */ Persistent() {} - + /** * Destructor */ - virtual ~Persistent() + virtual ~Persistent() { // remove all handles while (!_handles.empty()) { // get first handle auto iter = _handles.begin(); - + // remove the handle DL_UNLOAD(*iter); - + // remove from set _handles.erase(iter); } } - + /** * Check whether a handle is already persistently opened * @param handle @@ -91,7 +91,7 @@ class Module { return _handles.find(handle) != _handles.end(); } - + /** * Add a library persistently * @param module @@ -112,11 +112,11 @@ class Module public: /** * Constructor - * + * * A module can be loaded persistently. This means that the variables in * the module will keep in scope for as long as Apache runs, even though * the extension is not active in other page views - * + * * @param module Name of the module * @param persistent Should it be loaded persistently */ @@ -124,27 +124,27 @@ class Module { // the path we're going to load ExtensionPath path(module); - + // load the module _handle = DL_LOAD(path); - + // handle should be valid if (!_handle) return; - + // if we have to open it persistently, we open it for a second time so that // the refcounter always stays 1 or higher if (persistent && !_persistent.contains(_handle)) _persistent.add(module); - + // we have to call the get_module() function Symbol get_module(_handle, "get_module"); - + // was the get_module() function found if (!get_module) return; // retrieve the module entry _entry = get_module(); } - + /** * Destructor */ @@ -153,7 +153,7 @@ class Module // if the handle is still valid, we have to unload it if (_handle) DL_UNLOAD((DL_HANDLE)_handle); } - + /** * Check if the module is valid * @return bool @@ -162,14 +162,14 @@ class Module { // module-entry must exist if (!_handle || !_entry) return false; - + // check api compatibility if (_entry->zend_api != ZEND_MODULE_API_NO) return false; - + // and other stuff return strcmp(_entry->build_id, ZEND_MODULE_BUILD_ID) == 0; } - + /** * Start the module * @return bool @@ -178,22 +178,26 @@ class Module { // this is not possible if the module is invalid in the first place if (!valid()) return false; - + // the Zend engine sets a number of properties in the entry class, we do that here too // note that it would be better to call zend_next_free_module() to find the next module // number, but some users complain that this function is not always available _entry->type = MODULE_TEMPORARY; _entry->module_number = zend_hash_num_elements(&module_registry) + 1; _entry->handle = _handle; - + // @todo does loading an extension even work in a multi-threading setup? - + // register the module, this apparently returns a copied entry pointer +#if PHP_VERSION_ID < 80400 auto *entry = zend_register_module_ex(_entry); +#else + auto *entry = zend_register_module_ex(_entry, MODULE_PERSISTENT); +#endif // forget the entry, so that a new call to start() will fail too _entry = nullptr; - + // leap out on failure if (entry == NULL) return false; @@ -206,18 +210,18 @@ class Module // call the startup function if (entry->request_startup_func(MODULE_TEMPORARY, entry->module_number) == FAILURE) return false; } - + // all is ok, we can forget about the handle now, so that is won't get destructed _handle = nullptr; // enable full-table-cleanup, because inside the Zend-engine this is done too EG(full_tables_cleanup) = 1; - + // we're ready return true; } }; - + /** * End of namespace */