Annotation of embedaddon/php/ext/standard/dl.c, revision 1.1.1.4
1.1 misho 1: /*
2: +----------------------------------------------------------------------+
3: | PHP Version 5 |
4: +----------------------------------------------------------------------+
1.1.1.4 ! misho 5: | Copyright (c) 1997-2014 The PHP Group |
1.1 misho 6: +----------------------------------------------------------------------+
7: | This source file is subject to version 3.01 of the PHP 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.php.net/license/3_01.txt |
11: | If you did not receive a copy of the PHP license and are unable to |
12: | obtain it through the world-wide-web, please send a note to |
13: | license@php.net so we can mail you a copy immediately. |
14: +----------------------------------------------------------------------+
15: | Authors: Brian Schaffner <brian@tool.net> |
16: | Shane Caraveo <shane@caraveo.com> |
17: | Zeev Suraski <zeev@zend.com> |
18: +----------------------------------------------------------------------+
19: */
20:
1.1.1.2 misho 21: /* $Id$ */
1.1 misho 22:
23: #include "php.h"
24: #include "dl.h"
25: #include "php_globals.h"
26: #include "php_ini.h"
27: #include "ext/standard/info.h"
28:
29: #include "SAPI.h"
30:
31: #if defined(HAVE_LIBDL)
32: #include <stdlib.h>
33: #include <stdio.h>
34: #ifdef HAVE_STRING_H
35: #include <string.h>
36: #else
37: #include <strings.h>
38: #endif
39: #ifdef PHP_WIN32
40: #include "win32/param.h"
41: #include "win32/winutil.h"
42: #define GET_DL_ERROR() php_win_err()
43: #elif defined(NETWARE)
44: #include <sys/param.h>
45: #define GET_DL_ERROR() dlerror()
46: #else
47: #include <sys/param.h>
48: #define GET_DL_ERROR() DL_ERROR()
49: #endif
50: #endif /* defined(HAVE_LIBDL) */
51:
52: /* {{{ proto int dl(string extension_filename)
53: Load a PHP extension at runtime */
54: PHPAPI PHP_FUNCTION(dl)
55: {
56: char *filename;
57: int filename_len;
58:
59: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &filename, &filename_len) == FAILURE) {
60: return;
61: }
62:
63: if (!PG(enable_dl)) {
64: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Dynamically loaded extensions aren't enabled");
65: RETURN_FALSE;
66: }
67:
68: if (filename_len >= MAXPATHLEN) {
69: php_error_docref(NULL TSRMLS_CC, E_WARNING, "File name exceeds the maximum allowed length of %d characters", MAXPATHLEN);
70: RETURN_FALSE;
71: }
72:
73: if ((strncmp(sapi_module.name, "cgi", 3) != 0) &&
74: (strcmp(sapi_module.name, "cli") != 0) &&
75: (strncmp(sapi_module.name, "embed", 5) != 0)
76: ) {
77: #ifdef ZTS
78: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Not supported in multithreaded Web servers - use extension=%s in your php.ini", filename);
79: RETURN_FALSE;
80: #else
81: php_error_docref(NULL TSRMLS_CC, E_DEPRECATED, "dl() is deprecated - use extension=%s in your php.ini", filename);
82: #endif
83: }
84:
85: php_dl(filename, MODULE_TEMPORARY, return_value, 0 TSRMLS_CC);
86: if (Z_LVAL_P(return_value) == 1) {
87: EG(full_tables_cleanup) = 1;
88: }
89: }
90: /* }}} */
91:
92: #if defined(HAVE_LIBDL)
93:
94: #ifdef ZTS
95: #define USING_ZTS 1
96: #else
97: #define USING_ZTS 0
98: #endif
99:
100: /* {{{ php_dl
101: */
102: PHPAPI int php_load_extension(char *filename, int type, int start_now TSRMLS_DC) /* {{{ */
103: {
104: void *handle;
105: char *libpath;
106: zend_module_entry *module_entry;
107: zend_module_entry *(*get_module)(void);
108: int error_type;
109: char *extension_dir;
110:
111: if (type == MODULE_PERSISTENT) {
112: extension_dir = INI_STR("extension_dir");
113: } else {
114: extension_dir = PG(extension_dir);
115: }
116:
117: if (type == MODULE_TEMPORARY) {
118: error_type = E_WARNING;
119: } else {
120: error_type = E_CORE_WARNING;
121: }
122:
123: /* Check if passed filename contains directory separators */
124: if (strchr(filename, '/') != NULL || strchr(filename, DEFAULT_SLASH) != NULL) {
125: /* Passing modules with full path is not supported for dynamically loaded extensions */
126: if (type == MODULE_TEMPORARY) {
127: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Temporary module name should contain only filename");
128: return FAILURE;
129: }
130: libpath = estrdup(filename);
131: } else if (extension_dir && extension_dir[0]) {
132: int extension_dir_len = strlen(extension_dir);
133:
134: if (IS_SLASH(extension_dir[extension_dir_len-1])) {
135: spprintf(&libpath, 0, "%s%s", extension_dir, filename); /* SAFE */
136: } else {
137: spprintf(&libpath, 0, "%s%c%s", extension_dir, DEFAULT_SLASH, filename); /* SAFE */
138: }
139: } else {
140: return FAILURE; /* Not full path given or extension_dir is not set */
141: }
142:
143: /* load dynamic symbol */
144: handle = DL_LOAD(libpath);
145: if (!handle) {
146: #if PHP_WIN32
147: char *err = GET_DL_ERROR();
148: if (err && (*err != "")) {
149: php_error_docref(NULL TSRMLS_CC, error_type, "Unable to load dynamic library '%s' - %s", libpath, err);
150: LocalFree(err);
151: } else {
152: php_error_docref(NULL TSRMLS_CC, error_type, "Unable to load dynamic library '%s' - %s", libpath, "Unknown reason");
153: }
154: #else
155: php_error_docref(NULL TSRMLS_CC, error_type, "Unable to load dynamic library '%s' - %s", libpath, GET_DL_ERROR());
156: GET_DL_ERROR(); /* free the buffer storing the error */
157: #endif
158: efree(libpath);
159: return FAILURE;
160: }
161: efree(libpath);
162:
163: get_module = (zend_module_entry *(*)(void)) DL_FETCH_SYMBOL(handle, "get_module");
164:
165: /* Some OS prepend _ to symbol names while their dynamic linker
166: * does not do that automatically. Thus we check manually for
167: * _get_module. */
168:
169: if (!get_module) {
170: get_module = (zend_module_entry *(*)(void)) DL_FETCH_SYMBOL(handle, "_get_module");
171: }
172:
173: if (!get_module) {
174: DL_UNLOAD(handle);
175: php_error_docref(NULL TSRMLS_CC, error_type, "Invalid library (maybe not a PHP library) '%s'", filename);
176: return FAILURE;
177: }
178: module_entry = get_module();
179: if (module_entry->zend_api != ZEND_MODULE_API_NO) {
180: /* Check for pre-4.1.0 module which has a slightly different module_entry structure :( */
181: struct pre_4_1_0_module_entry {
182: char *name;
183: zend_function_entry *functions;
184: int (*module_startup_func)(INIT_FUNC_ARGS);
185: int (*module_shutdown_func)(SHUTDOWN_FUNC_ARGS);
186: int (*request_startup_func)(INIT_FUNC_ARGS);
187: int (*request_shutdown_func)(SHUTDOWN_FUNC_ARGS);
188: void (*info_func)(ZEND_MODULE_INFO_FUNC_ARGS);
189: int (*global_startup_func)(void);
190: int (*global_shutdown_func)(void);
191: int globals_id;
192: int module_started;
193: unsigned char type;
194: void *handle;
195: int module_number;
196: unsigned char zend_debug;
197: unsigned char zts;
198: unsigned int zend_api;
199: };
200:
201: const char *name;
202: int zend_api;
203:
204: if ((((struct pre_4_1_0_module_entry *)module_entry)->zend_api > 20000000) &&
205: (((struct pre_4_1_0_module_entry *)module_entry)->zend_api < 20010901)
206: ) {
207: name = ((struct pre_4_1_0_module_entry *)module_entry)->name;
208: zend_api = ((struct pre_4_1_0_module_entry *)module_entry)->zend_api;
209: } else {
210: name = module_entry->name;
211: zend_api = module_entry->zend_api;
212: }
213:
214: php_error_docref(NULL TSRMLS_CC, error_type,
215: "%s: Unable to initialize module\n"
216: "Module compiled with module API=%d\n"
217: "PHP compiled with module API=%d\n"
218: "These options need to match\n",
219: name, zend_api, ZEND_MODULE_API_NO);
220: DL_UNLOAD(handle);
221: return FAILURE;
222: }
223: if(strcmp(module_entry->build_id, ZEND_MODULE_BUILD_ID)) {
224: php_error_docref(NULL TSRMLS_CC, error_type,
225: "%s: Unable to initialize module\n"
226: "Module compiled with build ID=%s\n"
227: "PHP compiled with build ID=%s\n"
228: "These options need to match\n",
229: module_entry->name, module_entry->build_id, ZEND_MODULE_BUILD_ID);
230: DL_UNLOAD(handle);
231: return FAILURE;
232: }
233: module_entry->type = type;
234: module_entry->module_number = zend_next_free_module();
235: module_entry->handle = handle;
236:
237: if ((module_entry = zend_register_module_ex(module_entry TSRMLS_CC)) == NULL) {
238: DL_UNLOAD(handle);
239: return FAILURE;
240: }
241:
242: if ((type == MODULE_TEMPORARY || start_now) && zend_startup_module_ex(module_entry TSRMLS_CC) == FAILURE) {
243: DL_UNLOAD(handle);
244: return FAILURE;
245: }
246:
247: if ((type == MODULE_TEMPORARY || start_now) && module_entry->request_startup_func) {
248: if (module_entry->request_startup_func(type, module_entry->module_number TSRMLS_CC) == FAILURE) {
249: php_error_docref(NULL TSRMLS_CC, error_type, "Unable to initialize module '%s'", module_entry->name);
250: DL_UNLOAD(handle);
251: return FAILURE;
252: }
253: }
254: return SUCCESS;
255: }
256: /* }}} */
257:
258: /* {{{ php_dl
259: */
260: PHPAPI void php_dl(char *file, int type, zval *return_value, int start_now TSRMLS_DC)
261: {
262: /* Load extension */
263: if (php_load_extension(file, type, start_now TSRMLS_CC) == FAILURE) {
264: RETVAL_FALSE;
265: } else {
266: RETVAL_TRUE;
267: }
268: }
269: /* }}} */
270:
271: PHP_MINFO_FUNCTION(dl)
272: {
273: php_info_print_table_row(2, "Dynamic Library Support", "enabled");
274: }
275:
276: #else
277:
278: PHPAPI void php_dl(char *file, int type, zval *return_value, int start_now TSRMLS_DC)
279: {
280: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot dynamically load %s - dynamic modules are not supported", file);
281: RETURN_FALSE;
282: }
283:
284: PHP_MINFO_FUNCTION(dl)
285: {
286: PUTS("Dynamic Library support not available<br />.\n");
287: }
288:
289: #endif
290:
291: /*
292: * Local variables:
293: * tab-width: 4
294: * c-basic-offset: 4
295: * End:
296: * vim600: sw=4 ts=4 fdm=marker
297: * vim<600: sw=4 ts=4
298: */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>