summaryrefslogtreecommitdiff
path: root/Zend/zend_extensions.c
blob: fe63768dba9ecc05975e4bbbe158bb95ed8438d7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/*
   +----------------------------------------------------------------------+
   | Zend Engine                                                          |
   +----------------------------------------------------------------------+
   | Copyright (c) 1998, 1999 Andi Gutmans, Zeev Suraski                  |
   +----------------------------------------------------------------------+
   | This source file is subject to the Zend license, that is bundled     |
   | with this package in the file LICENSE.  If you did not receive a     |
   | copy of the Zend license, please mail us at zend@zend.com so we can  |
   | send you a copy immediately.                                         |
   +----------------------------------------------------------------------+
   | Authors: Andi Gutmans <andi@zend.com>                                |
   |          Zeev Suraski <zeev@zend.com>                                |
   +----------------------------------------------------------------------+
*/

#include "zend_extensions.h"

ZEND_API zend_llist zend_extensions;
static int last_resource_number;

int zend_load_extensions(char **extension_paths)
{
	char **p = extension_paths;

	if (!p) {
		return SUCCESS;
	}
	while (*p) {
		if (zend_load_extension(*p)==FAILURE) {
			return FAILURE;
		}
		p++;
	}
	return SUCCESS;
}


int zend_load_extension(char *path)
{
#if ZEND_EXTENSIONS_SUPPORT
	DL_HANDLE handle;
	zend_extension extension, *new_extension;
	zend_extension_version_info *extension_version_info;

	handle = DL_LOAD(path);
	if (!handle) {
		zend_printf("Failed loading %s\n", path);
		return FAILURE;
	}

	extension_version_info = (zend_extension_version_info *) DL_FETCH_SYMBOL(handle, "extension_version_info");
	new_extension = (zend_extension *) DL_FETCH_SYMBOL(handle, "zend_extension_entry");
	if (!extension_version_info || !new_extension) {
		zend_printf("%s doesn't appear to be a valid Zend extension\n", path);
		return FAILURE;
	}

	if (extension_version_info->zend_extension_api_no > ZEND_EXTENSION_API_NO) {
		zend_printf("%s requires Zend version %s or later\n"
					"Current version %s, API version %d\n",
					new_extension->name,
					extension_version_info->required_zend_version,
					ZEND_VERSION,
					ZEND_EXTENSION_API_NO);
		return FAILURE;
	} else if (extension_version_info->zend_extension_api_no < ZEND_EXTENSION_API_NO) {
		/* we may be able to allow for downwards compatability in some harmless cases. */
		zend_printf("%s is outdated (API version %d, current version %d)\n"
					"Contact %s at %s for a later version of this module.\n",
					new_extension->name,
					extension_version_info->zend_extension_api_no,
					ZEND_EXTENSION_API_NO,
					new_extension->author,
					new_extension->URL);
		return FAILURE;
	} else if (ZTS_V!=extension_version_info->thread_safe) {
		zend_printf("Cannot load %s - it %s thread safe, whereas Zend %s\n",
					new_extension->name,
					(extension_version_info->thread_safe?"is":"isn't"),
					(ZTS_V?"is":"isn't"));
		return FAILURE;
	}

	if (new_extension->startup) {
		new_extension->startup(new_extension);
	}
	extension = *new_extension;
	extension.handle = handle;

	zend_llist_add_element(&zend_extensions, &extension);

	/*zend_printf("Loaded %s, version %s\n", extension.name, extension.version);*/

	zend_append_version_info(&extension);
	return SUCCESS;
#else
	zend_printf("Extensions are not supported on this platform.\n");
	return FAILURE
#endif
}


void zend_extension_dtor(zend_extension *extension)
{
#if ZEND_EXTENSIONS_SUPPORT
	if (extension->shutdown) {
		extension->shutdown(extension);
	}
	DL_UNLOAD(extension->handle);
#endif
}


ZEND_API int zend_get_resource_handle(zend_extension *extension)
{
	if (last_resource_number<4) {
		extension->resource_number = last_resource_number;
		return last_resource_number;
	} else {
		return -1;
	}
}