diff options
author | Pierre Joye <pajoye@php.net> | 2010-09-10 14:01:44 +0000 |
---|---|---|
committer | Pierre Joye <pajoye@php.net> | 2010-09-10 14:01:44 +0000 |
commit | 391ff7682cc820645307f1966ebb16fc228a3435 (patch) | |
tree | 58d98252418370468578ab5d085ccb64bd6ef3ca /TSRM | |
parent | 6e06a45f24b91d524b4d3c4b51d3ce408948cff6 (diff) | |
download | php-git-391ff7682cc820645307f1966ebb16fc228a3435.tar.gz |
- add php_sys_readlink
Diffstat (limited to 'TSRM')
-rw-r--r-- | TSRM/tsrm_virtual_cwd.c | 56 | ||||
-rw-r--r-- | TSRM/tsrm_virtual_cwd.h | 4 |
2 files changed, 59 insertions, 1 deletions
diff --git a/TSRM/tsrm_virtual_cwd.c b/TSRM/tsrm_virtual_cwd.c index bc1d9bfda6..9e07da6ef6 100644 --- a/TSRM/tsrm_virtual_cwd.c +++ b/TSRM/tsrm_virtual_cwd.c @@ -207,6 +207,60 @@ static inline time_t FileTimeToUnixTime(const FILETIME FileTime) return (time_t)UnixTime; } +CWD_API int php_sys_readlink(const char *link, char *target, size_t target_len){ /* {{{ */ + HINSTANCE kernel32; + HANDLE hFile; + DWORD dwRet; + + typedef BOOL (WINAPI *gfpnh_func)(HANDLE, LPTSTR, DWORD, DWORD); + gfpnh_func pGetFinalPathNameByHandle; + + kernel32 = LoadLibrary("kernel32.dll"); + + if (kernel32) { + pGetFinalPathNameByHandle = (gfpnh_func)GetProcAddress(kernel32, "GetFinalPathNameByHandleA"); + if (pGetFinalPathNameByHandle == NULL) { + return -1; + } + } else { + return -1; + } + + hFile = CreateFile(link, // file to open + GENERIC_READ, // open for reading + FILE_SHARE_READ, // share for reading + NULL, // default security + OPEN_EXISTING, // existing file only + FILE_FLAG_BACKUP_SEMANTICS, // normal file + NULL); // no attr. template + + if( hFile == INVALID_HANDLE_VALUE) { + return -1; + } + + dwRet = pGetFinalPathNameByHandle(hFile, target, MAXPATHLEN, VOLUME_NAME_DOS); + if(dwRet >= MAXPATHLEN) { + return -1; + } + + CloseHandle(hFile); + + if(dwRet > 4) { + /* Skip first 4 characters if they are "\??\" */ + if(target[0] == '\\' && target[1] == '\\' && target[2] == '?' && target[3] == '\\') { + char tmp[MAXPATHLEN]; + + dwRet -= 4; + memcpy(tmp, target + 4, dwRet); + memcpy(target, tmp, dwRet); + } + } + + target[dwRet] = '\0'; + return dwRet; +} +/* }}} */ + CWD_API int php_sys_stat_ex(const char *path, struct stat *buf, int lstat) /* {{{ */ { WIN32_FILE_ATTRIBUTE_DATA data; @@ -756,7 +810,7 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i tmp = tsrm_do_alloca(len+1, use_heap); memcpy(tmp, path, len+1); - if(save && + if(save && !(IS_UNC_PATH(path, len) && len >= 3 && path[2] != '?') && (data.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) { /* File is a reparse point. Get the target */ diff --git a/TSRM/tsrm_virtual_cwd.h b/TSRM/tsrm_virtual_cwd.h index c962dc5874..f80e5c7e6b 100644 --- a/TSRM/tsrm_virtual_cwd.h +++ b/TSRM/tsrm_virtual_cwd.h @@ -133,9 +133,13 @@ typedef unsigned short mode_t; CWD_API int php_sys_stat_ex(const char *path, struct stat *buf, int lstat); # define php_sys_stat(path, buf) php_sys_stat_ex(path, buf, 0) # define php_sys_lstat(path, buf) php_sys_stat_ex(path, buf, 1) +CWD_API int php_sys_readlink(link, target, target_len); #else # define php_sys_stat stat # define php_sys_lstat lstat +# ifdef HAVE_SYMLINK +# define php_sys_readlink(link, target, target_len) readlink(link, target, target_len) +# endif #endif typedef struct _cwd_state { |