aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Laszlo Csomor <laszlocsomor@google.com>2016-12-21 15:01:36 +0000
committerGravatar Klaus Aehlig <aehlig@google.com>2016-12-21 17:23:51 +0000
commit7de9b6f1d9748d7347fa76f5ac8d0258c79b6d70 (patch)
treee0fc695c7e65e6d0fcd9f2929de6811afdf7e734
parentfd31061d4cd99277ba1cfacd17ac316f8dfea4f5 (diff)
Bazel client, Windows: implement ReadFile
Implement blaze_util::ReadFile on top of the ::ReadFile Windows API function. Also implement blaze_util::AsWindowsPath so we can convert MSYS paths to Windows widechar paths. Add tests. See https://github.com/bazelbuild/bazel/issues/2107 -- PiperOrigin-RevId: 142659955 MOS_MIGRATED_REVID=142659955
-rw-r--r--src/main/cpp/util/file_posix.cc2
-rw-r--r--src/main/cpp/util/file_windows.cc41
-rw-r--r--src/test/cpp/util/file_test.cc24
3 files changed, 59 insertions, 8 deletions
diff --git a/src/main/cpp/util/file_posix.cc b/src/main/cpp/util/file_posix.cc
index c5568a4c3e..127f811d32 100644
--- a/src/main/cpp/util/file_posix.cc
+++ b/src/main/cpp/util/file_posix.cc
@@ -179,7 +179,6 @@ pair<string, string> SplitPath(const string &path) {
return std::make_pair(string(path, 0, pos), string(path, pos + 1));
}
-#endif // not __CYGWIN__
bool ReadFile(const string &filename, string *content, int max_size) {
int fd = open(filename.c_str(), O_RDONLY);
@@ -190,6 +189,7 @@ bool ReadFile(const string &filename, string *content, int max_size) {
close(fd);
return result;
}
+#endif // not __CYGWIN__
bool WriteFile(const void *data, size_t size, const string &filename) {
UnlinkPath(filename); // We don't care about the success of this.
diff --git a/src/main/cpp/util/file_windows.cc b/src/main/cpp/util/file_windows.cc
index 78cb331185..6ded8c83cf 100644
--- a/src/main/cpp/util/file_windows.cc
+++ b/src/main/cpp/util/file_windows.cc
@@ -217,14 +217,43 @@ bool AsWindowsPath(const string& path, wstring* result) {
return true;
}
-#ifdef COMPILER_MSVC
bool ReadFile(const string& filename, string* content, int max_size) {
- // TODO(bazel-team): implement this.
- pdie(255, "blaze_util::ReadFile is not implemented on Windows");
- return false;
+ wstring wfilename;
+ if (!AsWindowsPath(filename, &wfilename)) {
+ // Failed to convert the path because it was an absolute MSYS path but we
+ // could not retrieve the BAZEL_SH envvar.
+ return false;
+ }
+
+ if (wfilename.size() > MAX_PATH) {
+ // CreateFileW requires that paths longer than MAX_PATH be prefixed with
+ // "\\?\", so add that here.
+ // TODO(laszlocsomor): add a test for this code path.
+ wfilename = wstring(L"\\\\?\\") + wfilename;
+ }
+
+ HANDLE handle = CreateFileW(
+ /* lpFileName */ wfilename.c_str(),
+ /* dwDesiredAccess */ GENERIC_READ,
+ /* dwShareMode */ FILE_SHARE_READ,
+ /* lpSecurityAttributes */ NULL,
+ /* dwCreationDisposition */ OPEN_EXISTING,
+ /* dwFlagsAndAttributes */ FILE_ATTRIBUTE_NORMAL,
+ /* hTemplateFile */ NULL);
+ if (handle == INVALID_HANDLE_VALUE) {
+ return false;
+ }
+
+ bool result = ReadFrom(
+ [handle](void* buf, int len) {
+ DWORD actually_read = 0;
+ ::ReadFile(handle, buf, len, &actually_read, NULL);
+ return actually_read;
+ },
+ content, max_size);
+ CloseHandle(handle);
+ return result;
}
-#else // not COMPILER_MSVC
-#endif // COMPILER_MSVC
#ifdef COMPILER_MSVC
bool WriteFile(const void* data, size_t size, const string& filename) {
diff --git a/src/test/cpp/util/file_test.cc b/src/test/cpp/util/file_test.cc
index f98ed9975a..7c15ceb816 100644
--- a/src/test/cpp/util/file_test.cc
+++ b/src/test/cpp/util/file_test.cc
@@ -11,10 +11,11 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
+#include <stdio.h>
#include <string.h>
#include <memory> // unique_ptr
-#include <thread> // NOLINT (to slience Google-internal linter)
+#include <thread> // NOLINT (to silence Google-internal linter)
#include "src/main/cpp/util/file.h"
#include "src/main/cpp/util/file_platform.h"
@@ -22,6 +23,8 @@
namespace blaze_util {
+using std::string;
+
TEST(FileTest, TestNormalizePath) {
ASSERT_EQ(string(""), NormalizePath(""));
ASSERT_EQ(string(""), NormalizePath("."));
@@ -66,4 +69,23 @@ TEST(FileTest, TestMultiThreadedPipe) {
ASSERT_EQ(0, strncmp(buffer, "hello world", 11));
}
+TEST(FileTest, TestReadFile) {
+ const char* tempdir = getenv("TEST_TMPDIR");
+ ASSERT_NE(nullptr, tempdir);
+ ASSERT_NE(0, tempdir[0]);
+
+ std::string filename(JoinPath(tempdir, "test.readfile"));
+ FILE* fh = fopen(filename.c_str(), "wt");
+ ASSERT_NE(nullptr, fh);
+ ASSERT_EQ(11, fwrite("hello world", 1, 11, fh));
+ fclose(fh);
+
+ std::string actual;
+ ASSERT_TRUE(ReadFile(filename, &actual));
+ ASSERT_EQ(std::string("hello world"), actual);
+
+ ASSERT_TRUE(ReadFile(filename, &actual, 5));
+ ASSERT_EQ(std::string("hello"), actual);
+}
+
} // namespace blaze_util