diff options
author | Mark A. Hershberger <mah@debian.(none)> | 2009-03-25 00:37:27 -0400 |
---|---|---|
committer | Mark A. Hershberger <mah@debian.(none)> | 2009-03-25 00:37:27 -0400 |
commit | 2d4e5b09576bb4f0ba716cc82cdf29ea04d9184b (patch) | |
tree | 41ccc042009cba53e4ce43e727fcba4c1cfbf7f3 /TSRM | |
parent | d29a4fd2dd3b5d4cf6e80b602544d7b71d794e76 (diff) | |
download | php-2d4e5b09576bb4f0ba716cc82cdf29ea04d9184b.tar.gz |
Imported Upstream version 5.2.2upstream/5.2.2
Diffstat (limited to 'TSRM')
-rw-r--r-- | TSRM/TSRM.c | 2 | ||||
-rw-r--r-- | TSRM/TSRM.h | 19 | ||||
-rw-r--r-- | TSRM/readdir.h | 13 | ||||
-rw-r--r-- | TSRM/tsrm_config_common.h | 6 | ||||
-rw-r--r-- | TSRM/tsrm_nw.c | 4 | ||||
-rw-r--r-- | TSRM/tsrm_nw.h | 2 | ||||
-rw-r--r-- | TSRM/tsrm_virtual_cwd.c | 388 | ||||
-rw-r--r-- | TSRM/tsrm_virtual_cwd.h | 38 | ||||
-rw-r--r-- | TSRM/tsrm_win32.c | 29 | ||||
-rw-r--r-- | TSRM/tsrm_win32.h | 4 |
10 files changed, 352 insertions, 153 deletions
diff --git a/TSRM/TSRM.c b/TSRM/TSRM.c index 8acf0698a..fd6f56481 100644 --- a/TSRM/TSRM.c +++ b/TSRM/TSRM.c @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | Thread Safe Resource Manager | +----------------------------------------------------------------------+ - | Copyright (c) 1999-2006, Andi Gutmans, Sascha Schumann, Zeev Suraski | + | Copyright (c) 1999-2007, Andi Gutmans, Sascha Schumann, Zeev Suraski | | This source file is subject to the TSRM license, that is bundled | | with this package in the file LICENSE | +----------------------------------------------------------------------+ diff --git a/TSRM/TSRM.h b/TSRM/TSRM.h index 2eecd52b6..558f3d07f 100644 --- a/TSRM/TSRM.h +++ b/TSRM/TSRM.h @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | Thread Safe Resource Manager | +----------------------------------------------------------------------+ - | Copyright (c) 1999-2006, Andi Gutmans, Sascha Schumann, Zeev Suraski | + | Copyright (c) 1999-2007, Andi Gutmans, Sascha Schumann, Zeev Suraski | | This source file is subject to the TSRM license, that is bundled | | with this package in the file LICENSE | +----------------------------------------------------------------------+ @@ -13,14 +13,11 @@ #ifndef TSRM_H #define TSRM_H -/* #ifndef WIN32 */ -#ifndef WIN32 -# include <tsrm_config.h> -#endif - -#ifdef WIN32 +#if !defined(__CYGWIN__) && defined(WIN32) # define TSRM_WIN32 # include "tsrm_config.w32.h" +#else +# include <tsrm_config.h> #endif #ifdef TSRM_WIN32 @@ -33,6 +30,14 @@ # define TSRM_API #endif +#ifdef _WIN64 +typedef __int64 tsrm_intptr_t; +typedef unsigned __int64 tsrm_uintptr_t; +#else +typedef long tsrm_intptr_t; +typedef unsigned long tsrm_uintptr_t; +#endif + /* Only compile multi-threading functions if we're in ZTS mode */ #ifdef ZTS diff --git a/TSRM/readdir.h b/TSRM/readdir.h index b0f1ad9e6..139bc7bb7 100644 --- a/TSRM/readdir.h +++ b/TSRM/readdir.h @@ -7,11 +7,15 @@ * on Windows 95/NT. */ +#define _WIN32_WINNT 0x0400 + +#include <windows.h> + #include <io.h> #include <stdio.h> #include <stdlib.h> #include <sys/types.h> - +#include <direct.h> /* struct dirent - same as Unix */ @@ -25,10 +29,10 @@ struct dirent { /* typedef DIR - not the same as Unix */ typedef struct { - long handle; /* _findfirst/_findnext handle */ + HANDLE handle; /* _findfirst/_findnext handle */ short offset; /* offset into directory */ short finished; /* 1 if there are not more files */ - struct _finddata_t fileinfo; /* from _findfirst/_findnext */ + WIN32_FIND_DATA fileinfo; /* from _findfirst/_findnext */ char *dir; /* the dir we are reading */ struct dirent dent; /* the dirent to return */ } DIR; @@ -38,7 +42,6 @@ DIR *opendir(const char *); struct dirent *readdir(DIR *); int readdir_r(DIR *, struct dirent *, struct dirent **); int closedir(DIR *); -void rewinddir(DIR *); - +int rewinddir(DIR *); #endif /* READDIR_H */ diff --git a/TSRM/tsrm_config_common.h b/TSRM/tsrm_config_common.h index 62a7c8efc..0c6a2a183 100644 --- a/TSRM/tsrm_config_common.h +++ b/TSRM/tsrm_config_common.h @@ -1,8 +1,10 @@ #ifndef TSRM_CONFIG_COMMON_H #define TSRM_CONFIG_COMMON_H -#if WINNT|WIN32 -# define TSRM_WIN32 +#ifndef __CYGWIN__ +# if WINNT|WIN32 +# define TSRM_WIN32 +# endif #endif #ifdef TSRM_WIN32 diff --git a/TSRM/tsrm_nw.c b/TSRM/tsrm_nw.c index 7e8301ab6..d12044c7f 100644 --- a/TSRM/tsrm_nw.c +++ b/TSRM/tsrm_nw.c @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2006 The PHP Group | + | Copyright (c) 1997-2007 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: tsrm_nw.c,v 1.8.2.1 2006/01/01 12:50:00 sniper Exp $ */ +/* $Id: tsrm_nw.c,v 1.8.2.1.2.1 2007/01/01 09:35:45 sebastian Exp $ */ #include <stdlib.h> #include <stdio.h> diff --git a/TSRM/tsrm_nw.h b/TSRM/tsrm_nw.h index 1ad9ae752..71acb408a 100644 --- a/TSRM/tsrm_nw.h +++ b/TSRM/tsrm_nw.h @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2006 The PHP Group | + | Copyright (c) 1997-2007 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | diff --git a/TSRM/tsrm_virtual_cwd.c b/TSRM/tsrm_virtual_cwd.c index 5918b85e6..d364c46b3 100644 --- a/TSRM/tsrm_virtual_cwd.c +++ b/TSRM/tsrm_virtual_cwd.c @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2006 The PHP Group | + | Copyright (c) 1997-2007 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: tsrm_virtual_cwd.c,v 1.74.2.9.2.9 2006/10/06 14:03:19 tony2001 Exp $ */ +/* $Id: tsrm_virtual_cwd.c,v 1.74.2.9.2.26 2007/04/12 15:28:58 dmitry Exp $ */ #include <sys/types.h> #include <sys/stat.h> @@ -35,11 +35,6 @@ #ifdef TSRM_WIN32 #include <io.h> #include "tsrm_win32.h" -# if HAVE_NEWAPIS_H -# define WANT_GETLONGPATHNAME_WRAPPER -# define COMPILE_NEWAPIS_STUBS -# include <NewAPIs.h> -# endif #endif #ifdef NETWARE @@ -140,11 +135,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 +231,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); @@ -172,18 +249,7 @@ static void cwd_globals_ctor(virtual_cwd_globals *cwd_globals TSRMLS_DC) static void cwd_globals_dtor(virtual_cwd_globals *cwd_globals TSRMLS_DC) { CWD_STATE_FREE(&cwd_globals->cwd); - { - int i; - - for (i = 0; i < sizeof(cwd_globals->realpath_cache)/sizeof(cwd_globals->realpath_cache[0]); i++) { - realpath_cache_bucket *p = cwd_globals->realpath_cache[i]; - while (p != NULL) { - realpath_cache_bucket *r = p; - p = p->next; - free(r); - } - } - } + realpath_cache_clean(TSRMLS_C); } static char *tsrm_strndup(const char *s, size_t length) @@ -306,14 +372,51 @@ CWD_API char *virtual_getcwd(char *buf, size_t size TSRMLS_DC) static inline unsigned long realpath_cache_key(const char *path, int path_len) { - register unsigned long h; - - const char *e = path + path_len; - for (h = 2166136261U; path < e; ) { - h *= 16777619; - h ^= *path++; - } - return h; + register unsigned long h; + const char *e = path + path_len; + + for (h = 2166136261U; path < e;) { + h *= 16777619; + h ^= *path++; + } + + return h; +} + +CWD_API void realpath_cache_clean(TSRMLS_D) +{ + int i; + + for (i = 0; i < sizeof(CWDG(realpath_cache))/sizeof(CWDG(realpath_cache)[0]); i++) { + realpath_cache_bucket *p = CWDG(realpath_cache)[i]; + while (p != NULL) { + realpath_cache_bucket *r = p; + p = p->next; + free(r); + } + CWDG(realpath_cache)[i] = NULL; + } + CWDG(realpath_cache_size) = 0; +} + +CWD_API void realpath_cache_del(const char *path, int path_len TSRMLS_DC) +{ + unsigned long key = realpath_cache_key(path, path_len); + unsigned long n = key % (sizeof(CWDG(realpath_cache)) / sizeof(CWDG(realpath_cache)[0])); + realpath_cache_bucket **bucket = &CWDG(realpath_cache)[n]; + + while (*bucket != NULL) { + if (key == (*bucket)->key && path_len == (*bucket)->path_len && + memcmp(path, (*bucket)->path, path_len) == 0) { + realpath_cache_bucket *r = *bucket; + *bucket = (*bucket)->next; + CWDG(realpath_cache_size) -= sizeof(realpath_cache_bucket) + r->path_len + 1 + r->realpath_len + 1; + free(r); + return; + } else { + bucket = &(*bucket)->next; + } + } } static inline void realpath_cache_add(const char *path, int path_len, const char *realpath, int realpath_len, time_t t TSRMLS_DC) @@ -334,7 +437,7 @@ static inline void realpath_cache_add(const char *path, int path_len, const char n = bucket->key % (sizeof(CWDG(realpath_cache)) / sizeof(CWDG(realpath_cache)[0])); bucket->next = CWDG(realpath_cache)[n]; CWDG(realpath_cache)[n] = bucket; - CWDG(realpath_cache_size) += size; + CWDG(realpath_cache_size) += size; } } @@ -371,7 +474,11 @@ CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func realpath_cache_bucket *bucket; time_t t = 0; int ret; + int use_cache; + int use_relative_path = 0; TSRMLS_FETCH(); + + use_cache = ((use_realpath != CWD_EXPAND) && CWDG(realpath_cache_size_limit)); if (path_length == 0) return (0); @@ -385,27 +492,32 @@ CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func /* cwd_length can be 0 when getcwd() fails. * This can happen under solaris when a dir does not have read permissions * but *does* have execute permissions */ - if (!IS_ABSOLUTE_PATH(path, path_length) && (state->cwd_length > 0)) { - int orig_path_len; - int state_cwd_length = state->cwd_length; + if (!IS_ABSOLUTE_PATH(path, path_length)) { + if (state->cwd_length == 0) { + use_cache = 0; + use_relative_path = 1; + } else { + int orig_path_len; + int state_cwd_length = state->cwd_length; #ifdef TSRM_WIN32 - if (IS_SLASH(path[0])) { - state_cwd_length = 2; - } + if (IS_SLASH(path[0])) { + state_cwd_length = 2; + } #endif - orig_path_len = path_length + state_cwd_length + 1; - if (orig_path_len >= MAXPATHLEN) { - return 1; + orig_path_len = path_length + state_cwd_length + 1; + if (orig_path_len >= MAXPATHLEN) { + return 1; + } + memcpy(orig_path, state->cwd, state_cwd_length); + orig_path[state_cwd_length] = DEFAULT_SLASH; + memcpy(orig_path + state_cwd_length + 1, path, path_length + 1); + path = orig_path; + path_length = orig_path_len; } - memcpy(orig_path, state->cwd, state_cwd_length); - orig_path[state_cwd_length] = DEFAULT_SLASH; - memcpy(orig_path + state_cwd_length + 1, path, path_length + 1); - path = orig_path; - path_length = orig_path_len; } - if (use_realpath && CWDG(realpath_cache_size_limit)) { + if (use_cache) { t = CWDG(realpath_cache_ttl)?time(NULL):0; if ((bucket = realpath_cache_find(path, path_length, t TSRMLS_CC)) != NULL) { int len = bucket->realpath_len; @@ -425,11 +537,14 @@ CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func } } - if (use_realpath) { + if (use_realpath != CWD_EXPAND) { #if !defined(TSRM_WIN32) && !defined(NETWARE) char resolved_path[MAXPATHLEN]; if (!realpath(path, resolved_path)) { /* Note: Not threadsafe on older *BSD's */ + if (use_realpath == CWD_REALPATH) { + return 1; + } goto no_realpath; } CWD_STATE_COPY(&old_state, state); @@ -442,15 +557,19 @@ CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func #endif } else { char *ptr, *path_copy, *free_path; - char *tok = NULL; + char *tok; int ptr_length; - +#ifdef TSRM_WIN32 + int is_unc; +#endif no_realpath: free_path = path_copy = tsrm_strndup(path, path_length); CWD_STATE_COPY(&old_state, state); -#ifdef TSRM_WIN32 +#ifdef TSRM_WIN32 + ret = 0; + is_unc = 0; if (path_length >= 2 && path[1] == ':') { state->cwd = (char *) realloc(state->cwd, 2 + 1); state->cwd[0] = toupper(path[0]); @@ -464,6 +583,7 @@ no_realpath: state->cwd[1] = '\0'; state->cwd_length = 1; path_copy += 2; + is_unc = 2; } else { #endif state->cwd = (char *) realloc(state->cwd, 1); @@ -473,6 +593,7 @@ no_realpath: } #endif + tok = NULL; ptr = tsrm_strtok_r(path_copy, TOKENIZER_STRING, &tok); while (ptr) { ptr_length = strlen(ptr); @@ -480,6 +601,12 @@ no_realpath: if (IS_DIRECTORY_UP(ptr, ptr_length)) { char save; + if (use_relative_path) { + CWD_STATE_FREE(state); + *state = old_state; + return 1; + } + save = DEFAULT_SLASH; #define PREVIOUS state->cwd[state->cwd_length - 1] @@ -499,37 +626,42 @@ no_realpath: state->cwd_length--; } } else if (!IS_DIRECTORY_CURRENT(ptr, ptr_length)) { - state->cwd = (char *) realloc(state->cwd, state->cwd_length+ptr_length+1+1); + if (use_relative_path) { + state->cwd = (char *) realloc(state->cwd, state->cwd_length+ptr_length+1); + use_relative_path = 0; + } else { + state->cwd = (char *) realloc(state->cwd, state->cwd_length+ptr_length+1+1); #ifdef TSRM_WIN32 - /* Windows 9x will consider C:\\Foo as a network path. Avoid it. */ - if (state->cwd_length < 2 || - (state->cwd[state->cwd_length-1]!='\\' && state->cwd[state->cwd_length-1]!='/') || - IsDBCSLeadByte(state->cwd[state->cwd_length-2])) { - state->cwd[state->cwd_length++] = DEFAULT_SLASH; - } + /* Windows 9x will consider C:\\Foo as a network path. Avoid it. */ + if (state->cwd_length < 2 || + (state->cwd[state->cwd_length-1]!='\\' && state->cwd[state->cwd_length-1]!='/') || + IsDBCSLeadByte(state->cwd[state->cwd_length-2])) { + state->cwd[state->cwd_length++] = DEFAULT_SLASH; + } #elif defined(NETWARE) - /* - Below code keeps appending to state->cwd a File system seperator - cases where this appending should not happen is given below, - a) sys: should just be left as it is - b) sys:system should just be left as it is, - Colon is allowed only in the first token as volume names alone can have the : in their names. - Files and Directories cannot have : in their names - So the check goes like this, - For second token and above simply append the DEFAULT_SLASH to the state->cwd. - For first token check for the existence of : - if it exists don't append the DEFAULT_SLASH to the state->cwd. - */ - if(((state->cwd_length == 0) && (strchr(ptr, ':') == NULL)) || (state->cwd_length > 0)) { - state->cwd[state->cwd_length++] = DEFAULT_SLASH; - } + /* + Below code keeps appending to state->cwd a File system seperator + cases where this appending should not happen is given below, + a) sys: should just be left as it is + b) sys:system should just be left as it is, + Colon is allowed only in the first token as volume names alone can have the : in their names. + Files and Directories cannot have : in their names + So the check goes like this, + For second token and above simply append the DEFAULT_SLASH to the state->cwd. + For first token check for the existence of : + if it exists don't append the DEFAULT_SLASH to the state->cwd. + */ + if(((state->cwd_length == 0) && (strchr(ptr, ':') == NULL)) || (state->cwd_length > 0)) { + state->cwd[state->cwd_length++] = DEFAULT_SLASH; + } #else - state->cwd[state->cwd_length++] = DEFAULT_SLASH; + state->cwd[state->cwd_length++] = DEFAULT_SLASH; #endif + } memcpy(&state->cwd[state->cwd_length], ptr, ptr_length+1); #ifdef TSRM_WIN32 - if (use_realpath) { + if (use_realpath != CWD_EXPAND) { WIN32_FIND_DATA data; HANDLE hFind; @@ -542,6 +674,15 @@ no_realpath: memcpy(&state->cwd[state->cwd_length], data.cFileName, length+1); ptr_length = length; FindClose(hFind); + ret = 0; + } else if (use_realpath == CWD_REALPATH) { + if (is_unc) { + /* skip share name */ + is_unc--; + ret = 0; + } else { + ret = 1; + } } } #endif @@ -553,6 +694,12 @@ no_realpath: free(free_path); + if ((use_realpath == CWD_REALPATH) && ret) { + CWD_STATE_FREE(state); + *state = old_state; + return 1; + } + if (state->cwd_length == COPY_WHEN_ABSOLUTE(state->cwd)) { state->cwd = (char *) realloc(state->cwd, state->cwd_length+1+1); state->cwd[state->cwd_length] = DEFAULT_SLASH; @@ -561,7 +708,7 @@ no_realpath: } } - if (use_realpath && CWDG(realpath_cache_size_limit)) { + if (use_cache) { realpath_cache_add(path, path_length, state->cwd, state->cwd_length, t TSRMLS_CC); } @@ -582,7 +729,7 @@ no_realpath: CWD_API int virtual_chdir(const char *path TSRMLS_DC) { - return virtual_file_ex(&CWDG(cwd), path, php_is_dir_ok, 1)?-1:0; + return virtual_file_ex(&CWDG(cwd), path, php_is_dir_ok, CWD_REALPATH)?-1:0; } CWD_API int virtual_chdir_file(const char *path, int (*p_chdir)(const char *path TSRMLS_DC) TSRMLS_DC) @@ -624,7 +771,7 @@ CWD_API char *virtual_realpath(const char *path, char *real_path TSRMLS_DC) CWD_STATE_COPY(&new_state, &CWDG(cwd)); - if (virtual_file_ex(&new_state, path, NULL, 1)==0) { + if (virtual_file_ex(&new_state, path, NULL, CWD_REALPATH)==0) { int len = new_state.cwd_length>MAXPATHLEN-1?MAXPATHLEN-1:new_state.cwd_length; memcpy(real_path, new_state.cwd, len); @@ -645,7 +792,7 @@ CWD_API int virtual_filepath_ex(const char *path, char **filepath, verify_path_f int retval; CWD_STATE_COPY(&new_state, &CWDG(cwd)); - retval = virtual_file_ex(&new_state, path, verify_path, 1); + retval = virtual_file_ex(&new_state, path, verify_path, CWD_FILEPATH); *filepath = new_state.cwd; @@ -668,7 +815,8 @@ CWD_API FILE *virtual_fopen(const char *path, const char *mode TSRMLS_DC) } CWD_STATE_COPY(&new_state, &CWDG(cwd)); - if (virtual_file_ex(&new_state, path, NULL, 1)) { + if (virtual_file_ex(&new_state, path, NULL, CWD_FILEPATH)) { + CWD_STATE_FREE(&new_state); return NULL; } @@ -684,7 +832,8 @@ CWD_API int virtual_access(const char *pathname, int mode TSRMLS_DC) int ret; CWD_STATE_COPY(&new_state, &CWDG(cwd)); - if (virtual_file_ex(&new_state, pathname, NULL, 1)) { + if (virtual_file_ex(&new_state, pathname, NULL, CWD_REALPATH)) { + CWD_STATE_FREE(&new_state); return -1; } @@ -707,7 +856,8 @@ CWD_API int virtual_utime(const char *filename, struct utimbuf *buf TSRMLS_DC) int ret; CWD_STATE_COPY(&new_state, &CWDG(cwd)); - if (virtual_file_ex(&new_state, filename, NULL, 0)) { + if (virtual_file_ex(&new_state, filename, NULL, CWD_REALPATH)) { + CWD_STATE_FREE(&new_state); return -1; } @@ -724,7 +874,8 @@ CWD_API int virtual_chmod(const char *filename, mode_t mode TSRMLS_DC) int ret; CWD_STATE_COPY(&new_state, &CWDG(cwd)); - if (virtual_file_ex(&new_state, filename, NULL, 1)) { + if (virtual_file_ex(&new_state, filename, NULL, CWD_REALPATH)) { + CWD_STATE_FREE(&new_state); return -1; } @@ -741,7 +892,8 @@ CWD_API int virtual_chown(const char *filename, uid_t owner, gid_t group, int li int ret; CWD_STATE_COPY(&new_state, &CWDG(cwd)); - if (virtual_file_ex(&new_state, filename, NULL, 0)) { + if (virtual_file_ex(&new_state, filename, NULL, CWD_REALPATH)) { + CWD_STATE_FREE(&new_state); return -1; } @@ -766,7 +918,8 @@ CWD_API int virtual_open(const char *path TSRMLS_DC, int flags, ...) int f; CWD_STATE_COPY(&new_state, &CWDG(cwd)); - if (virtual_file_ex(&new_state, path, NULL, 1)) { + if (virtual_file_ex(&new_state, path, NULL, CWD_FILEPATH)) { + CWD_STATE_FREE(&new_state); return -1; } @@ -792,7 +945,8 @@ CWD_API int virtual_creat(const char *path, mode_t mode TSRMLS_DC) int f; CWD_STATE_COPY(&new_state, &CWDG(cwd)); - if (virtual_file_ex(&new_state, path, NULL, 1)) { + if (virtual_file_ex(&new_state, path, NULL, CWD_FILEPATH)) { + CWD_STATE_FREE(&new_state); return -1; } @@ -809,13 +963,16 @@ CWD_API int virtual_rename(char *oldname, char *newname TSRMLS_DC) int retval; CWD_STATE_COPY(&old_state, &CWDG(cwd)); - if (virtual_file_ex(&old_state, oldname, NULL, 0)) { + if (virtual_file_ex(&old_state, oldname, NULL, CWD_REALPATH)) { + CWD_STATE_FREE(&old_state); return -1; } oldname = old_state.cwd; CWD_STATE_COPY(&new_state, &CWDG(cwd)); - if (virtual_file_ex(&new_state, newname, NULL, 0)) { + if (virtual_file_ex(&new_state, newname, NULL, CWD_FILEPATH)) { + CWD_STATE_FREE(&old_state); + CWD_STATE_FREE(&new_state); return -1; } newname = new_state.cwd; @@ -834,11 +991,12 @@ CWD_API int virtual_stat(const char *path, struct stat *buf TSRMLS_DC) int retval; CWD_STATE_COPY(&new_state, &CWDG(cwd)); - if (virtual_file_ex(&new_state, path, NULL, 1)) { + if (virtual_file_ex(&new_state, path, NULL, CWD_REALPATH)) { + CWD_STATE_FREE(&new_state); return -1; } - retval = stat(new_state.cwd, buf); + retval = php_sys_stat(new_state.cwd, buf); CWD_STATE_FREE(&new_state); return retval; @@ -851,7 +1009,8 @@ CWD_API int virtual_lstat(const char *path, struct stat *buf TSRMLS_DC) int retval; CWD_STATE_COPY(&new_state, &CWDG(cwd)); - if (virtual_file_ex(&new_state, path, NULL, 0)) { + if (virtual_file_ex(&new_state, path, NULL, CWD_REALPATH)) { + CWD_STATE_FREE(&new_state); return -1; } @@ -868,7 +1027,8 @@ CWD_API int virtual_unlink(const char *path TSRMLS_DC) int retval; CWD_STATE_COPY(&new_state, &CWDG(cwd)); - if (virtual_file_ex(&new_state, path, NULL, 0)) { + if (virtual_file_ex(&new_state, path, NULL, CWD_EXPAND)) { + CWD_STATE_FREE(&new_state); return -1; } @@ -884,7 +1044,8 @@ CWD_API int virtual_mkdir(const char *pathname, mode_t mode TSRMLS_DC) int retval; CWD_STATE_COPY(&new_state, &CWDG(cwd)); - if (virtual_file_ex(&new_state, pathname, NULL, 1)) { + if (virtual_file_ex(&new_state, pathname, NULL, CWD_FILEPATH)) { + CWD_STATE_FREE(&new_state); return -1; } @@ -903,7 +1064,8 @@ CWD_API int virtual_rmdir(const char *pathname TSRMLS_DC) int retval; CWD_STATE_COPY(&new_state, &CWDG(cwd)); - if (virtual_file_ex(&new_state, pathname, NULL, 0)) { + if (virtual_file_ex(&new_state, pathname, NULL, CWD_EXPAND)) { + CWD_STATE_FREE(&new_state); return -1; } @@ -923,7 +1085,8 @@ CWD_API DIR *virtual_opendir(const char *pathname TSRMLS_DC) DIR *retval; CWD_STATE_COPY(&new_state, &CWDG(cwd)); - if (virtual_file_ex(&new_state, pathname, NULL, 1)) { + if (virtual_file_ex(&new_state, pathname, NULL, CWD_REALPATH)) { + CWD_STATE_FREE(&new_state); return NULL; } @@ -1033,25 +1196,36 @@ CWD_API FILE *virtual_popen(const char *command, const char *type TSRMLS_DC) #endif -/* On AIX & Tru64 when a file does not exist realpath() returns - * NULL, and sets errno to ENOENT. Unlike in other libc implementations - * the destination is not filled and remains undefined. Therefor, we - * must populate it manually using strcpy as done on systems with no - * realpath() function. - */ -#if defined(__osf__) || defined(_AIX) -char *php_realpath_hack(const char *src, char *dest) +CWD_API char *tsrm_realpath(const char *path, char *real_path TSRMLS_DC) { - char *ret; + cwd_state new_state; + char cwd[MAXPATHLEN]; - if ((ret = realpath(src, dest)) == NULL && errno == ENOENT) { - return strcpy(dest, src); + if (!IS_ABSOLUTE_PATH(path, strlen(path)) && + VCWD_GETCWD(cwd, MAXPATHLEN)) { + new_state.cwd = strdup(cwd); + new_state.cwd_length = strlen(cwd); } else { - return ret; + new_state.cwd = (char*)malloc(1); + new_state.cwd[0] = '\0'; + new_state.cwd_length = 0; } -} -#endif + if (virtual_file_ex(&new_state, path, NULL, CWD_REALPATH)) { + free(new_state.cwd); + return NULL; + } + + if (real_path) { + int copy_len = new_state.cwd_length>MAXPATHLEN-1 ? MAXPATHLEN-1 : new_state.cwd_length; + memcpy(real_path, new_state.cwd, copy_len); + real_path[copy_len] = '\0'; + free(new_state.cwd); + return real_path; + } else { + return new_state.cwd; + } +} /* diff --git a/TSRM/tsrm_virtual_cwd.h b/TSRM/tsrm_virtual_cwd.h index a43482b21..4ee77b7c1 100644 --- a/TSRM/tsrm_virtual_cwd.h +++ b/TSRM/tsrm_virtual_cwd.h @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2006 The PHP Group | + | Copyright (c) 1997-2007 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: tsrm_virtual_cwd.h,v 1.48.2.5.2.2 2006/10/04 13:24:19 tony2001 Exp $ */ +/* $Id: tsrm_virtual_cwd.h,v 1.48.2.5.2.8 2007/01/22 09:31:46 dmitry Exp $ */ #ifndef VIRTUAL_CWD_H #define 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; @@ -172,10 +178,6 @@ CWD_API int virtual_access(const char *pathname, int mode TSRMLS_DC); #endif #endif -#if defined(__osf__) || defined(_AIX) -char *php_realpath_hack(const char *src, char *dest); -#endif - #if HAVE_UTIME CWD_API int virtual_utime(const char *filename, struct utimbuf *buf TSRMLS_DC); #endif @@ -184,8 +186,17 @@ CWD_API int virtual_chmod(const char *filename, mode_t mode TSRMLS_DC); CWD_API int virtual_chown(const char *filename, uid_t owner, gid_t group, int link TSRMLS_DC); #endif +/* One of the following constants must be used as the last argument + in virtual_file_ex() call. */ + +#define CWD_EXPAND 0 /* expand "." and ".." but dont resolve symlinks */ +#define CWD_FILEPATH 1 /* resolve symlinks if file is exist otherwise expand */ +#define CWD_REALPATH 2 /* call realpath(), resolve symlinks. File must exist */ + CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func verify_path, int use_realpath); +CWD_API char *tsrm_realpath(const char *path, char *real_path TSRMLS_DC); + #define REALPATH_CACHE_TTL (2*60) /* 2 minutes */ #define REALPATH_CACHE_SIZE 0 /* disabled while php.ini isn't loaded */ @@ -215,6 +226,9 @@ extern virtual_cwd_globals cwd_globals; # define CWDG(v) (cwd_globals.v) #endif +CWD_API void realpath_cache_clean(TSRMLS_D); +CWD_API void realpath_cache_del(const char *path, int path_len TSRMLS_DC); + /* The actual macros to be used in programs using TSRM * If the program defines VIRTUAL_DIR it will use the * virtual_* functions @@ -265,7 +279,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) @@ -278,15 +292,7 @@ extern virtual_cwd_globals cwd_globals; #define VCWD_ACCESS(pathname, mode) access(pathname, mode) #endif -#ifdef HAVE_REALPATH -#if defined(__osf__) || defined(_AIX) -#define VCWD_REALPATH(path, real_path) php_realpath_hack(path, real_path) -#else -#define VCWD_REALPATH(path, real_path) realpath(path, real_path) -#endif -#else -#define VCWD_REALPATH(path, real_path) strcpy(real_path, path) -#endif +#define VCWD_REALPATH(path, real_path) tsrm_realpath(path, real_path TSRMLS_CC) #if HAVE_UTIME #define VCWD_UTIME(path, time) utime(path, time) diff --git a/TSRM/tsrm_win32.c b/TSRM/tsrm_win32.c index f1bc3dcf3..eb5ae877a 100644 --- a/TSRM/tsrm_win32.c +++ b/TSRM/tsrm_win32.c @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2006 The PHP Group | + | Copyright (c) 1997-2007 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: tsrm_win32.c,v 1.27.2.1 2006/01/01 12:50:00 sniper Exp $ */ +/* $Id: tsrm_win32.c,v 1.27.2.1.2.7 2007/04/16 08:09:54 dmitry Exp $ */ #include <stdio.h> #include <fcntl.h> @@ -86,11 +86,19 @@ TSRM_API void tsrm_win32_shutdown(void) TSRM_API int tsrm_win32_access(const char *pathname, int mode) { - SHFILEINFO sfi; - if (mode == 1 /*X_OK*/) { +#if 1 + /* This code is not supported by Windows 98, + * but we don't support it anymore */ + DWORD type; + + return GetBinaryType(pathname, &type)?0:-1; +#else + SHFILEINFO sfi; + return access(pathname, 0) == 0 && SHGetFileInfo(pathname, 0, &sfi, sizeof(SHFILEINFO), SHGFI_EXETYPE) != 0 ? 0 : -1; +#endif } else { return access(pathname, mode); } @@ -211,7 +219,7 @@ TSRM_API FILE *popen_ex(const char *command, const char *type, const char *cwd, cmd = (char*)malloc(strlen(command)+strlen(TWG(comspec))+sizeof(" /c ")); sprintf(cmd, "%s /c %s", TWG(comspec), command); - if (!CreateProcess(NULL, cmd, &security, &security, security.bInheritHandle, NORMAL_PRIORITY_CLASS, env, cwd, &startup, &process)) { + if (!CreateProcess(NULL, cmd, &security, &security, security.bInheritHandle, NORMAL_PRIORITY_CLASS|CREATE_NO_WINDOW, env, cwd, &startup, &process)) { return NULL; } free(cmd); @@ -220,10 +228,10 @@ TSRM_API FILE *popen_ex(const char *command, const char *type, const char *cwd, proc = process_get(NULL TSRMLS_CC); if (read) { - fno = _open_osfhandle((long)in, _O_RDONLY | mode); + fno = _open_osfhandle((tsrm_intptr_t)in, _O_RDONLY | mode); CloseHandle(out); } else { - fno = _open_osfhandle((long)out, _O_WRONLY | mode); + fno = _open_osfhandle((tsrm_intptr_t)out, _O_WRONLY | mode); CloseHandle(in); } @@ -272,9 +280,6 @@ TSRM_API int shmget(int key, int size, int flags) info_handle = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, shm_info); if ((!shm_handle && !info_handle)) { - if (flags & IPC_EXCL) { - return -1; - } if (flags & IPC_CREAT) { shm_handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, size, shm_segment); info_handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(shm->descriptor), shm_info); @@ -283,6 +288,10 @@ TSRM_API int shmget(int key, int size, int flags) if ((!shm_handle || !info_handle)) { return -1; } + } else { + if (flags & IPC_EXCL) { + return -1; + } } shm = shm_get(key, NULL); diff --git a/TSRM/tsrm_win32.h b/TSRM/tsrm_win32.h index 5b26bb264..1695b117e 100644 --- a/TSRM/tsrm_win32.h +++ b/TSRM/tsrm_win32.h @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2006 The PHP Group | + | Copyright (c) 1997-2007 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: tsrm_win32.h,v 1.19.2.1 2006/01/01 12:50:00 sniper Exp $ */ +/* $Id: tsrm_win32.h,v 1.19.2.1.2.1 2007/01/01 09:35:45 sebastian Exp $ */ #ifndef TSRM_WIN32_H #define TSRM_WIN32_H |