diff options
-rw-r--r-- | ext/ffi/ffi.c | 93 | ||||
-rw-r--r-- | ext/ffi/tests/303.phpt | 15 | ||||
-rw-r--r-- | php.ini-development | 2 | ||||
-rw-r--r-- | php.ini-production | 2 |
4 files changed, 99 insertions, 13 deletions
diff --git a/ext/ffi/ffi.c b/ext/ffi/ffi.c index e2476653f7..ca6e7c4ef5 100644 --- a/ext/ffi/ffi.c +++ b/ext/ffi/ffi.c @@ -35,6 +35,14 @@ #include <sys/stat.h> #include <fcntl.h> +#ifdef HAVE_GLOB +#ifdef PHP_WIN32 +#include "win32/glob.h" +#else +#include <glob.h> +#endif +#endif + ZEND_DECLARE_MODULE_GLOBALS(ffi) typedef enum _zend_ffi_tag_kind { @@ -4836,10 +4844,50 @@ ZEND_INI_BEGIN() STD_ZEND_INI_ENTRY("ffi.preload", NULL, ZEND_INI_SYSTEM, OnUpdateString, preload, zend_ffi_globals, ffi_globals) ZEND_INI_END() +static int zend_ffi_preload_glob(const char *filename) /* {{{ */ +{ +#ifdef HAVE_GLOB + glob_t globbuf; + int ret; + unsigned int i; + + memset(&globbuf, 0, sizeof(glob_t)); + + ret = glob(filename, 0, NULL, &globbuf); +#ifdef GLOB_NOMATCH + if (ret == GLOB_NOMATCH || !globbuf.gl_pathc) { +#else + if (!globbuf.gl_pathc) { +#endif + /* pass */ + } else { + for(i=0 ; i<globbuf.gl_pathc; i++) { + zend_ffi *ffi = zend_ffi_load(globbuf.gl_pathv[i], 1); + if (!ffi) { + globfree(&globbuf); + return FAILURE; + } + efree(ffi); + } + globfree(&globbuf); + } +#else + zend_ffi *ffi = zend_ffi_load(filename, 1); + if (!ffi) { + return FAILURE; + } + efree(ffi); +#endif + + return SUCCESS; +} +/* }}} */ + static int zend_ffi_preload(char *preload) /* {{{ */ { zend_ffi *ffi; char *s = NULL, *e, *filename; + zend_bool is_glob = 0; e = preload; while (*e) { @@ -4847,15 +4895,30 @@ static int zend_ffi_preload(char *preload) /* {{{ */ case ZEND_PATHS_SEPARATOR: if (s) { filename = estrndup(s, e-s); - ffi = zend_ffi_load(filename, 1); - efree(filename); - if (!ffi) { - return FAILURE; - } - efree(ffi); s = NULL; + if (!is_glob) { + ffi = zend_ffi_load(filename, 1); + efree(filename); + if (!ffi) { + return FAILURE; + } + efree(ffi); + } else { + int ret = zend_ffi_preload_glob(filename); + + efree(filename); + if (ret != SUCCESS) { + return FAILURE; + } + is_glob = 0; + } } break; + case '*': + case '?': + case '[': + is_glob = 1; + break; default: if (!s) { s = e; @@ -4866,12 +4929,20 @@ static int zend_ffi_preload(char *preload) /* {{{ */ } if (s) { filename = estrndup(s, e-s); - ffi = zend_ffi_load(filename, 1); - efree(filename); - if (!ffi) { - return FAILURE; + if (!is_glob) { + ffi = zend_ffi_load(filename, 1); + efree(filename); + if (!ffi) { + return FAILURE; + } + efree(ffi); + } else { + int ret = zend_ffi_preload_glob(filename); + efree(filename); + if (ret != SUCCESS) { + return FAILURE; + } } - efree(ffi); } return SUCCESS; diff --git a/ext/ffi/tests/303.phpt b/ext/ffi/tests/303.phpt new file mode 100644 index 0000000000..756adbbf40 --- /dev/null +++ b/ext/ffi/tests/303.phpt @@ -0,0 +1,15 @@ +--TEST-- +FFI 303: FFI preloading flob +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +<?php if (substr(PHP_OS, 0, 3) == 'WIN') die('skip not for Windows'); ?> +--INI-- +ffi.enable=1 +ffi.preload={PWD}/300*.h +--FILE-- +<?php +$ffi = FFI::scope("TEST_300"); +$ffi->printf("Hello World from %s!\n", "PHP"); +?> +--EXPECT-- +Hello World from PHP! diff --git a/php.ini-development b/php.ini-development index 3f0c90cfca..f44c541a7a 100644 --- a/php.ini-development +++ b/php.ini-development @@ -1946,5 +1946,5 @@ ldap.max_links = -1 ; "true" - always enabled ;ffi.enable=preload -; List of headers files to preload +; List of headers files to preload, wilcards allowed. ;ffi.preload= diff --git a/php.ini-production b/php.ini-production index 867de11c60..b7f2536fd9 100644 --- a/php.ini-production +++ b/php.ini-production @@ -1948,5 +1948,5 @@ ldap.max_links = -1 ; "true" - always enabled ;ffi.enable=preload -; List of headers files to preload +; List of headers files to preload, wilcards allowed. ;ffi.preload= |