mirror of
https://github.com/php/php-src.git
synced 2024-11-23 01:44:06 +08:00
Cache d_type in directory entry
This commit is contained in:
parent
00c1e7bf0f
commit
0b2e6bc2b0
@ -67,6 +67,9 @@ PHP 8.3 INTERNALS UPGRADE NOTES
|
||||
- zend_set_user_opcode_handler
|
||||
- zend_ssa_inference
|
||||
* Removed unused macros PHP_FNV1_32A_INIT and PHP_FNV1A_64_INIT. See GH-11114.
|
||||
* _php_stream_dirent now has an extra d_type field that is used to store the
|
||||
directory entry type. This can be used to avoid additional stat calls for
|
||||
types when the type is already known.
|
||||
|
||||
========================
|
||||
2. Build system changes
|
||||
|
@ -87,6 +87,16 @@ typedef unsigned short mode_t;
|
||||
#else
|
||||
#ifdef HAVE_DIRENT_H
|
||||
#include <dirent.h>
|
||||
|
||||
#ifndef DT_UNKNOWN
|
||||
# define DT_UNKNOWN 0
|
||||
#endif
|
||||
#ifndef DT_DIR
|
||||
# define DT_DIR 4
|
||||
#endif
|
||||
#ifndef DT_REG
|
||||
# define DT_REG 8
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define DEFAULT_SLASH '/'
|
||||
|
@ -108,6 +108,7 @@ static ssize_t phar_dir_read(php_stream *stream, char *buf, size_t count) /* {{{
|
||||
memset(buf, 0, sizeof(php_stream_dirent));
|
||||
memcpy(((php_stream_dirent *) buf)->d_name, ZSTR_VAL(str_key), to_read);
|
||||
((php_stream_dirent *) buf)->d_name[to_read + 1] = '\0';
|
||||
((php_stream_dirent *) buf)->d_type = DT_UNKNOWN;
|
||||
|
||||
return sizeof(php_stream_dirent);
|
||||
}
|
||||
|
@ -1485,6 +1485,11 @@ PHP_METHOD(RecursiveDirectoryIterator, hasChildren)
|
||||
if (spl_filesystem_is_invalid_or_dot(intern->u.dir.entry.d_name)) {
|
||||
RETURN_FALSE;
|
||||
} else {
|
||||
if (intern->u.dir.entry.d_type == DT_DIR) {
|
||||
RETURN_TRUE;
|
||||
} else if (intern->u.dir.entry.d_type == DT_REG) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
if (spl_filesystem_object_get_file_name(intern) == FAILURE) {
|
||||
RETURN_THROWS();
|
||||
}
|
||||
|
@ -629,6 +629,7 @@ static ssize_t php_ftp_dirstream_read(php_stream *stream, char *buf, size_t coun
|
||||
memcpy(ent->d_name, ZSTR_VAL(basename), tmp_len);
|
||||
ent->d_name[tmp_len - 1] = '\0';
|
||||
zend_string_release_ex(basename, 0);
|
||||
ent->d_type = DT_UNKNOWN;
|
||||
|
||||
/* Trim off trailing whitespace characters */
|
||||
while (tmp_len > 0 &&
|
||||
|
@ -112,6 +112,7 @@ typedef struct _php_stream_dirent {
|
||||
#else
|
||||
char d_name[MAXPATHLEN];
|
||||
#endif
|
||||
unsigned char d_type;
|
||||
} php_stream_dirent;
|
||||
|
||||
/* operations on streams that are file-handles */
|
||||
|
@ -150,6 +150,7 @@ static ssize_t php_glob_stream_read(php_stream *stream, char *buf, size_t count)
|
||||
php_glob_stream_path_split(pglob, pglob->glob.gl_pathv[index], pglob->flags & GLOB_APPEND, &path);
|
||||
++pglob->index;
|
||||
PHP_STRLCPY(ent->d_name, path, sizeof(ent->d_name), strlen(path));
|
||||
ent->d_type = DT_UNKNOWN;
|
||||
return sizeof(php_stream_dirent);
|
||||
}
|
||||
pglob->index = glob_result_count;
|
||||
|
@ -1032,6 +1032,11 @@ static ssize_t php_plain_files_dirstream_read(php_stream *stream, char *buf, siz
|
||||
result = readdir(dir);
|
||||
if (result) {
|
||||
PHP_STRLCPY(ent->d_name, result->d_name, sizeof(ent->d_name), strlen(result->d_name));
|
||||
#ifdef _DIRENT_HAVE_D_TYPE
|
||||
ent->d_type = result->d_type;
|
||||
#else
|
||||
ent->d_type = DT_UNKNOWN;
|
||||
#endif
|
||||
return sizeof(php_stream_dirent);
|
||||
}
|
||||
return 0;
|
||||
|
@ -1320,6 +1320,7 @@ static ssize_t php_userstreamop_readdir(php_stream *stream, char *buf, size_t co
|
||||
if (call_result == SUCCESS && Z_TYPE(retval) != IS_FALSE && Z_TYPE(retval) != IS_TRUE) {
|
||||
convert_to_string(&retval);
|
||||
PHP_STRLCPY(ent->d_name, Z_STRVAL(retval), sizeof(ent->d_name), Z_STRLEN(retval));
|
||||
ent->d_type = DT_UNKNOWN;
|
||||
|
||||
didread = sizeof(php_stream_dirent);
|
||||
} else if (call_result == FAILURE) {
|
||||
|
@ -120,6 +120,13 @@ struct dirent *readdir(DIR *dp)
|
||||
|
||||
dp->dent.d_ino = 1;
|
||||
dp->dent.d_off = dp->offset;
|
||||
if (dp->fileinfo.dwFileAttributes & (FILE_ATTRIBUTE_REPARSE_POINT | FILE_ATTRIBUTE_DEVICE)) {
|
||||
dp->dent.d_type = DT_UNKNOWN; /* conservative */
|
||||
} else if (dp->fileinfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
|
||||
dp->dent.d_type = DT_DIR;
|
||||
} else {
|
||||
dp->dent.d_type = DT_REG;
|
||||
}
|
||||
|
||||
return &(dp->dent);
|
||||
}/*}}}*/
|
||||
|
@ -15,11 +15,17 @@ extern "C" {
|
||||
|
||||
#include "ioutil.h"
|
||||
|
||||
#define _DIRENT_HAVE_D_TYPE
|
||||
#define DT_UNKNOWN 0
|
||||
#define DT_DIR 4
|
||||
#define DT_REG 8
|
||||
|
||||
/* struct dirent - same as Unix */
|
||||
struct dirent {
|
||||
long d_ino; /* inode (always 1 in WIN32) */
|
||||
off_t d_off; /* offset to this dirent */
|
||||
unsigned short d_reclen; /* length of d_name */
|
||||
unsigned char d_type;
|
||||
char d_name[1]; /* null terminated filename in the current encoding, glyph number <= 255 wchar_t's + \0 byte */
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user