]> granicus.if.org Git - php/commitdiff
- add lstat support for Windows
authorPierre Joye <pajoye@php.net>
Wed, 1 Sep 2010 09:49:53 +0000 (09:49 +0000)
committerPierre Joye <pajoye@php.net>
Wed, 1 Sep 2010 09:49:53 +0000 (09:49 +0000)
TSRM/tsrm_virtual_cwd.c
TSRM/tsrm_virtual_cwd.h
main/streams/plain_wrapper.c
main/streams/streams.c
main/win95nt.h

index 197948f598b1dc98543eff80854e12bdd9050794..48aeeb59c20d0429ba7831d589a8fcf1d333d31b 100644 (file)
@@ -14,6 +14,7 @@
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans <andi@zend.com>                                |
    |          Sascha Schumann <sascha@schumann.cx>                        |
+   |          Pierre Joye <pierre@php.net>                                |
    +----------------------------------------------------------------------+
 */
 
 # endif
 #endif
 
+#ifndef S_IFLNK
+# define S_IFLNK 0120000
+#endif
+
 #ifdef NETWARE
 #include <fsio.h>
 #endif
@@ -202,7 +207,7 @@ static inline time_t FileTimeToUnixTime(const FILETIME FileTime)
        return (time_t)UnixTime;
 }
 
