1: /*
2: +----------------------------------------------------------------------+
3: | Zend Engine |
4: +----------------------------------------------------------------------+
5: | Copyright (c) 1998-2014 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,v 1.1.1.4 2014/06/15 20:04:03 misho Exp $ */
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: {
29: #if ZEND_EXTENSIONS_SUPPORT
30: DL_HANDLE handle;
31: zend_extension *new_extension;
32: zend_extension_version_info *extension_version_info;
33:
34: handle = DL_LOAD(path);
35: if (!handle) {
36: #ifndef ZEND_WIN32
37: fprintf(stderr, "Failed loading %s: %s\n", path, DL_ERROR());
38: /* See http://support.microsoft.com/kb/190351 */
39: #ifdef PHP_WIN32
40: fflush(stderr);
41: #endif
42: #else
43: fprintf(stderr, "Failed loading %s\n", path);
44: #endif
45: return FAILURE;
46: }
47:
48: extension_version_info = (zend_extension_version_info *) DL_FETCH_SYMBOL(handle, "extension_version_info");
49: if (!extension_version_info) {
50: extension_version_info = (zend_extension_version_info *) DL_FETCH_SYMBOL(handle, "_extension_version_info");
51: }
52: new_extension = (zend_extension *) DL_FETCH_SYMBOL(handle, "zend_extension_entry");
53: if (!new_extension) {
54: new_extension = (zend_extension *) DL_FETCH_SYMBOL(handle, "_zend_extension_entry");
55: }
56: if (!extension_version_info || !new_extension) {
57: fprintf(stderr, "%s doesn't appear to be a valid Zend extension\n", path);
58: /* See http://support.microsoft.com/kb/190351 */
59: #ifdef PHP_WIN32
60: fflush(stderr);
61: #endif
62: DL_UNLOAD(handle);
63: return FAILURE;
64: }
65:
66:
67: /* allow extension to proclaim compatibility with any Zend version */
68: 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)) {
69: if (extension_version_info->zend_extension_api_no > ZEND_EXTENSION_API_NO) {
70: fprintf(stderr, "%s requires Zend Engine API version %d.\n"
71: "The Zend Engine API version %d which is installed, is outdated.\n\n",
72: new_extension->name,
73: extension_version_info->zend_extension_api_no,
74: ZEND_EXTENSION_API_NO);
75: /* See http://support.microsoft.com/kb/190351 */
76: #ifdef PHP_WIN32
77: fflush(stderr);
78: #endif
79: DL_UNLOAD(handle);
80: return FAILURE;
81: } else if (extension_version_info->zend_extension_api_no < ZEND_EXTENSION_API_NO) {
82: fprintf(stderr, "%s requires Zend Engine API version %d.\n"
83: "The Zend Engine API version %d which is installed, is newer.\n"
84: "Contact %s at %s for a later version of %s.\n\n",
85: new_extension->name,
86: extension_version_info->zend_extension_api_no,
87: ZEND_EXTENSION_API_NO,
88: new_extension->author,
89: new_extension->URL,
90: new_extension->name);
91: /* See http://support.microsoft.com/kb/190351 */
92: #ifdef PHP_WIN32
93: fflush(stderr);
94: #endif
95: DL_UNLOAD(handle);
96: return FAILURE;
97: }
98: } else if (strcmp(ZEND_EXTENSION_BUILD_ID, extension_version_info->build_id) &&
99: (!new_extension->build_id_check || new_extension->build_id_check(ZEND_EXTENSION_BUILD_ID) != SUCCESS)) {
100: fprintf(stderr, "Cannot load %s - it was built with configuration %s, whereas running engine is %s\n",
101: new_extension->name, extension_version_info->build_id, ZEND_EXTENSION_BUILD_ID);
102: /* See http://support.microsoft.com/kb/190351 */
103: #ifdef PHP_WIN32
104: fflush(stderr);
105: #endif
106: DL_UNLOAD(handle);
107: return FAILURE;
108: }
109:
110: return zend_register_extension(new_extension, handle);
111: #else
112: fprintf(stderr, "Extensions are not supported on this platform.\n");
113: /* See http://support.microsoft.com/kb/190351 */
114: #ifdef PHP_WIN32
115: fflush(stderr);
116: #endif
117: return FAILURE;
118: #endif
119: }
120:
121:
122: int zend_register_extension(zend_extension *new_extension, DL_HANDLE handle)
123: {
124: #if ZEND_EXTENSIONS_SUPPORT
125: zend_extension extension;
126:
127: extension = *new_extension;
128: extension.handle = handle;
129:
130: zend_extension_dispatch_message(ZEND_EXTMSG_NEW_EXTENSION, &extension);
131:
132: zend_llist_add_element(&zend_extensions, &extension);
133:
134: /*fprintf(stderr, "Loaded %s, version %s\n", extension.name, extension.version);*/
135: #endif
136:
137: return SUCCESS;
138: }
139:
140:
141: static void zend_extension_shutdown(zend_extension *extension TSRMLS_DC)
142: {
143: #if ZEND_EXTENSIONS_SUPPORT
144: if (extension->shutdown) {
145: extension->shutdown(extension);
146: }
147: #endif
148: }
149:
150: static int zend_extension_startup(zend_extension *extension)
151: {
152: #if ZEND_EXTENSIONS_SUPPORT
153: if (extension->startup) {
154: if (extension->startup(extension)!=SUCCESS) {
155: return 1;
156: }
157: zend_append_version_info(extension);
158: }
159: #endif
160: return 0;
161: }
162:
163:
164: int zend_startup_extensions_mechanism()
165: {
166: /* Startup extensions mechanism */
167: zend_llist_init(&zend_extensions, sizeof(zend_extension), (void (*)(void *)) zend_extension_dtor, 1);
168: last_resource_number = 0;
169: return SUCCESS;
170: }
171:
172:
173: int zend_startup_extensions()
174: {
175: zend_llist_apply_with_del(&zend_extensions, (int (*)(void *)) zend_extension_startup);
176: return SUCCESS;
177: }
178:
179:
180: void zend_shutdown_extensions(TSRMLS_D)
181: {
182: zend_llist_apply(&zend_extensions, (llist_apply_func_t) zend_extension_shutdown TSRMLS_CC);
183: zend_llist_destroy(&zend_extensions);
184: }
185:
186:
187: void zend_extension_dtor(zend_extension *extension)
188: {
189: #if ZEND_EXTENSIONS_SUPPORT && !ZEND_DEBUG
190: if (extension->handle) {
191: DL_UNLOAD(extension->handle);
192: }
193: #endif
194: }
195:
196:
197: static void zend_extension_message_dispatcher(const zend_extension *extension, int num_args, va_list args TSRMLS_DC)
198: {
199: int message;
200: void *arg;
201:
202: if (!extension->message_handler || num_args!=2) {
203: return;
204: }
205: message = va_arg(args, int);
206: arg = va_arg(args, void *);
207: extension->message_handler(message, arg);
208: }
209:
210:
211: ZEND_API void zend_extension_dispatch_message(int message, void *arg)
212: {
213: TSRMLS_FETCH();
214:
215: zend_llist_apply_with_arguments(&zend_extensions, (llist_apply_with_args_func_t) zend_extension_message_dispatcher TSRMLS_CC, 2, message, arg);
216: }
217:
218:
219: ZEND_API int zend_get_resource_handle(zend_extension *extension)
220: {
221: if (last_resource_number<ZEND_MAX_RESERVED_RESOURCES) {
222: extension->resource_number = last_resource_number;
223: return last_resource_number++;
224: } else {
225: return -1;
226: }
227: }
228:
229:
230: ZEND_API zend_extension *zend_get_extension(const char *extension_name)
231: {
232: zend_llist_element *element;
233:
234: for (element = zend_extensions.head; element; element = element->next) {
235: zend_extension *extension = (zend_extension *) element->data;
236:
237: if (!strcmp(extension->name, extension_name)) {
238: return extension;
239: }
240: }
241: return NULL;
242: }
243:
244: /*
245: * Local variables:
246: * tab-width: 4
247: * c-basic-offset: 4
248: * indent-tabs-mode: t
249: * End:
250: */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>