diff options
author | Dmitry Stogov <dmitry@php.net> | 2006-11-10 15:04:07 +0000 |
---|---|---|
committer | Dmitry Stogov <dmitry@php.net> | 2006-11-10 15:04:07 +0000 |
commit | ce958eded56ddb44d9d362a5b4d007543b6c82bc (patch) | |
tree | 801652e6ea19cff8a1ee131c240ced95717e54ff | |
parent | 40d3abba416d9db2a42bc7ecac8b2a85d5199663 (diff) | |
download | php-git-ce958eded56ddb44d9d362a5b4d007543b6c82bc.tar.gz |
stat() is reimplemented using using GetFileAttributesEx().
The new implementation is faster then implementation in MS VC CRT, but it doesn't support Windows 95.
-rw-r--r-- | NEWS | 3 | ||||
-rw-r--r-- | TSRM/tsrm_virtual_cwd.c | 88 | ||||
-rw-r--r-- | TSRM/tsrm_virtual_cwd.h | 8 |
3 files changed, 95 insertions, 4 deletions
@@ -9,6 +9,9 @@ PHP NEWS In case of modification of corresponding registry-tree PHP will reload it automatic . start timiout thread only if necessary + . stat() is reimplemented using using GetFileAttributesEx(). + The new implementation is faster then implementation in MS VC CRT, but + it doesn't support Windows 95. - Streams optimization (Dmitry) . removed unnecessary ftell() calls (one call for each included PHP file) . disabled calls to read() after EOF diff --git a/TSRM/tsrm_virtual_cwd.c b/TSRM/tsrm_virtual_cwd.c index 30c83f06cf..15d30d0742 100644 --- a/TSRM/tsrm_virtual_cwd.c +++ b/TSRM/tsrm_virtual_cwd.c @@ -140,11 +140,93 @@ static int php_check_dots(const char *element, int n) #define CWD_STATE_FREE(s) \ free((s)->cwd); +#ifdef TSRM_WIN32 +CWD_API int php_sys_stat(const char *path, struct stat *buf) +{ + WIN32_FILE_ATTRIBUTE_DATA data; + __int64 t; + + if (!GetFileAttributesEx(path, GetFileExInfoStandard, &data)) { + return stat(path, buf); + } + + if (path[1] == ':') { + if (path[0] >= 'A' && path[0] <= 'Z') { + buf->st_dev = buf->st_rdev = path[0] - 'A'; + } else { + buf->st_dev = buf->st_rdev = path[0] - 'a'; + } + } else { + char cur_path[MAXPATHLEN+1]; + DWORD len = sizeof(cur_path); + char *tmp = cur_path; + + while(1) { + DWORD r = GetCurrentDirectory(len, tmp); + if (r < len) { + if (tmp[1] == ':') { + if (path[0] >= 'A' && path[0] <= 'Z') { + buf->st_dev = buf->st_rdev = path[0] - 'A'; + } else { + buf->st_dev = buf->st_rdev = path[0] - 'a'; + } + } else { + buf->st_dev = buf->st_rdev = -1; + } + break; + } else if (!r) { + buf->st_dev = buf->st_rdev = -1; + break; + } else { + len = r+1; + tmp = (char*)malloc(len); + } + } + if (tmp != cur_path) { + free(tmp); + } + } + buf->st_uid = buf->st_gid = buf->st_ino = 0; + buf->st_mode = (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? (S_IFDIR|S_IEXEC|(S_IEXEC>>3)|(S_IEXEC>>6)) : S_IFREG; + buf->st_mode |= (data.dwFileAttributes & FILE_ATTRIBUTE_READONLY) ? (S_IREAD|(S_IREAD>>3)|(S_IREAD>>6)) : (S_IREAD|(S_IREAD>>3)|(S_IREAD>>6)|S_IWRITE|(S_IWRITE>>3)|(S_IWRITE>>6)); + if ((data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) { + int len = strlen(path); + + if (path[len-4] == '.') { + if (_memicmp(path+len-3, "exe", 3) == 0 || + _memicmp(path+len-3, "com", 3) == 0 || + _memicmp(path+len-3, "bat", 3) == 0 || + _memicmp(path+len-3, "cmd", 3) == 0) { + buf->st_mode |= (S_IEXEC|(S_IEXEC>>3)|(S_IEXEC>>6)); + } + } + } + buf->st_nlink = 1; + t = data.nFileSizeHigh; + t = t << 32; + t |= data.nFileSizeLow; + buf->st_size = t; + t = data.ftLastAccessTime.dwHighDateTime; + t = t << 32; + t |= data.ftLastAccessTime.dwLowDateTime; + buf->st_atime = (unsigned long)((t / 10000000) - 11644473600); + t = data.ftCreationTime.dwHighDateTime; + t = t << 32; + t |= data.ftCreationTime.dwLowDateTime; + buf->st_ctime = (unsigned long)((t / 10000000) - 11644473600); + t = data.ftLastWriteTime.dwHighDateTime; + t = t << 32; + t |= data.ftLastWriteTime.dwLowDateTime; + buf->st_mtime = (unsigned long)((t / 10000000) - 11644473600); + return 0; +} +#endif + static int php_is_dir_ok(const cwd_state *state) { struct stat buf; - if (stat(state->cwd, &buf) == 0 && S_ISDIR(buf.st_mode)) + if (php_sys_stat(state->cwd, &buf) == 0 && S_ISDIR(buf.st_mode)) return (0); return (1); @@ -154,7 +236,7 @@ static int php_is_file_ok(const cwd_state *state) { struct stat buf; - if (stat(state->cwd, &buf) == 0 && S_ISREG(buf.st_mode)) + if (php_sys_stat(state->cwd, &buf) == 0 && S_ISREG(buf.st_mode)) return (0); return (1); @@ -838,7 +920,7 @@ CWD_API int virtual_stat(const char *path, struct stat *buf TSRMLS_DC) return -1; } - retval = stat(new_state.cwd, buf); + retval = php_sys_stat(new_state.cwd, buf); CWD_STATE_FREE(&new_state); return retval; diff --git a/TSRM/tsrm_virtual_cwd.h b/TSRM/tsrm_virtual_cwd.h index 9bb8b0f68a..f15fae26ec 100644 --- a/TSRM/tsrm_virtual_cwd.h +++ b/TSRM/tsrm_virtual_cwd.h @@ -126,6 +126,12 @@ typedef unsigned short mode_t; #define CWD_API #endif +#ifdef TSRM_WIN32 +CWD_API int php_sys_stat(const char *path, struct stat *buf); +#else +# define php_sys_stat stat +#endif + typedef struct _cwd_state { char *cwd; int cwd_length; @@ -263,7 +269,7 @@ extern virtual_cwd_globals cwd_globals; #define VCWD_CHDIR(path) chdir(path) #define VCWD_CHDIR_FILE(path) virtual_chdir_file(path, chdir) #define VCWD_GETWD(buf) getwd(buf) -#define VCWD_STAT(path, buff) stat(path, buff) +#define VCWD_STAT(path, buff) php_sys_stat(path, buff) #define VCWD_LSTAT(path, buff) lstat(path, buff) #define VCWD_UNLINK(path) unlink(path) #define VCWD_MKDIR(pathname, mode) mkdir(pathname, mode) |