Annotation of embedaddon/php/ext/standard/dl.c, revision 1.1.1.1
1.1 misho 1: /*
2: +----------------------------------------------------------------------+
3: | PHP Version 5 |
4: +----------------------------------------------------------------------+
5: | Copyright (c) 1997-2012 The PHP Group |
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:
21: /* $Id: dl.c 321634 2012-01-01 13:15:04Z felipe $ */
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: } else if (PG(safe_mode)) {
67: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Dynamically loaded extensions aren't allowed when running in Safe Mode");
68: RETURN_FALSE;
69: }
70:
71: if (filename_len >= MAXPATHLEN) {
72: php_error_docref(NULL TSRMLS_CC, E_WARNING, "File name exceeds the maximum allowed length of %d characters", MAXPATHLEN);
73: RETURN_FALSE;
74: }
75:
76: if ((strncmp(sapi_module.name, "cgi", 3) != 0) &&
77: (strcmp(sapi_module.name, "cli") != 0) &&
78: (strncmp(sapi_module.name, "embed", 5) != 0)
79: ) {
80: #ifdef ZTS
81: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Not supported in multithreaded Web servers - use extension=%s in your php.ini", filename);
82: RETURN_FALSE;
83: #else
84: php_error_docref(NULL TSRMLS_CC, E_DEPRECATED, "dl() is deprecated - use extension=%s in your php.ini", filename);
85: #endif
86: }
87:
88: php_dl(filename, MODULE_TEMPORARY, return_value, 0 TSRMLS_CC);
89: if (Z_LVAL_P(return_value) == 1) {
90: EG(full_tables_cleanup) = 1;
91: }
92: }
93: /* }}} */
94:
95: #if defined(HAVE_LIBDL)
96:
97: #ifdef ZTS
98: #define USING_ZTS 1
99: #else
100: #define USING_ZTS 0
101: #endif
102:
103: /* {{{ php_dl
104: */
105: PHPAPI int php_load_extension(char *filename, int type, int start_now TSRMLS_DC) /* {{{ */
106: {
107: void *handle;
108: char *libpath;
109: zend_module_entry *module_entry;
110: zend_module_entry *(*get_module)(void);
111: int error_type;
112: char *extension_dir;
113:
114: if (type == MODULE_PERSISTENT) {
115: extension_dir = INI_STR("extension_dir");
116: } else {
117: extension_dir = PG(extension_dir);
118: }
119:
120: if (type == MODULE_TEMPORARY) {
121: error_type = E_WARNING;
122: } else {
123: error_type = E_CORE_WARNING;
124: }
125:
126: /* Check if passed filename contains directory separators */
127: if (strchr(filename, '/') != NULL || strchr(filename, DEFAULT_SLASH) != NULL) {
128: /* Passing modules with full path is not supported for dynamically loaded extensions */
129: if (type == MODULE_TEMPORARY) {
130: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Temporary module name should contain only filename");
131: return FAILURE;
132: }
133: libpath = estrdup(filename);
134: } else if (extension_dir && extension_dir[0]) {
135: int extension_dir_len = strlen(extension_dir);
136:
137: if (IS_SLASH(extension_dir[extension_dir_len-1])) {
138: spprintf(&libpath, 0, "%s%s", extension_dir, filename); /* SAFE */
139: } else {
140: spprintf(&libpath, 0, "%s%c%s", extension_dir, DEFAULT_SLASH, filename); /* SAFE */
141: }
142: } else {
143: return FAILURE; /* Not full path given or extension_dir is not set */
144: }
145:
146: /* load dynamic symbol */
147: handle = DL_LOAD(libpath);
148: if (!handle) {
149: #if PHP_WIN32
150: char *err = GET_DL_ERROR();
151: if (err && (*err != "")) {
152: php_error_docref(NULL TSRMLS_CC, error_type, "Unable to load dynamic library '%s' - %s", libpath, err);
153: LocalFree(err);
154: } else {
155: php_error_docref(NULL TSRMLS_CC, error_type, "Unable to load dynamic library '%s' - %s", libpath, "Unknown reason");
156: }
157: #else
158: php_error_docref(NULL TSRMLS_CC, error_type, "Unable to load dynamic library '%s' - %s", libpath, GET_DL_ERROR());
159: GET_DL_ERROR(); /* free the buffer storing the error */
160: #endif
161: efree(libpath);
162: return FAILURE;
163: }
164: efree(libpath);
165:
166: get_module = (zend_module_entry *(*)(void)) DL_FETCH_SYMBOL(handle, "get_module");
167:
168: /* Some OS prepend _ to symbol names while their dynamic linker
169: * does not do that automatically. Thus we check manually for
170: * _get_module. */
171:
172: if (!get_module) {
173: get_module = (zend_module_entry *(*)(void)) DL_FETCH_SYMBOL(handle, "_get_module");
174: }
175:
176: if (!get_module) {
177: DL_UNLOAD(handle);
178: php_error_docref(NULL TSRMLS_CC, error_type, "Invalid library (maybe not a PHP library) '%s'", filename);
179: return FAILURE;
180: }
181: module_entry = get_module();
182: if (module_entry->zend_api != ZEND_MODULE_API_NO) {
183: /* Check for pre-4.1.0 module which has a slightly different module_entry structure :( */
184: struct pre_4_1_0_module_entry {
185: char *name;
186: zend_function_entry *functions;
187: int (*module_startup_func)(INIT_FUNC_ARGS);
188: int (*module_shutdown_func)(SHUTDOWN_FUNC_ARGS);
189: int (*request_startup_func)(INIT_FUNC_ARGS);
190: int (*request_shutdown_func)(SHUTDOWN_FUNC_ARGS);
191: void (*info_func)(ZEND_MODULE_INFO_FUNC_ARGS);
192: int (*global_startup_func)(void);
193: int (*global_shutdown_func)(void);
194: int globals_id;
195: int module_started;
196: unsigned char type;
197: void *handle;
198: int module_number;
199: unsigned char zend_debug;
200: unsigned char zts;
201: unsigned int zend_api;
202: };
203:
204: const char *name;
205: int zend_api;
206:
207: if ((((struct pre_4_1_0_module_entry *)module_entry)->zend_api > 20000000) &&
208: (((struct pre_4_1_0_module_entry *)module_entry)->zend_api < 20010901)
209: ) {
210: name = ((struct pre_4_1_0_module_entry *)module_entry)->name;
211: zend_api = ((struct pre_4_1_0_module_entry *)module_entry)->zend_api;
212: } else {
213: name = module_entry->name;
214: zend_api = module_entry->zend_api;
215: }
216:
217: php_error_docref(NULL TSRMLS_CC, error_type,
218: "%s: Unable to initialize module\n"
219: "Module compiled with module API=%d\n"
220: "PHP compiled with module API=%d\n"
221: "These options need to match\n",
222: name, zend_api, ZEND_MODULE_API_NO);
223: DL_UNLOAD(handle);
224: return FAILURE;
225: }
226: if(strcmp(module_entry->build_id, ZEND_MODULE_BUILD_ID)) {
227: php_error_docref(NULL TSRMLS_CC, error_type,
228: "%s: Unable to initialize module\n"
229: "Module compiled with build ID=%s\n"
230: "PHP compiled with build ID=%s\n"
231: "These options need to match\n",
232: module_entry->name, module_entry->build_id, ZEND_MODULE_BUILD_ID);
233: DL_UNLOAD(handle);
234: return FAILURE;
235: }
236: module_entry->type = type;
237: module_entry->module_number = zend_next_free_module();
238: module_entry->handle = handle;
239:
240: if ((module_entry = zend_register_module_ex(module_entry TSRMLS_CC)) == NULL) {
241: DL_UNLOAD(handle);
242: return FAILURE;
243: }
244:
245: if ((type == MODULE_TEMPORARY || start_now) && zend_startup_module_ex(module_entry TSRMLS_CC) == FAILURE) {
246: DL_UNLOAD(handle);
247: return FAILURE;
248: }
249:
250: if ((type == MODULE_TEMPORARY || start_now) && module_entry->request_startup_func) {
251: if (module_entry->request_startup_func(type, module_entry->module_number TSRMLS_CC) == FAILURE) {
252: php_error_docref(NULL TSRMLS_CC, error_type, "Unable to initialize module '%s'", module_entry->name);
253: DL_UNLOAD(handle);
254: return FAILURE;
255: }
256: }
257:
258: #if SUHOSIN_PATCH
259: if (strncmp("suhosin", module_entry->name, sizeof("suhosin")-1) == 0) {
260: void *log_func;
261: /* sucessfully loaded suhosin extension, now check for logging function replacement */
262: log_func = (void *) DL_FETCH_SYMBOL(handle, "suhosin_log");
263: if (log_func == NULL) {
264: log_func = (void *) DL_FETCH_SYMBOL(handle, "_suhosin_log");
265: }
266: if (log_func != NULL) {
267: zend_suhosin_log = log_func;
268: } else {
269: zend_suhosin_log(S_MISC, "could not replace logging function");
270: }
271: }
272: #endif
273:
274: return SUCCESS;
275: }
276: /* }}} */
277:
278: /* {{{ php_dl
279: */
280: PHPAPI void php_dl(char *file, int type, zval *return_value, int start_now TSRMLS_DC)
281: {
282: /* Load extension */
283: if (php_load_extension(file, type, start_now TSRMLS_CC) == FAILURE) {
284: RETVAL_FALSE;
285: } else {
286: RETVAL_TRUE;
287: }
288: }
289: /* }}} */
290:
291: PHP_MINFO_FUNCTION(dl)
292: {
293: php_info_print_table_row(2, "Dynamic Library Support", "enabled");
294: }
295:
296: #else
297:
298: PHPAPI void php_dl(char *file, int type, zval *return_value, int start_now TSRMLS_DC)
299: {
300: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot dynamically load %s - dynamic modules are not supported", file);
301: RETURN_FALSE;
302: }
303:
304: PHP_MINFO_FUNCTION(dl)
305: {
306: PUTS("Dynamic Library support not available<br />.\n");
307: }
308:
309: #endif
310:
311: /*
312: * Local variables:
313: * tab-width: 4
314: * c-basic-offset: 4
315: * End:
316: * vim600: sw=4 ts=4 fdm=marker
317: * vim<600: sw=4 ts=4
318: */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>