File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / php / ext / standard / dl.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue May 29 12:34:43 2012 UTC (12 years, 1 month ago) by misho
Branches: php, MAIN
CVS tags: v5_4_3elwix, v5_4_17p0, HEAD
php 5.4.3+patches

    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,v 1.1.1.2 2012/05/29 12:34:43 misho Exp $ */
   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>