pajoye                                   Wed, 01 Sep 2010 09:49:53 +0000

Revision: http://svn.php.net/viewvc?view=revision&revision=302966

Log:
- add lstat support for Windows

Changed paths:
    U   php/php-src/branches/PHP_5_3/TSRM/tsrm_virtual_cwd.c
    U   php/php-src/branches/PHP_5_3/TSRM/tsrm_virtual_cwd.h
    U   php/php-src/branches/PHP_5_3/main/streams/plain_wrapper.c
    U   php/php-src/branches/PHP_5_3/main/win95nt.h
    U   php/php-src/trunk/TSRM/tsrm_virtual_cwd.c
    U   php/php-src/trunk/TSRM/tsrm_virtual_cwd.h
    U   php/php-src/trunk/main/streams/plain_wrapper.c
    U   php/php-src/trunk/main/streams/streams.c
    U   php/php-src/trunk/main/win95nt.h

Modified: php/php-src/branches/PHP_5_3/TSRM/tsrm_virtual_cwd.c
===================================================================
--- php/php-src/branches/PHP_5_3/TSRM/tsrm_virtual_cwd.c	2010-09-01 08:17:18 UTC (rev 302965)
+++ php/php-src/branches/PHP_5_3/TSRM/tsrm_virtual_cwd.c	2010-09-01 09:49:53 UTC (rev 302966)
@@ -14,6 +14,7 @@
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans <a...@zend.com>                                |
    |          Sascha Schumann <sas...@schumann.cx>                        |
+   |          Pierre Joye <pie...@php.net>                                |
    +----------------------------------------------------------------------+
 */

@@ -40,6 +41,10 @@
 # endif
 #endif

+#ifndef S_IFLNK
+# define S_IFLNK 0120000
+#endif
+
 #ifdef NETWARE
 #include <fsio.h>
 #endif
@@ -202,7 +207,7 @@
 	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 @@
 			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);

@@ -715,8 +757,8 @@
 		memcpy(tmp, path, len+1);

 		if(save &&
-		!(IS_UNC_PATH(path, len) && len >= 3 && path[2] != '?') &&
-		(data.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) {
+				!(IS_UNC_PATH(path, len) && len >= 3 && path[2] != '?') &&
+				(data.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) {
 			/* File is a reparse point. Get the target */
 			HANDLE hLink = NULL;
 			REPARSE_DATA_BUFFER * pbuffer;
@@ -1209,7 +1251,7 @@

 	if (length == 0) {
 		return 1; /* Can't cd to empty string */
-	}
+	}
 	while(--length >= 0 && !IS_SLASH(path[length])) {
 	}

@@ -1558,7 +1600,6 @@
 }
 /* }}} */

-#if !defined(TSRM_WIN32)
 CWD_API int virtual_lstat(const char *path, struct stat *buf TSRMLS_DC) /* {{{ */
 {
 	cwd_state new_state;
@@ -1570,13 +1611,12 @@
 		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) /* {{{ */
 {

Modified: php/php-src/branches/PHP_5_3/TSRM/tsrm_virtual_cwd.h
===================================================================
--- php/php-src/branches/PHP_5_3/TSRM/tsrm_virtual_cwd.h	2010-09-01 08:17:18 UTC (rev 302965)
+++ php/php-src/branches/PHP_5_3/TSRM/tsrm_virtual_cwd.h	2010-09-01 09:49:53 UTC (rev 302966)
@@ -14,6 +14,7 @@
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans <a...@zend.com>                                |
    |          Sascha Schumann <sas...@schumann.cx>                        |
+   |          Pierre Joye <pie...@php.net>                                |
    +----------------------------------------------------------------------+
 */

@@ -129,9 +130,12 @@
 #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_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 @@
 #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_LSTAT(path, buff) virtual_lstat(path, buff TSRMLS_CC)
 #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)

Modified: php/php-src/branches/PHP_5_3/main/streams/plain_wrapper.c
===================================================================
--- php/php-src/branches/PHP_5_3/main/streams/plain_wrapper.c	2010-09-01 08:17:18 UTC (rev 302965)
+++ php/php-src/branches/PHP_5_3/main/streams/plain_wrapper.c	2010-09-01 09:49:53 UTC (rev 302966)
@@ -1017,10 +1017,18 @@
 		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);
 }

Modified: php/php-src/branches/PHP_5_3/main/win95nt.h
===================================================================
--- php/php-src/branches/PHP_5_3/main/win95nt.h	2010-09-01 08:17:18 UTC (rev 302965)
+++ php/php-src/branches/PHP_5_3/main/win95nt.h	2010-09-01 09:49:53 UTC (rev 302966)
@@ -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 */

Modified: php/php-src/trunk/TSRM/tsrm_virtual_cwd.c
===================================================================
--- php/php-src/trunk/TSRM/tsrm_virtual_cwd.c	2010-09-01 08:17:18 UTC (rev 302965)
+++ php/php-src/trunk/TSRM/tsrm_virtual_cwd.c	2010-09-01 09:49:53 UTC (rev 302966)
@@ -14,6 +14,7 @@
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans <a...@zend.com>                                |
    |          Sascha Schumann <sas...@schumann.cx>                        |
+   |          Pierre Joye <pie...@php.net>                                |
    +----------------------------------------------------------------------+
 */

@@ -40,6 +41,10 @@
 # endif
 #endif

+#ifndef S_IFLNK
+# define S_IFLNK 0120000
+#endif
+
 #ifdef NETWARE
 #include <fsio.h>
 #endif
@@ -202,7 +207,7 @@
 	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 @@
 			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 @@
 }
 /* }}} */

-#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 @@
 		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) /* {{{ */
 {

Modified: php/php-src/trunk/TSRM/tsrm_virtual_cwd.h
===================================================================
--- php/php-src/trunk/TSRM/tsrm_virtual_cwd.h	2010-09-01 08:17:18 UTC (rev 302965)
+++ php/php-src/trunk/TSRM/tsrm_virtual_cwd.h	2010-09-01 09:49:53 UTC (rev 302966)
@@ -14,6 +14,7 @@
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans <a...@zend.com>                                |
    |          Sascha Schumann <sas...@schumann.cx>                        |
+   |          Pierre Joye <pie...@php.net>                                |
    +----------------------------------------------------------------------+
 */

@@ -129,9 +130,12 @@
 #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_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 @@
 #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)

Modified: php/php-src/trunk/main/streams/plain_wrapper.c
===================================================================
--- php/php-src/trunk/main/streams/plain_wrapper.c	2010-09-01 08:17:18 UTC (rev 302965)
+++ php/php-src/trunk/main/streams/plain_wrapper.c	2010-09-01 09:49:53 UTC (rev 302966)
@@ -1002,10 +1002,18 @@
 		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);
 }

Modified: php/php-src/trunk/main/streams/streams.c
===================================================================
--- php/php-src/trunk/main/streams/streams.c	2010-09-01 08:17:18 UTC (rev 302965)
+++ php/php-src/trunk/main/streams/streams.c	2010-09-01 09:49:53 UTC (rev 302966)
@@ -1822,7 +1822,6 @@
 	char *resolved_path = NULL;
 	char *copy_of_path = NULL;

-
 	if (opened_path) {
 		*opened_path = NULL;
 	}

Modified: php/php-src/trunk/main/win95nt.h
===================================================================
--- php/php-src/trunk/main/win95nt.h	2010-09-01 08:17:18 UTC (rev 302965)
+++ php/php-src/trunk/main/win95nt.h	2010-09-01 09:49:53 UTC (rev 302966)
@@ -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 */
-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to