summaryrefslogtreecommitdiffstats
path: root/PATCHES/0003-Windows-Follow-Posix-dir-exists-semantics-more-close.patch
diff options
context:
space:
mode:
Diffstat (limited to 'PATCHES/0003-Windows-Follow-Posix-dir-exists-semantics-more-close.patch')
-rw-r--r--PATCHES/0003-Windows-Follow-Posix-dir-exists-semantics-more-close.patch130
1 files changed, 130 insertions, 0 deletions
diff --git a/PATCHES/0003-Windows-Follow-Posix-dir-exists-semantics-more-close.patch b/PATCHES/0003-Windows-Follow-Posix-dir-exists-semantics-more-close.patch
new file mode 100644
index 0000000..f4ce341
--- /dev/null
+++ b/PATCHES/0003-Windows-Follow-Posix-dir-exists-semantics-more-close.patch
@@ -0,0 +1,130 @@
+From 9f49390e2cd9085ca1cc03906a146861dbe8135f Mon Sep 17 00:00:00 2001
+From: Ray Donnelly <mingw.android@gmail.com>
+Date: Wed, 5 Aug 2015 23:36:07 +0100
+Subject: [PATCH 03/15] Windows: Follow Posix dir-exists semantics more closely
+
+Make Windows behave the same as Posix in the consideration
+of whether folder "/doesnt-exist/.." is a valid
+path. In Posix, it isn't.
+
+A concrete instance of when this matters is when cross
+compiling GNU/Linux glibc on Windows.
+---
+ libcpp/files.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 87 insertions(+)
+
+diff --git a/libcpp/files.c b/libcpp/files.c
+index ea2cc23..ac17272 100644
+--- a/libcpp/files.c
++++ b/libcpp/files.c
+@@ -30,6 +30,13 @@ along with this program; see the file COPYING3. If not see
+ #include "md5.h"
+ #include <dirent.h>
+
++/* Needed for stat_st_mode_symlink below */
++#if defined(_WIN32)
++# include <windows.h>
++# define S_IFLNK 0xF000
++# define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
++#endif
++
+ /* Variable length record files on VMS will have a stat size that includes
+ record control characters that won't be included in the read size. */
+ #ifdef VMS
+@@ -198,6 +205,49 @@ static int pchf_save_compare (const void *e1, const void *e2);
+ static int pchf_compare (const void *d_p, const void *e_p);
+ static bool check_file_against_entries (cpp_reader *, _cpp_file *, bool);
+
++#if defined(_WIN32)
++
++static int stat_st_mode_symlink (char const* path, struct stat* buf)
++{
++ WIN32_FILE_ATTRIBUTE_DATA attr;
++ memset(buf,0,sizeof(*buf));
++ int err = GetFileAttributesExA (path, GetFileExInfoStandard, &attr) ? 0 : 1;
++ if (!err)
++ {
++ WIN32_FIND_DATAA finddata;
++ HANDLE h = FindFirstFileA (path, &finddata);
++ if (h != INVALID_HANDLE_VALUE)
++ {
++ FindClose (h);
++ if ((finddata.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) &&
++ (finddata.dwReserved0 == IO_REPARSE_TAG_SYMLINK))
++ buf->st_mode = S_IFLNK;
++ else if (finddata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
++ buf->st_mode = S_IFDIR;
++ else if (finddata.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE)
++ buf->st_mode = S_IFDIR;
++ else
++ buf->st_mode = S_IFREG;
++ buf->st_mode |= S_IREAD;
++ if (!(finddata.dwFileAttributes & FILE_ATTRIBUTE_READONLY))
++ buf->st_mode |= S_IWRITE;
++ }
++ else
++ {
++ buf->st_mode = S_IFDIR;
++ }
++ return 0;
++ }
++ return -1;
++}
++
++#else
++
++#define stat_st_mode_symlink (_name, _buf) stat ((_name), (_buf))
++
++#endif
++
++
+ /* Given a filename in FILE->PATH, with the empty string interpreted
+ as <stdin>, open it.
+
+@@ -227,6 +277,43 @@ open_file (_cpp_file *file)
+ }
+ else
+ file->fd = open (file->path, O_RDONLY | O_NOCTTY | O_BINARY, 0666);
++#if defined(_WIN32) || defined(__CYGWIN__)
++ /* Windows and Posix differ in the face of paths of the form:
++ nonexistantdir/.. in that Posix will return ENOENT whereas
++ Windows won't care that we stepped into a non-existant dir
++ Only do these slow checks if ".." appears in file->path.
++ Cygwin also suffers from the same problem (but doesn't need
++ a new stat function):
++ http://cygwin.com/ml/cygwin/2013-05/msg00222.html
++ */
++ if (file->fd > 0)
++ {
++ char filepath[MAX_PATH];
++ strncpy (filepath, file->path, sizeof(filepath) - 1);
++ char* dirsep = &filepath[0];
++ while ( (dirsep = strchr (dirsep, '\\')) != NULL)
++ *dirsep = '/';
++ if (strstr(file->path, "/../"))
++ {
++ dirsep = &filepath[0];
++ char dirsepc;
++ /* Check each directory in the chain. */
++ while ( (dirsep = strpbrk (dirsep, "\\/")) != NULL)
++ {
++ dirsepc = *(++dirsep);
++ *dirsep = '\0';
++ if (stat_st_mode_symlink (filepath, &file->st) == -1)
++ {
++ *dirsep = dirsepc;
++ close (file->fd);
++ file->fd = -1;
++ return false;
++ }
++ *dirsep++ = dirsepc;
++ }
++ }
++ }
++#endif
+
+ if (file->fd != -1)
+ {
+--
+2.8.1
+