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>