From 69a127b8f4e353ecb163688ed3271fb47e0f385d Mon Sep 17 00:00:00 2001 From: Laszlo Csomor Date: Thu, 2 Mar 2017 14:02:58 +0000 Subject: ijar: use bazel's file utilities This change not only implements ijar for Windows (with MSVC), but also fixes a bug in mapped_file_windows (path conversion didn't make the input path absolute, so we could not build java code with the MSYS-less bazel). Fixes https://github.com/bazelbuild/bazel/issues/2157 -- PiperOrigin-RevId: 148995025 MOS_MIGRATED_REVID=148995025 --- third_party/ijar/BUILD | 27 ++++--- third_party/ijar/mapped_file_windows.cc | 83 +++++--------------- third_party/ijar/platform_utils.cc | 133 +++++--------------------------- third_party/ijar/platform_utils.h | 5 +- 4 files changed, 60 insertions(+), 188 deletions(-) (limited to 'third_party') diff --git a/third_party/ijar/BUILD b/third_party/ijar/BUILD index 5e97bc84c6..7836ea1bd9 100644 --- a/third_party/ijar/BUILD +++ b/third_party/ijar/BUILD @@ -30,7 +30,18 @@ cc_library( deps = [ ":platform_utils", ":zlib_client", - ], + ] + select({ + "//src:windows": [ + "//src/main/cpp/util:errors", + "//src/main/cpp/util:file", + ], + "//src:windows_msvc": [ + "//src/main/cpp/util:errors", + "//src/main/cpp/util:file", + ], + "//conditions:default": [ + ], + }), ) cc_library( @@ -51,16 +62,10 @@ cc_library( "platform_utils.h", ], visibility = ["//visibility:private"], - deps = select({ - "//src:windows": [ - "//src/main/cpp/util:file", - ], - "//src:windows_msvc": [ - "//src/main/cpp/util:file", - ], - "//conditions:default": [ - ], - }), + deps = [ + "//src/main/cpp/util:errors", + "//src/main/cpp/util:file", + ], ) cc_binary( diff --git a/third_party/ijar/mapped_file_windows.cc b/third_party/ijar/mapped_file_windows.cc index e96f4d41da..5ab6ce05e9 100644 --- a/third_party/ijar/mapped_file_windows.cc +++ b/third_party/ijar/mapped_file_windows.cc @@ -12,34 +12,22 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include // malloc, free #include #include -#ifdef COMPILER_MSVC -#include // exit -#else // not COMPILER_MSVC -#include // cygwin_create_path, CCP_POSIX_TO_WIN_A -#endif // COMPILER_MSVC +#include +#include "src/main/cpp/util/errors.h" +#include "src/main/cpp/util/file_platform.h" #include "third_party/ijar/mapped_file.h" #define MAX_ERROR 2048 namespace devtools_ijar { -static char errmsg[MAX_ERROR] = ""; - -class WindowsPath { - public: - WindowsPath(const char* path); - ~WindowsPath(); - const char* GetWindowsPath() const { return _win_path; } - - private: - char* _win_path; -}; +using std::wstring; +static char errmsg[MAX_ERROR] = ""; void PrintLastError(const char* op) { char *message; @@ -79,11 +67,13 @@ MappedInputFile::MappedInputFile(const char* name) { opened_ = false; errmsg_ = errmsg; - WindowsPath path(name); - char* unicode_path = ToUnicodePath(path.GetWindowsPath()); - HANDLE file = CreateFile(unicode_path, GENERIC_READ, FILE_SHARE_READ, NULL, - OPEN_EXISTING, 0, NULL); - free(unicode_path); + wstring wname; + if (!blaze_util::AsWindowsPathWithUncPrefix(name, &wname)) { + blaze_util::die( + 255, "MappedInputFile(%s): AsWindowsPathWithUncPrefix failed", name); + } + HANDLE file = CreateFileW(wname.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, + OPEN_EXISTING, 0, NULL); if (file == INVALID_HANDLE_VALUE) { PrintLastError("CreateFile()"); return; @@ -98,7 +88,7 @@ MappedInputFile::MappedInputFile(const char* name) { HANDLE mapping = CreateFileMapping(file, NULL, PAGE_READONLY, size.HighPart, size.LowPart, NULL); - if (mapping == NULL) { + if (mapping == NULL || mapping == INVALID_HANDLE_VALUE) { PrintLastError("CreateFileMapping()"); CloseHandle(file); return; @@ -162,11 +152,13 @@ MappedOutputFile::MappedOutputFile(const char* name, u8 estimated_size) { opened_ = false; errmsg_ = errmsg; - WindowsPath path(name); - char* unicode_path = ToUnicodePath(path.GetWindowsPath()); - HANDLE file = CreateFile(unicode_path, GENERIC_READ | GENERIC_WRITE, 0, NULL, - CREATE_ALWAYS, 0, NULL); - free(unicode_path); + wstring wname; + if (!blaze_util::AsWindowsPathWithUncPrefix(name, &wname)) { + blaze_util::die( + 255, "MappedOutputFile(%s): AsWindowsPathWithUncPrefix failed", name); + } + HANDLE file = CreateFileW(wname.c_str(), GENERIC_READ | GENERIC_WRITE, 0, + NULL, CREATE_ALWAYS, 0, NULL); if (file == INVALID_HANDLE_VALUE) { PrintLastError("CreateFile()"); return; @@ -174,7 +166,7 @@ MappedOutputFile::MappedOutputFile(const char* name, u8 estimated_size) { HANDLE mapping = CreateFileMapping(file, NULL, PAGE_READWRITE, estimated_size >> 32, estimated_size & 0xffffffffUL, NULL); - if (mapping == NULL) { + if (mapping == NULL || mapping == INVALID_HANDLE_VALUE) { PrintLastError("CreateFileMapping()"); CloseHandle(file); return; @@ -226,37 +218,4 @@ int MappedOutputFile::Close(int size) { return 0; } -#ifdef COMPILER_MSVC - - WindowsPath::WindowsPath(const char* path) - : _win_path(const_cast(path)) { - // Input path should already be Windows-style, but let's do a sanity check - // nevertheless. Not using assert(2) because we need this even in non-debug - // builds. - if (path[0] == '/') { - fprintf( - stderr, - "ERROR: Illegal state; '%s' is assumed to be a Windows path. This" \ - " is a programming error, fix" \ - " third_party/ijar/mapped_file_windows.cc\n", - path); - exit(1); - } - } - - WindowsPath::~WindowsPath() {} - -#else // not COMPILER_MSVC - - WindowsPath::WindowsPath(const char* path) { - this->_win_path = - reinterpret_cast(cygwin_create_path(CCP_POSIX_TO_WIN_A, path)); - } - - WindowsPath::~WindowsPath() { - free(this->_win_path); - } - -#endif // COMPILER_MSVC - } // namespace devtools_ijar diff --git a/third_party/ijar/platform_utils.cc b/third_party/ijar/platform_utils.cc index e1b46db5b5..29d468a4fc 100644 --- a/third_party/ijar/platform_utils.cc +++ b/third_party/ijar/platform_utils.cc @@ -14,26 +14,22 @@ #include "third_party/ijar/platform_utils.h" -#include #include #include #if defined(COMPILER_MSVC) || defined(__CYGWIN__) #include -#endif // defined(COMPILER_MSVC) || defined(__CYGWIN__) - -#ifndef COMPILER_MSVC -#include +#else // !(defined(COMPILER_MSVC) || defined(__CYGWIN__)) #include +#include #include -#endif // not COMPILER_MSVC +#endif // defined(COMPILER_MSVC) || defined(__CYGWIN__) #include -#if defined(COMPILER_MSVC) || defined(__CYGWIN__) #include "src/main/cpp/util/errors.h" +#include "src/main/cpp/util/file.h" #include "src/main/cpp/util/file_platform.h" -#endif // defined(COMPILER_MSVC) || defined(__CYGWIN__) namespace devtools_ijar { @@ -81,119 +77,30 @@ bool stat_file(const char* path, Stat* result) { #endif // defined(COMPILER_MSVC) || defined(__CYGWIN__) } -bool write_file(const char* path, mode_t perm, const void* data, size_t size) { -#ifdef COMPILER_MSVC - // TODO(laszlocsomor) 2016-12-01: implement this and other methods, in order - // to close https://github.com/bazelbuild/bazel/issues/2157. - fprintf(stderr, "Not yet implemented on Windows\n"); - return false; -#else // not COMPILER_MSVC - int fd = open(path, O_CREAT | O_WRONLY, perm); - if (fd < 0) { - fprintf(stderr, "Cannot open file %s for writing: %s\n", path, - strerror(errno)); - return false; - } - bool result = true; - int error = write(fd, data, size); - // Check for an error condition, or if we didn't write all of the data. - if (error < 0 || static_cast(error) != size) { - fprintf(stderr, "Cannot write %zu bytes to file %s: %s\n", size, path, - strerror(errno)); - result = false; - } - if (close(fd)) { - fprintf(stderr, "Cannot close file %s: %s\n", path, strerror(errno)); - result = false; - } - return result; -#endif // COMPILER_MSVC +bool write_file(const char* path, unsigned int perm, const void* data, + size_t size) { + return blaze_util::WriteFile(data, size, path, perm); } bool read_file(const char* path, void* buffer, size_t size) { -#ifdef COMPILER_MSVC - // TODO(laszlocsomor) 2016-12-01: implement this and other methods, in order - // to close https://github.com/bazelbuild/bazel/issues/2157. - fprintf(stderr, "Not yet implemented on Windows\n"); - return false; -#else // not COMPILER_MSVC - // read the input file - int fd = open(path, O_RDONLY); - if (fd < 0) { - fprintf(stderr, "Can't open file %s for reading: %s\n", path, - strerror(errno)); - return false; - } - bool result = true; - size_t nb_read = 0; - while (nb_read < size) { - size_t to_read = size - nb_read; - if (to_read > 16384 /* 16K */) { - to_read = 16384; - } - ssize_t r = read(fd, static_cast(buffer) + nb_read, to_read); - if (r < 0) { - fprintf(stderr, "Can't read %zu bytes from file %s: %s\n", to_read, path, - strerror(errno)); - result = false; - break; - } - nb_read += r; - } - if (close(fd)) { - fprintf(stderr, "Cannot close file %s: %s\n", path, strerror(errno)); - result = false; - } - return result; -#endif // COMPILER_MSVC + return blaze_util::ReadFile(path, buffer, size); } -string get_cwd() { -#ifdef COMPILER_MSVC - // TODO(laszlocsomor) 2016-12-01: implement this and other methods, in order - // to close https://github.com/bazelbuild/bazel/issues/2157. - fprintf(stderr, "Not yet implemented on Windows\n"); - return ""; -#else // not COMPILER_MSVC - char cwd[PATH_MAX]; - if (getcwd(cwd, PATH_MAX) == NULL) { - fprintf(stderr, "getcwd() failed: %s\n", strerror(errno)); - return ""; - } else { - return string(cwd); - } -#endif // COMPILER_MSVC -} +string get_cwd() { return blaze_util::GetCwd(); } -bool make_dirs(const char* path, mode_t mode) { -#ifdef COMPILER_MSVC - // TODO(laszlocsomor) 2016-12-01: implement this and other methods, in order - // to close https://github.com/bazelbuild/bazel/issues/2157. - fprintf(stderr, "Not yet implemented on Windows\n"); - return false; -#else // not COMPILER_MSVC - // Directories created must have executable bit set and be owner writeable. - // Otherwise, we cannot write or create any file inside. +bool make_dirs(const char* path, unsigned int mode) { +#ifndef COMPILER_MSVC + // TODO(laszlocsomor): respect `mode` on Windows/MSVC. mode |= S_IWUSR | S_IXUSR; - char path_[PATH_MAX]; - Stat file_stat; - strncpy(path_, path, PATH_MAX); - path_[PATH_MAX - 1] = 0; - char* pointer = path_; - while ((pointer = strchr(pointer, '/')) != NULL) { - if (path_ != pointer) { // skip leading slash - *pointer = 0; - if (!stat_file(path_, &file_stat) && mkdir(path_, mode) < 0) { - fprintf(stderr, "Cannot create folder %s: %s\n", path_, - strerror(errno)); - return false; - } - *pointer = '/'; - } - pointer++; +#endif // not COMPILER_MSVC + string spath(path); + if (spath.empty()) { + return true; } - return true; -#endif // COMPILER_MSVC + if (spath.back() != '/' && spath.back() != '\\') { + spath = blaze_util::Dirname(spath); + } + return blaze_util::MakeDirectories(spath, mode); } } // namespace devtools_ijar diff --git a/third_party/ijar/platform_utils.h b/third_party/ijar/platform_utils.h index 2a2f37f810..5cdab2d132 100644 --- a/third_party/ijar/platform_utils.h +++ b/third_party/ijar/platform_utils.h @@ -52,7 +52,8 @@ bool stat_file(const char* path, Stat* result); // The file is created or overwritten and is set to have `perm` permissions. // Returns true upon success: file is created and all data is written. // Returns false upon failure and reports the error to stderr. -bool write_file(const char* path, mode_t perm, const void* data, size_t size); +bool write_file(const char* path, unsigned int perm, const void* data, + size_t size); // Reads at most `size` bytes into `buffer` from the file under `path`. // Returns true upon success: file is opened and all data is read. @@ -69,7 +70,7 @@ std::string get_cwd(); // openable by the current user. // Returns true if all directories were created and permissions set. // Returns false upon failure and reports the error to stderr. -bool make_dirs(const char* path, mode_t perm); +bool make_dirs(const char* path, unsigned int perm); } // namespace devtools_ijar -- cgit v1.2.3