-CWD_API int php_sys_stat(const char *path, struct stat *buf) /* {{{ */
+CWD_API int php_sys_stat_ex(const char *path, struct stat *buf, int lstat) /* {{{ */
 {
        WIN32_FILE_ATTRIBUTE_DATA data;
        __int64 t;
@@ -247,9 +252,46 @@ CWD_API int php_sys_stat(const char *path, struct stat *buf) /* {{{ */
                        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 (lstat && data.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
+               /* File is a reparse point. Get the target */
+               HANDLE hLink = NULL;
+               REPARSE_DATA_BUFFER * pbuffer;
+               unsigned int retlength = 0;
+               TSRM_ALLOCA_FLAG(use_heap_large);
+
+               hLink = CreateFile(path, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS, NULL);
+               if(hLink == INVALID_HANDLE_VALUE) {
+                       return -1;
+               }
+
+               pbuffer = (REPARSE_DATA_BUFFER *)tsrm_do_alloca(MAXIMUM_REPARSE_DATA_BUFFER_SIZE, use_heap_large);
+               if(!DeviceIoControl(hLink, FSCTL_GET_REPARSE_POINT, NULL, 0, pbuffer,  MAXIMUM_REPARSE_DATA_BUFFER_SIZE, &retlength, NULL)) {
+                       tsrm_free_alloca(pbuffer, use_heap_large);
+                       CloseHandle(hLink);
+                       return -1;
+               }
+
+               CloseHandle(hLink);
+
+               if(pbuffer->ReparseTag == IO_REPARSE_TAG_SYMLINK) {
+                       buf->st_mode = S_IFLNK;
+                       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 0 /* Not used yet */
+               else if(pbuffer->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT) {
+                       buf->st_mode |=;
+               }
+#endif
+               tsrm_free_alloca(pbuffer, use_heap_large);
+       } else {
+               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);
 
@@ -1557,7 +1599,6 @@ CWD_API int virtual_stat(const char *path, struct stat *buf TSRMLS_DC) /* {{{ */
 }
 /* }}} */
 
-#if !defined(TSRM_WIN32)
 CWD_API int virtual_lstat(const char *path, struct stat *buf TSRMLS_DC) /* {{{ */
 {
        cwd_state new_state;
@@ -1569,13 +1610,12 @@ CWD_API int virtual_lstat(const char *path, struct stat *buf TSRMLS_DC) /* {{{ *
                return -1;
        }
 
-       retval = lstat(new_state.cwd, buf);
+       retval = php_sys_lstat(new_state.cwd, buf);
 
        CWD_STATE_FREE(&new_state);
        return retval;
 }
 /* }}} */
-#endif
 
 CWD_API int virtual_unlink(const char *path TSRMLS_DC) /* {{{ */
 {
index 1636ca6984d334ca4bde3cccfd12022cd9b1473f..44ed99e345aa602adc5cedacfe145704b872e430 100644 (file)
@@ -14,6 +14,7 @@
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans <andi@zend.com>                                |
    |          Sascha Schumann <sascha@schumann.cx>                        |
+   |          Pierre Joye <pierre@php.net>                                |
    +----------------------------------------------------------------------+
 */
 
@@ -129,9 +130,12 @@ typedef unsigned short mode_t;
 #endif
 
 #ifdef TSRM_WIN32
-CWD_API int php_sys_stat(const char *path, struct stat *buf);
+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)
 #else
 # define php_sys_stat stat
+# define php_sys_lstat lstat
 #endif
 
 typedef struct _cwd_state {
@@ -155,9 +159,7 @@ CWD_API int virtual_open(const char *path TSRMLS_DC, int flags, ...);
 CWD_API int virtual_creat(const char *path, mode_t mode TSRMLS_DC);
 CWD_API int virtual_rename(char *oldname, char *newname TSRMLS_DC);
 CWD_API int virtual_stat(const char *path, struct stat *buf TSRMLS_DC);
-#if !defined(TSRM_WIN32)
 CWD_API int virtual_lstat(const char *path, struct stat *buf TSRMLS_DC);
-#endif
 CWD_API int virtual_unlink(const char *path TSRMLS_DC);
 CWD_API int virtual_mkdir(const char *pathname, mode_t mode TSRMLS_DC);
 CWD_API int virtual_rmdir(const char *pathname TSRMLS_DC);
@@ -261,9 +263,7 @@ CWD_API realpath_cache_bucket** realpath_cache_get_buckets(TSRMLS_D);
 #define VCWD_REALPATH(path, real_path) virtual_realpath(path, real_path TSRMLS_CC)
 #define VCWD_RENAME(oldname, newname) virtual_rename(oldname, newname TSRMLS_CC)
 #define VCWD_STAT(path, buff) virtual_stat(path, buff TSRMLS_CC)
-#if !defined(TSRM_WIN32)
 # define VCWD_LSTAT(path, buff) virtual_lstat(path, buff TSRMLS_CC)
-#endif
 #define VCWD_UNLINK(path) virtual_unlink(path TSRMLS_CC)
 #define VCWD_MKDIR(pathname, mode) virtual_mkdir(pathname, mode TSRMLS_CC)
 #define VCWD_RMDIR(pathname) virtual_rmdir(pathname TSRMLS_CC)
index 0f1d8375c1ffc1e4fcd641d4dde963beaf244481..80099757627eaa4558bf97248f22ba8ef0167567 100644 (file)
@@ -1002,10 +1002,18 @@ static int php_plain_files_url_stater(php_stream_wrapper *wrapper, char *url, in
                return -1;
        }
 
-#ifdef HAVE_SYMLINK
+#ifdef PHP_WIN32
+       if (EG(windows_version_info).dwMajorVersion >= 5) {
+               if (flags & PHP_STREAM_URL_STAT_LINK) {
+                       return VCWD_LSTAT(url, &ssb->sb);
+               }
+       }
+#else
+# ifdef HAVE_SYMLINK
        if (flags & PHP_STREAM_URL_STAT_LINK) {
                return VCWD_LSTAT(url, &ssb->sb);
        } else
+# endif
 #endif
                return VCWD_STAT(url, &ssb->sb);
 }
index e698d4eb72f15c72ae73d026acf4a84223f98e45..6aa52b3cb4fc351af264deeb38d2bdd333679af1 100755 (executable)
@@ -1822,7 +1822,6 @@ PHPAPI php_stream *_php_stream_open_wrapper_ex(char *path, char *mode, int optio
        char *resolved_path = NULL;
        char *copy_of_path = NULL;
 
-
        if (opened_path) {
                *opened_path = NULL;
        }
index a5971a7dc27055fa76abcd3225af9c72345d0a1d..cf46056cd7d14c039ed07dd0df43d7d7a0415e5a 100644 (file)
@@ -33,7 +33,7 @@
 typedef int uid_t;
 typedef int gid_t;
 typedef char * caddr_t;
-#define lstat(x, y) stat(x, y)
+#define lstat(x, y) php_sys_lstat(x, y)
 #define                _IFIFO  0010000 /* fifo */
 #define                _IFBLK  0060000 /* block special */
 #define                _IFLNK  0120000 /* symbolic link */