From f323baa845b51e00e8116bc55fa40400a0f70e44 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 2 Apr 2021 13:39:12 +0300 Subject: [PATCH] Reduce number of stat() calls --- ext/spl/spl_directory.c | 10 ++++++---- ext/standard/filestat.c | 7 +++++-- ext/standard/php_filestat.h | 1 + 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/ext/spl/spl_directory.c b/ext/spl/spl_directory.c index fc2bf437167..ad4823062a2 100644 --- a/ext/spl/spl_directory.c +++ b/ext/spl/spl_directory.c @@ -1474,13 +1474,15 @@ PHP_METHOD(RecursiveDirectoryIterator, hasChildren) if (spl_filesystem_object_get_file_name(intern) != SUCCESS) { RETURN_THROWS(); } - if (!allow_links && !(intern->flags & SPL_FILE_DIR_FOLLOW_SYMLINKS)) { - php_stat(intern->file_name, FS_IS_LINK, return_value); - if (zend_is_true(return_value)) { + php_stat(intern->file_name, FS_LPERMS, return_value); + if (S_ISLNK(Z_LVAL_P(return_value))) { + if (!allow_links + && !(intern->flags & SPL_FILE_DIR_FOLLOW_SYMLINKS)) { RETURN_FALSE; } + php_stat(intern->file_name, FS_PERMS, return_value); } - php_stat(intern->file_name, FS_IS_DIR, return_value); + RETURN_BOOL(S_ISDIR(Z_LVAL_P(return_value))); } } /* }}} */ diff --git a/ext/standard/filestat.c b/ext/standard/filestat.c index 0b488df4b26..c2b6f2ce2de 100644 --- a/ext/standard/filestat.c +++ b/ext/standard/filestat.c @@ -714,7 +714,7 @@ PHP_FUNCTION(clearstatcache) } /* }}} */ -#define IS_LINK_OPERATION(__t) ((__t) == FS_TYPE || (__t) == FS_IS_LINK || (__t) == FS_LSTAT) +#define IS_LINK_OPERATION(__t) ((__t) == FS_TYPE || (__t) == FS_IS_LINK || (__t) == FS_LSTAT || (__t) == FS_LPERMS) #define IS_EXISTS_CHECK(__t) ((__t) == FS_EXISTS || (__t) == FS_IS_W || (__t) == FS_IS_R || (__t) == FS_IS_X || (__t) == FS_IS_FILE || (__t) == FS_IS_DIR || (__t) == FS_IS_LINK) #define IS_ABLE_CHECK(__t) ((__t) == FS_IS_R || (__t) == FS_IS_W || (__t) == FS_IS_X) #define IS_ACCESS_CHECK(__t) (IS_ABLE_CHECK(type) || (__t) == FS_EXISTS) @@ -824,7 +824,9 @@ PHPAPI void php_stat(zend_string *filename, int type, zval *return_value) } BG(CurrentLStatFile) = zend_string_copy(filename); memcpy(&BG(lssb), &ssb, sizeof(php_stream_statbuf)); - } else { + } + if (!(flags & PHP_STREAM_URL_STAT_LINK) + || !S_ISLNK(ssb.sb.st_mode)) { if (BG(CurrentStatFile)) { zend_string_release(BG(CurrentStatFile)); } @@ -878,6 +880,7 @@ PHPAPI void php_stat(zend_string *filename, int type, zval *return_value) switch (type) { case FS_PERMS: + case FS_LPERMS: RETURN_LONG((zend_long)ssb.sb.st_mode); case FS_INODE: RETURN_LONG((zend_long)ssb.sb.st_ino); diff --git a/ext/standard/php_filestat.h b/ext/standard/php_filestat.h index ab4e32729d4..7f6569576cb 100644 --- a/ext/standard/php_filestat.h +++ b/ext/standard/php_filestat.h @@ -62,5 +62,6 @@ PHPAPI void php_stat(zend_string *filename, int type, zval *return_value); #define FS_EXISTS 15 #define FS_LSTAT 16 #define FS_STAT 17 +#define FS_LPERMS 18 #endif /* PHP_FILESTAT_H */