* path.h (INTERIX_SYMLINK_COOKIE): Define.
* path.cc (symlink_info::check_sysfile): Read Interix symlinks as well.
This commit is contained in:
		| @@ -1,3 +1,8 @@ | |||||||
|  | 2009-08-26  Corinna Vinschen  <corinna@vinschen.de> | ||||||
|  |  | ||||||
|  | 	* path.h (INTERIX_SYMLINK_COOKIE): Define. | ||||||
|  | 	* path.cc (symlink_info::check_sysfile): Read Interix symlinks as well. | ||||||
|  |  | ||||||
| 2009-08-26  Corinna Vinschen  <corinna@vinschen.de> | 2009-08-26  Corinna Vinschen  <corinna@vinschen.de> | ||||||
|  |  | ||||||
| 	* fhandler.cc (fhandler_base::open): Only set R/O attribute if ACLs | 	* fhandler.cc (fhandler_base::open): Only set R/O attribute if ACLs | ||||||
|   | |||||||
| @@ -1784,6 +1784,7 @@ symlink_info::check_sysfile (HANDLE in_h) | |||||||
|   NTSTATUS status; |   NTSTATUS status; | ||||||
|   HANDLE h; |   HANDLE h; | ||||||
|   IO_STATUS_BLOCK io; |   IO_STATUS_BLOCK io; | ||||||
|  |   bool interix_symlink = false; | ||||||
|  |  | ||||||
|   InitializeObjectAttributes (&attr, &same, 0, in_h, NULL); |   InitializeObjectAttributes (&attr, &same, 0, in_h, NULL); | ||||||
|   status = NtOpenFile (&h, FILE_READ_DATA | SYNCHRONIZE, |   status = NtOpenFile (&h, FILE_READ_DATA | SYNCHRONIZE, | ||||||
| @@ -1805,7 +1806,26 @@ symlink_info::check_sysfile (HANDLE in_h) | |||||||
|     { |     { | ||||||
|       /* It's a symlink.  */ |       /* It's a symlink.  */ | ||||||
|       pflags = PATH_SYMLINK; |       pflags = PATH_SYMLINK; | ||||||
|  |     } | ||||||
|  |   else if (io.Information == sizeof (cookie_buf) | ||||||
|  | 	   && memcmp (cookie_buf, SOCKET_COOKIE, sizeof (cookie_buf)) == 0) | ||||||
|  |     pflags |= PATH_SOCKET; | ||||||
|  |   else if (io.Information >= sizeof (INTERIX_SYMLINK_COOKIE) | ||||||
|  | 	   && memcmp (cookie_buf, INTERIX_SYMLINK_COOKIE, | ||||||
|  | 		      sizeof (INTERIX_SYMLINK_COOKIE) - 1) == 0) | ||||||
|  |     { | ||||||
|  |       /* It's an Interix symlink.  */ | ||||||
|  |       pflags = PATH_SYMLINK; | ||||||
|  |       interix_symlink = true; | ||||||
|  |       /* Interix symlink cookies are shorter than Cygwin symlink cookies, so | ||||||
|  |          in case of an Interix symlink cooky we have read too far into the | ||||||
|  | 	 file.  Set file pointer back to the position right after the cookie. */ | ||||||
|  |       FILE_POSITION_INFORMATION fpi; | ||||||
|  |       fpi.CurrentByteOffset.QuadPart = sizeof (INTERIX_SYMLINK_COOKIE) - 1; | ||||||
|  |       NtSetInformationFile (h, &io, &fpi, sizeof fpi, FilePositionInformation); | ||||||
|  |     } | ||||||
|  |   if (pflags == PATH_SYMLINK) | ||||||
|  |     { | ||||||
|       status = NtReadFile (h, NULL, NULL, NULL, &io, srcbuf, |       status = NtReadFile (h, NULL, NULL, NULL, &io, srcbuf, | ||||||
| 			   NT_MAX_PATH, NULL, NULL); | 			   NT_MAX_PATH, NULL, NULL); | ||||||
|       if (!NT_SUCCESS (status)) |       if (!NT_SUCCESS (status)) | ||||||
| @@ -1814,10 +1834,17 @@ symlink_info::check_sysfile (HANDLE in_h) | |||||||
| 	  if (status != STATUS_END_OF_FILE) | 	  if (status != STATUS_END_OF_FILE) | ||||||
| 	    set_error (EIO); | 	    set_error (EIO); | ||||||
| 	} | 	} | ||||||
|       else if (*(PWCHAR) srcbuf == 0xfeff)	/* BOM */ |       else if (*(PWCHAR) srcbuf == 0xfeff 	/* BOM */ | ||||||
|  | 	       || interix_symlink) | ||||||
| 	{ | 	{ | ||||||
|  | 	  /* Add trailing 0 to Interix symlink target.  Skip BOM in Cygwin | ||||||
|  | 	     symlinks. */ | ||||||
|  | 	  if (interix_symlink) | ||||||
|  | 	    ((PWCHAR) srcbuf)[io.Information / sizeof (WCHAR)] = L'\0'; | ||||||
|  | 	  else | ||||||
|  | 	    srcbuf += 2; | ||||||
| 	  char *tmpbuf = tp.c_get (); | 	  char *tmpbuf = tp.c_get (); | ||||||
| 	  if (sys_wcstombs (tmpbuf, NT_MAX_PATH, (PWCHAR) (srcbuf + 2)) | 	  if (sys_wcstombs (tmpbuf, NT_MAX_PATH, (PWCHAR) srcbuf) | ||||||
| 	      > SYMLINK_MAX + 1) | 	      > SYMLINK_MAX + 1) | ||||||
| 	    debug_printf ("symlink string too long"); | 	    debug_printf ("symlink string too long"); | ||||||
| 	  else | 	  else | ||||||
| @@ -1828,9 +1855,6 @@ symlink_info::check_sysfile (HANDLE in_h) | |||||||
|       else |       else | ||||||
| 	res = posixify (srcbuf); | 	res = posixify (srcbuf); | ||||||
|     } |     } | ||||||
|   else if (io.Information == sizeof (cookie_buf) |  | ||||||
| 	   && memcmp (cookie_buf, SOCKET_COOKIE, sizeof (cookie_buf)) == 0) |  | ||||||
|     pflags |= PATH_SOCKET; |  | ||||||
|   NtClose (h); |   NtClose (h); | ||||||
|   return res; |   return res; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -258,6 +258,9 @@ class path_conv | |||||||
| /* Socket marker */ | /* Socket marker */ | ||||||
| #define SOCKET_COOKIE  "!<socket >" | #define SOCKET_COOKIE  "!<socket >" | ||||||
|  |  | ||||||
|  | /* Interix symlink marker */ | ||||||
|  | #define INTERIX_SYMLINK_COOKIE  "IntxLNK\1" | ||||||
|  |  | ||||||
| int __stdcall slash_unc_prefix_p (const char *path) __attribute__ ((regparm(1))); | int __stdcall slash_unc_prefix_p (const char *path) __attribute__ ((regparm(1))); | ||||||
|  |  | ||||||
| enum fe_types | enum fe_types | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user