Patch add_php_sys_readlink for SPL related Bug #51804
Patch version 2010-09-06 15:14 UTC
Return to Bug #51804 |
Download this patch
Patch Revisions:
Developer: pajoye@php.net
Index: ext/spl/spl_directory.c
===================================================================
--- ext/spl/spl_directory.c (revision 303054)
+++ ext/spl/spl_directory.c (working copy)
@@ -1050,10 +1050,25 @@
zend_replace_error_handling(EH_THROW, spl_ce_RuntimeException, &error_handling TSRMLS_CC);
-#ifdef HAVE_SYMLINK
+#ifdef PHP_WIN32
+ if (!IS_ABSOLUTE_PATH(intern->file_name, intern->file_name_len)) {
+ char expanded_path[MAXPATHLEN];
+
+ if (!expand_filepath(intern->file_name, expanded_path TSRMLS_CC)) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "No such file or directory");
+ RETURN_FALSE;
+ }
+ ret = php_sys_readlink(expanded_path, buff, MAXPATHLEN - 1);
+ } else {
+ ret = php_sys_readlink(intern->file_name, buff, MAXPATHLEN-1);
+ }
+
+#else
+# ifdef HAVE_SYMLINK
ret = readlink(intern->file_name, buff, MAXPATHLEN-1);
-#else
+# else
ret = -1; /* always fail if not implemented */
+# endif
#endif
if (ret == -1) {
Index: TSRM/tsrm_virtual_cwd.c
===================================================================
--- TSRM/tsrm_virtual_cwd.c (revision 303054)
+++ TSRM/tsrm_virtual_cwd.c (working copy)
@@ -207,6 +207,61 @@
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;
Index: TSRM/tsrm_virtual_cwd.h
===================================================================
--- TSRM/tsrm_virtual_cwd.h (revision 303054)
+++ TSRM/tsrm_virtual_cwd.h (working copy)
@@ -133,9 +133,13 @@
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)
+# define php_sys_readlink(link, target, target_len) 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 {
|