Skip to content

Commit

Permalink
- add php_sys_readlink
Browse files Browse the repository at this point in the history
  • Loading branch information
pierrejoye committed Sep 10, 2010
1 parent 2441ddf commit bf0a5ea
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 0 deletions.
54 changes: 54 additions & 0 deletions TSRM/tsrm_virtual_cwd.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
4 changes: 4 additions & 0 deletions TSRM/tsrm_virtual_cwd.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
7 changes: 7 additions & 0 deletions UPGRADING.INTERNALS
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,10 @@ lstat is now available on all platforms. On unix-like platform
php_sys_lstat is an alias to lstat (when avaible). On Windows it is now
available using php_sys_lstat. php_sys_stat and php_sys_lstat usage is recommended
instead of calling lstat directly, to ensure portability.

b. readlink support

readlink is now available on all platforms. On unix-like platform
php_sys_readlink is an alias to readlink (when avaible). On Windows it is now
available using php_sys_readlink. php_sys_readlink usage is recommended
instead of calling readlink directly, to ensure portability.

0 comments on commit bf0a5ea

Please sign in to comment.