1 : /*
2 : +----------------------------------------------------------------------+
3 : | Zend Engine |
4 : +----------------------------------------------------------------------+
5 : | Copyright (c) 1998-2009 Zend Technologies Ltd. (http://www.zend.com) |
6 : +----------------------------------------------------------------------+
7 : | This source file is subject to version 2.00 of the Zend 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.zend.com/license/2_00.txt. |
11 : | If you did not receive a copy of the Zend license and are unable to |
12 : | obtain it through the world-wide-web, please send a note to |
13 : | license@zend.com so we can mail you a copy immediately. |
14 : +----------------------------------------------------------------------+
15 : | Authors: Andi Gutmans <andi@zend.com> |
16 : | Zeev Suraski <zeev@zend.com> |
17 : +----------------------------------------------------------------------+
18 : */
19 :
20 : /* $Id: zend_extensions.c 286859 2009-08-06 01:33:54Z scottmac $ */
21 :
22 : #include "zend_extensions.h"
23 :
24 : ZEND_API zend_llist zend_extensions;
25 : static int last_resource_number;
26 :
27 : int zend_load_extension(const char *path) /* {{{ */
28 0 : {
29 : #if ZEND_EXTENSIONS_SUPPORT
30 : DL_HANDLE handle;
31 : zend_extension *new_extension;
32 : zend_extension_version_info *extension_version_info;
33 :
34 0 : handle = DL_LOAD(path);
35 0 : if (!handle) {
36 : #ifndef ZEND_WIN32
37 0 : fprintf(stderr, "Failed loading %s: %s\n", path, DL_ERROR());
38 : #else
39 : fprintf(stderr, "Failed loading %s\n", path);
40 : #endif
41 0 : return FAILURE;
42 : }
43 :
44 0 : extension_version_info = (zend_extension_version_info *) DL_FETCH_SYMBOL(handle, "extension_version_info");
45 0 : if (!extension_version_info) {
46 0 : extension_version_info = (zend_extension_version_info *) DL_FETCH_SYMBOL(handle, "_extension_version_info");
47 : }
48 0 : new_extension = (zend_extension *) DL_FETCH_SYMBOL(handle, "zend_extension_entry");
49 0 : if (!new_extension) {
50 0 : new_extension = (zend_extension *) DL_FETCH_SYMBOL(handle, "_zend_extension_entry");
51 : }
52 0 : if (!extension_version_info || !new_extension) {
53 0 : fprintf(stderr, "%s doesn't appear to be a valid Zend extension\n", path);
54 0 : DL_UNLOAD(handle);
55 0 : return FAILURE;
56 : }
57 :
58 :
59 : /* allow extension to proclaim compatibility with any Zend version */
60 0 : 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)) {
61 0 : if (extension_version_info->zend_extension_api_no > ZEND_EXTENSION_API_NO) {
62 0 : fprintf(stderr, "%s requires Zend Engine API version %d.\n"
63 : "The Zend Engine API version %d which is installed, is outdated.\n\n",
64 : new_extension->name,
65 : extension_version_info->zend_extension_api_no,
66 : ZEND_EXTENSION_API_NO);
67 0 : DL_UNLOAD(handle);
68 0 : return FAILURE;
69 0 : } else if (extension_version_info->zend_extension_api_no < ZEND_EXTENSION_API_NO) {
70 0 : fprintf(stderr, "%s requires Zend Engine API version %d.\n"
71 : "The Zend Engine API version %d which is installed, is newer.\n"
72 : "Contact %s at %s for a later version of %s.\n\n",
73 : new_extension->name,
74 : extension_version_info->zend_extension_api_no,
75 : ZEND_EXTENSION_API_NO,
76 : new_extension->author,
77 : new_extension->URL,
78 : new_extension->name);
79 0 : DL_UNLOAD(handle);
80 0 : return FAILURE;
81 : }
82 0 : } else if (strcmp(ZEND_EXTENSION_BUILD_ID, extension_version_info->build_id) &&
83 : (!new_extension->build_id_check || new_extension->build_id_check(ZEND_EXTENSION_BUILD_ID) != SUCCESS)) {
84 0 : fprintf(stderr, "Cannot load %s - it was built with configuration %s, whereas running engine is %s\n",
85 : new_extension->name, extension_version_info->build_id, ZEND_EXTENSION_BUILD_ID);
86 0 : DL_UNLOAD(handle);
87 0 : return FAILURE;
88 : }
89 :
90 0 : return zend_register_extension(new_extension, handle);
91 : #else
92 : fprintf(stderr, "Extensions are not supported on this platform.\n");
93 : return FAILURE;
94 : #endif
95 : }
96 : /* }}} */
97 :
98 : int zend_register_extension(zend_extension *new_extension, DL_HANDLE handle) /* {{{ */
99 0 : {
100 : #if ZEND_EXTENSIONS_SUPPORT
101 : zend_extension extension;
102 :
103 0 : extension = *new_extension;
104 0 : extension.handle = handle;
105 :
106 0 : zend_extension_dispatch_message(ZEND_EXTMSG_NEW_EXTENSION, &extension);
107 :
108 0 : zend_llist_add_element(&zend_extensions, &extension);
109 :
110 : /*fprintf(stderr, "Loaded %s, version %s\n", extension.name, extension.version);*/
111 : #endif
112 :
113 0 : return SUCCESS;
114 : }
115 : /* }}} */
116 :
117 : static void zend_extension_shutdown(zend_extension *extension TSRMLS_DC) /* {{{ */
118 0 : {
119 : #if ZEND_EXTENSIONS_SUPPORT
120 0 : if (extension->shutdown) {
121 0 : extension->shutdown(extension);
122 : }
123 : #endif
124 0 : }
125 : /* }}} */
126 :
127 : static int zend_extension_startup(zend_extension *extension) /* {{{ */
128 0 : {
129 : #if ZEND_EXTENSIONS_SUPPORT
130 0 : if (extension->startup) {
131 0 : if (extension->startup(extension)!=SUCCESS) {
132 0 : return 1;
133 : }
134 0 : zend_append_version_info(extension);
135 : }
136 : #endif
137 0 : return 0;
138 : }
139 : /* }}} */
140 :
141 : int zend_startup_extensions_mechanism(void) /* {{{ */
142 17007 : {
143 : /* Startup extensions mechanism */
144 17007 : zend_llist_init(&zend_extensions, sizeof(zend_extension), (void (*)(void *)) zend_extension_dtor, 1);
145 17007 : last_resource_number = 0;
146 17007 : return SUCCESS;
147 : }
148 : /* }}} */
149 :
150 : int zend_startup_extensions(void) /* {{{ */
151 17007 : {
152 17007 : zend_llist_apply_with_del(&zend_extensions, (int (*)(void *)) zend_extension_startup);
153 17007 : return SUCCESS;
154 : }
155 : /* }}} */
156 :
157 : void zend_shutdown_extensions(TSRMLS_D) /* {{{ */
158 17039 : {
159 17039 : zend_llist_apply(&zend_extensions, (llist_apply_func_t) zend_extension_shutdown TSRMLS_CC);
160 17039 : zend_llist_destroy(&zend_extensions);
161 17039 : }
162 : /* }}} */
163 :
164 : void zend_extension_dtor(zend_extension *extension) /* {{{ */
165 0 : {
166 : #if ZEND_EXTENSIONS_SUPPORT && !ZEND_DEBUG
167 0 : if (extension->handle) {
168 0 : DL_UNLOAD(extension->handle);
169 : }
170 : #endif
171 0 : }
172 : /* }}} */
173 :
174 : static void zend_extension_message_dispatcher(const zend_extension *extension, int num_args, va_list args TSRMLS_DC) /* {{{ */
175 0 : {
176 : int message;
177 : void *arg;
178 :
179 0 : if (!extension->message_handler || num_args!=2) {
180 0 : return;
181 : }
182 0 : message = va_arg(args, int);
183 0 : arg = va_arg(args, void *);
184 0 : extension->message_handler(message, arg);
185 : }
186 : /* }}} */
187 :
188 : ZEND_API void zend_extension_dispatch_message(int message, void *arg) /* {{{ */
189 0 : {
190 : TSRMLS_FETCH();
191 :
192 0 : zend_llist_apply_with_arguments(&zend_extensions, (llist_apply_with_args_func_t) zend_extension_message_dispatcher TSRMLS_CC, 2, message, arg);
193 0 : }
194 : /* }}} */
195 :
196 : ZEND_API int zend_get_resource_handle(zend_extension *extension) /* {{{ */
197 0 : {
198 0 : if (last_resource_number<ZEND_MAX_RESERVED_RESOURCES) {
199 0 : extension->resource_number = last_resource_number;
200 0 : return last_resource_number++;
201 : } else {
202 0 : return -1;
203 : }
204 : }
205 : /* }}} */
206 :
207 : ZEND_API zend_extension *zend_get_extension(const char *extension_name) /* {{{ */
208 0 : {
209 : zend_llist_element *element;
210 :
211 0 : for (element = zend_extensions.head; element; element = element->next) {
212 0 : zend_extension *extension = (zend_extension *) element->data;
213 :
214 0 : if (!strcmp(extension->name, extension_name)) {
215 0 : return extension;
216 : }
217 : }
218 0 : return NULL;
219 : }
220 : /* }}} */
221 :
222 : /*
223 : * Local variables:
224 : * tab-width: 4
225 : * c-basic-offset: 4
226 : * indent-tabs-mode: t
227 : * End:
228 : */
|