diff options
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.patch | 130 |
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 + |