Back to index

php5  5.3.10
zend_extensions.c
Go to the documentation of this file.
00001 /*
00002    +----------------------------------------------------------------------+
00003    | Zend Engine                                                          |
00004    +----------------------------------------------------------------------+
00005    | Copyright (c) 1998-2012 Zend Technologies Ltd. (http://www.zend.com) |
00006    +----------------------------------------------------------------------+
00007    | This source file is subject to version 2.00 of the Zend license,     |
00008    | that is bundled with this package in the file LICENSE, and is        | 
00009    | available through the world-wide-web at the following url:           |
00010    | http://www.zend.com/license/2_00.txt.                                |
00011    | If you did not receive a copy of the Zend license and are unable to  |
00012    | obtain it through the world-wide-web, please send a note to          |
00013    | license@zend.com so we can mail you a copy immediately.              |
00014    +----------------------------------------------------------------------+
00015    | Authors: Andi Gutmans <andi@zend.com>                                |
00016    |          Zeev Suraski <zeev@zend.com>                                |
00017    +----------------------------------------------------------------------+
00018 */
00019 
00020 /* $Id: zend_extensions.c 321634 2012-01-01 13:15:04Z felipe $ */
00021 
00022 #include "zend_extensions.h"
00023 
00024 ZEND_API zend_llist zend_extensions;
00025 static int last_resource_number;
00026 
00027 int zend_load_extension(const char *path)
00028 {
00029 #if ZEND_EXTENSIONS_SUPPORT
00030        DL_HANDLE handle;
00031        zend_extension *new_extension;
00032        zend_extension_version_info *extension_version_info;
00033 
00034        handle = DL_LOAD(path);
00035        if (!handle) {
00036 #ifndef ZEND_WIN32
00037               fprintf(stderr, "Failed loading %s:  %s\n", path, DL_ERROR());
00038 /* See http://support.microsoft.com/kb/190351 */
00039 #ifdef PHP_WIN32
00040               fflush(stderr);
00041 #endif
00042 #else
00043               fprintf(stderr, "Failed loading %s\n", path);
00044 #endif
00045               return FAILURE;
00046        }
00047 
00048        extension_version_info = (zend_extension_version_info *) DL_FETCH_SYMBOL(handle, "extension_version_info");
00049        if (!extension_version_info) {
00050               extension_version_info = (zend_extension_version_info *) DL_FETCH_SYMBOL(handle, "_extension_version_info");
00051        }
00052        new_extension = (zend_extension *) DL_FETCH_SYMBOL(handle, "zend_extension_entry");
00053        if (!new_extension) {
00054               new_extension = (zend_extension *) DL_FETCH_SYMBOL(handle, "_zend_extension_entry");
00055        }
00056        if (!extension_version_info || !new_extension) {
00057               fprintf(stderr, "%s doesn't appear to be a valid Zend extension\n", path);
00058 /* See http://support.microsoft.com/kb/190351 */
00059 #ifdef PHP_WIN32
00060               fflush(stderr);
00061 #endif
00062               DL_UNLOAD(handle);
00063               return FAILURE;
00064        }
00065 
00066 
00067        /* allow extension to proclaim compatibility with any Zend version */
00068        if (extension_version_info->zend_extension_api_no != ZEND_EXTENSION_API_NO &&(!new_extension->api_no_check || new_extension->api_no_check(ZEND_EXTENSION_API_NO) != SUCCESS)) {
00069               if (extension_version_info->zend_extension_api_no > ZEND_EXTENSION_API_NO) {
00070                      fprintf(stderr, "%s requires Zend Engine API version %d.\n"
00071                                    "The Zend Engine API version %d which is installed, is outdated.\n\n",
00072                                    new_extension->name,
00073                                    extension_version_info->zend_extension_api_no,
00074                                    ZEND_EXTENSION_API_NO);
00075 /* See http://support.microsoft.com/kb/190351 */
00076 #ifdef PHP_WIN32
00077                      fflush(stderr);
00078 #endif
00079                      DL_UNLOAD(handle);
00080                      return FAILURE;
00081               } else if (extension_version_info->zend_extension_api_no < ZEND_EXTENSION_API_NO) {
00082                      fprintf(stderr, "%s requires Zend Engine API version %d.\n"
00083                                    "The Zend Engine API version %d which is installed, is newer.\n"
00084                                    "Contact %s at %s for a later version of %s.\n\n",
00085                                    new_extension->name,
00086                                    extension_version_info->zend_extension_api_no,
00087                                    ZEND_EXTENSION_API_NO,
00088                                    new_extension->author,
00089                                    new_extension->URL,
00090                                    new_extension->name);
00091 /* See http://support.microsoft.com/kb/190351 */
00092 #ifdef PHP_WIN32
00093                      fflush(stderr);
00094 #endif
00095                      DL_UNLOAD(handle);
00096                      return FAILURE;
00097               }
00098        } else if (strcmp(ZEND_EXTENSION_BUILD_ID, extension_version_info->build_id) &&
00099                   (!new_extension->build_id_check || new_extension->build_id_check(ZEND_EXTENSION_BUILD_ID) != SUCCESS)) {
00100               fprintf(stderr, "Cannot load %s - it was built with configuration %s, whereas running engine is %s\n",
00101                                    new_extension->name, extension_version_info->build_id, ZEND_EXTENSION_BUILD_ID);
00102 /* See http://support.microsoft.com/kb/190351 */
00103 #ifdef PHP_WIN32
00104               fflush(stderr);
00105 #endif
00106               DL_UNLOAD(handle);
00107               return FAILURE;
00108        }
00109 
00110        return zend_register_extension(new_extension, handle);
00111 #else
00112        fprintf(stderr, "Extensions are not supported on this platform.\n");
00113 /* See http://support.microsoft.com/kb/190351 */
00114 #ifdef PHP_WIN32
00115        fflush(stderr);
00116 #endif
00117        return FAILURE;
00118 #endif
00119 }
00120 
00121 
00122 int zend_register_extension(zend_extension *new_extension, DL_HANDLE handle)
00123 {
00124 #if ZEND_EXTENSIONS_SUPPORT
00125        zend_extension extension;
00126 
00127        extension = *new_extension;
00128        extension.handle = handle;
00129 
00130        zend_extension_dispatch_message(ZEND_EXTMSG_NEW_EXTENSION, &extension);
00131 
00132        zend_llist_add_element(&zend_extensions, &extension);
00133 
00134        /*fprintf(stderr, "Loaded %s, version %s\n", extension.name, extension.version);*/
00135 #endif
00136 
00137        return SUCCESS;
00138 }
00139 
00140 
00141 static void zend_extension_shutdown(zend_extension *extension TSRMLS_DC)
00142 {
00143 #if ZEND_EXTENSIONS_SUPPORT
00144        if (extension->shutdown) {
00145               extension->shutdown(extension);
00146        }
00147 #endif
00148 }
00149 
00150 static int zend_extension_startup(zend_extension *extension)
00151 {
00152 #if ZEND_EXTENSIONS_SUPPORT
00153        if (extension->startup) {
00154               if (extension->startup(extension)!=SUCCESS) {
00155                      return 1;
00156               }
00157               zend_append_version_info(extension);
00158        }
00159 #endif
00160        return 0;
00161 }
00162 
00163 
00164 int zend_startup_extensions_mechanism()
00165 {
00166        /* Startup extensions mechanism */
00167        zend_llist_init(&zend_extensions, sizeof(zend_extension), (void (*)(void *)) zend_extension_dtor, 1);
00168        last_resource_number = 0;
00169        return SUCCESS;
00170 }
00171 
00172 
00173 int zend_startup_extensions()
00174 {
00175        zend_llist_apply_with_del(&zend_extensions, (int (*)(void *)) zend_extension_startup);
00176        return SUCCESS;
00177 }
00178 
00179 
00180 void zend_shutdown_extensions(TSRMLS_D)
00181 {
00182        zend_llist_apply(&zend_extensions, (llist_apply_func_t) zend_extension_shutdown TSRMLS_CC);
00183        zend_llist_destroy(&zend_extensions);
00184 }
00185 
00186 
00187 void zend_extension_dtor(zend_extension *extension)
00188 {
00189 #if ZEND_EXTENSIONS_SUPPORT && !ZEND_DEBUG
00190        if (extension->handle) {
00191               DL_UNLOAD(extension->handle);
00192        }
00193 #endif
00194 }
00195 
00196 
00197 static void zend_extension_message_dispatcher(const zend_extension *extension, int num_args, va_list args TSRMLS_DC)
00198 {
00199        int message;
00200        void *arg;
00201 
00202        if (!extension->message_handler || num_args!=2) {
00203               return;
00204        }
00205        message = va_arg(args, int);
00206        arg = va_arg(args, void *);
00207        extension->message_handler(message, arg);
00208 }
00209 
00210 
00211 ZEND_API void zend_extension_dispatch_message(int message, void *arg)
00212 {
00213        TSRMLS_FETCH();
00214 
00215        zend_llist_apply_with_arguments(&zend_extensions, (llist_apply_with_args_func_t) zend_extension_message_dispatcher TSRMLS_CC, 2, message, arg);
00216 }
00217 
00218 
00219 ZEND_API int zend_get_resource_handle(zend_extension *extension)
00220 {
00221        if (last_resource_number<ZEND_MAX_RESERVED_RESOURCES) {
00222               extension->resource_number = last_resource_number;
00223               return last_resource_number++;
00224        } else {
00225               return -1;
00226        }
00227 }
00228 
00229 
00230 ZEND_API zend_extension *zend_get_extension(const char *extension_name)
00231 {
00232        zend_llist_element *element;
00233 
00234        for (element = zend_extensions.head; element; element = element->next) {
00235               zend_extension *extension = (zend_extension *) element->data;
00236 
00237               if (!strcmp(extension->name, extension_name)) {
00238                      return extension;
00239               }
00240        }
00241        return NULL;
00242 }
00243 
00244 /*
00245  * Local variables:
00246  * tab-width: 4
00247  * c-basic-offset: 4
00248  * indent-tabs-mode: t
00249  * End:
00250  */