diff options
author | Sara Golemon <pollita@php.net> | 2004-01-28 22:21:54 +0000 |
---|---|---|
committer | Sara Golemon <pollita@php.net> | 2004-01-28 22:21:54 +0000 |
commit | 6d10371ec642cbb42d61b9ee82448128c89cdf63 (patch) | |
tree | 2bd640225274195a8753b1a6818b363d8c0e3667 | |
parent | e691cbd4ee3d6a86e20ca93b1365996af7f23f62 (diff) | |
download | php-git-6d10371ec642cbb42d61b9ee82448128c89cdf63.tar.gz |
'Bug Fix': scandir, being a new function in PHP5 should have always been wrapper aware.
-rw-r--r-- | ext/standard/dir.c | 53 | ||||
-rwxr-xr-x | main/php_streams.h | 7 | ||||
-rwxr-xr-x | main/streams/streams.c | 59 |
3 files changed, 78 insertions, 41 deletions
diff --git a/ext/standard/dir.c b/ext/standard/dir.c index 41aad5e351..077f4fdfcd 100644 --- a/ext/standard/dir.c +++ b/ext/standard/dir.c @@ -444,74 +444,45 @@ PHP_FUNCTION(glob) /* }}} */ #endif -/* {{{ php_alphasortr -*/ -static int php_alphasortr(const struct dirent **a, const struct dirent **b) -{ - return strcoll((*b)->d_name, (*a)->d_name); -} -/* }}} */ - -/* {{{ proto array scandir(string dir [, int sorting_order]) +/* {{{ proto array scandir(string dir [, int sorting_order [, resource context]]) List files & directories inside the specified path */ PHP_FUNCTION(scandir) { char *dirn; int dirn_len; int flags = 0; - char *path; - struct dirent **namelist; + php_stream_dirent **namelist; int n, i; + zval *zcontext = NULL; + php_stream_context *context = NULL; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &dirn, &dirn_len, &flags) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lr", &dirn, &dirn_len, &flags, &zcontext) == FAILURE) { return; } -#ifdef ZTS - if (!IS_ABSOLUTE_PATH(dirn, dirn_len)) { - path = expand_filepath(dirn, NULL TSRMLS_CC); - } else -#endif - path = dirn; - - if (PG(safe_mode) && (!php_checkuid(path, NULL, CHECKUID_CHECK_FILE_AND_DIR))) { - RETVAL_FALSE; - goto err; - } - if (php_check_open_basedir(path TSRMLS_CC)) { - RETVAL_FALSE; - goto err; + if (zcontext) { + context = php_stream_context_from_zval(zcontext, 0); } if (!flags) { - n = php_scandir(path, &namelist, 0, php_alphasort); + n = php_stream_scandir(dirn, &namelist, context, (void *) php_stream_dirent_alphasort); } else { - n = php_scandir(path, &namelist, 0, (void *) php_alphasortr); + n = php_stream_scandir(dirn, &namelist, context, (void *) php_stream_dirent_alphasortr); } - if (n < 0) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "(errno %d): %s", errno, strerror(errno)); - RETVAL_FALSE; - goto err; + RETURN_FALSE; } array_init(return_value); for (i = 0; i < n; i++) { - add_next_index_string(return_value, namelist[i]->d_name, 1); - free(namelist[i]); + add_next_index_string(return_value, namelist[i]->d_name, 0); } if (n) { - free(namelist); + efree(namelist); } - -err: - if (path && path != dirn) { - efree(path); - } - - return; } /* }}} */ diff --git a/main/php_streams.h b/main/php_streams.h index 2fcb1c413d..47ed1181e3 100755 --- a/main/php_streams.h +++ b/main/php_streams.h @@ -325,6 +325,13 @@ PHPAPI php_stream_dirent *_php_stream_readdir(php_stream *dirstream, php_stream_ #define php_stream_closedir(dirstream) php_stream_close((dirstream)) #define php_stream_rewinddir(dirstream) php_stream_rewind((dirstream)) +PHPAPI int php_stream_dirent_alphasort(const php_stream_dirent **a, const php_stream_dirent **b); +PHPAPI int php_stream_dirent_alphasortr(const php_stream_dirent **a, const php_stream_dirent **b); + +PHPAPI int _php_stream_scandir(char *dirname, php_stream_dirent **namelist[], int flags, php_stream_context *context, + int (*compare) (const php_stream_dirent **a, const php_stream_dirent **b) TSRMLS_DC); +#define php_stream_scandir(dirname, namelist, context, compare) _php_stream_scandir((dirname), (namelist), 0, (context), (compare) TSRMLS_CC) + PHPAPI int _php_stream_set_option(php_stream *stream, int option, int value, void *ptrparam TSRMLS_DC); #define php_stream_set_option(stream, option, value, ptrvalue) _php_stream_set_option((stream), (option), (value), (ptrvalue) TSRMLS_CC) diff --git a/main/streams/streams.c b/main/streams/streams.c index ece1870ce1..dc7a4f37ed 100755 --- a/main/streams/streams.c +++ b/main/streams/streams.c @@ -1834,6 +1834,65 @@ PHPAPI int php_stream_context_del_link(php_stream_context *context, } /* }}} */ +/* {{{ php_stream_dirent_alphasort + */ +PHPAPI int php_stream_dirent_alphasort(const php_stream_dirent **a, const php_stream_dirent **b) +{ + return strcoll((*a)->d_name,(*b)->d_name); +} +/* }}} */ + +/* {{{ php_stream_dirent_alphasortr + */ +PHPAPI int php_stream_dirent_alphasortr(const php_stream_dirent **a, const php_stream_dirent **b) +{ + return strcoll((*b)->d_name,(*a)->d_name); +} +/* }}} */ + +/* {{{ php_stream_scandir + */ +PHPAPI int _php_stream_scandir(char *dirname, php_stream_dirent **namelist[], int flags, php_stream_context *context, + int (*compare) (const php_stream_dirent **a, const php_stream_dirent **b) TSRMLS_DC) +{ + php_stream *stream; + php_stream_dirent sdp; + php_stream_dirent **vector = NULL; + int vector_size = 0; + int nfiles = 0; + + if (!namelist) { + return FAILURE; + } + + stream = php_stream_opendir(dirname, ENFORCE_SAFE_MODE | REPORT_ERRORS, context); + if (!stream) { + return FAILURE; + } + + while (php_stream_readdir(stream, &sdp)) { + if (nfiles == vector_size) { + if (vector_size == 0) { + vector_size = 10; + } else { + vector_size *= 2; + } + vector = (php_stream_dirent **) erealloc(vector, vector_size * sizeof(php_stream_dirent *)); + } + + vector[nfiles++] = (php_stream_dirent*)estrndup(&sdp, sizeof(php_stream_dirent) + ((strlen(sdp.d_name) + 1) * sizeof(char))); + } + php_stream_closedir(stream); + + *namelist = vector; + + if (compare) { + qsort(*namelist, nfiles, sizeof(php_stream_dirent *), compare); + } + return nfiles; +} +/* }}} */ + /* * Local variables: * tab-width: 4 |