From 1d25f6b54773c739340361902b7d1412f53ef7fc Mon Sep 17 00:00:00 2001 From: Peter Collingbourne Date: Mon, 5 Mar 2012 01:45:04 +0000 Subject: Treat paths of the form "existing-file/something" as non-existent Some people like to construct phony target names by appending a "/something" suffix to an existing target "foo". But if "foo" is an existing file, stat will report ENOTDIR for this path, causing ninja to spew errors. Fix this by treating ENOTDIR in the same way as we do ENOENT -- as a non-existent path. --- src/disk_interface.cc | 2 +- src/disk_interface_test.cc | 26 ++++++++++++++------------ 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/disk_interface.cc b/src/disk_interface.cc index 96a1e59..b1a1746 100644 --- a/src/disk_interface.cc +++ b/src/disk_interface.cc @@ -94,7 +94,7 @@ TimeStamp RealDiskInterface::Stat(const string& path) { #else struct stat st; if (stat(path.c_str(), &st) < 0) { - if (errno == ENOENT) + if (errno == ENOENT || errno == ENOTDIR) return 0; Error("stat(%s): %s", path.c_str(), strerror(errno)); return -1; diff --git a/src/disk_interface_test.cc b/src/disk_interface_test.cc index 052a94b..67e2a04 100644 --- a/src/disk_interface_test.cc +++ b/src/disk_interface_test.cc @@ -36,6 +36,13 @@ class DiskInterfaceTest : public testing::Test { temp_dir_.Cleanup(); } + bool Touch(const char* path) { + FILE *f = fopen(path, "w"); + if (!f) + return false; + return fclose(f) == 0; + } + ScopedTempDir temp_dir_; RealDiskInterface disk_; }; @@ -46,6 +53,11 @@ TEST_F(DiskInterfaceTest, StatMissingFile) { // On Windows, the errno for a file in a nonexistent directory // is different. EXPECT_EQ(0, disk_.Stat("nosuchdir/nosuchfile")); + + // On POSIX systems, the errno is different if a component of the + // path prefix is not a directory. + ASSERT_TRUE(Touch("notadir")); + EXPECT_EQ(0, disk_.Stat("notadir/nosuchfile")); } TEST_F(DiskInterfaceTest, StatBadPath) { @@ -56,11 +68,7 @@ TEST_F(DiskInterfaceTest, StatBadPath) { } TEST_F(DiskInterfaceTest, StatExistingFile) { -#ifdef _WIN32 - ASSERT_EQ(0, system("cmd.exe /c echo hi > file")); -#else - ASSERT_EQ(0, system("touch file")); -#endif + ASSERT_TRUE(Touch("file")); EXPECT_GT(disk_.Stat("file"), 1); } @@ -86,13 +94,7 @@ TEST_F(DiskInterfaceTest, MakeDirs) { TEST_F(DiskInterfaceTest, RemoveFile) { const char* kFileName = "file-to-remove"; -#ifdef _WIN32 - string cmd = "cmd /c echo hi > "; -#else - string cmd = "touch "; -#endif - cmd += kFileName; - ASSERT_EQ(0, system(cmd.c_str())); + ASSERT_TRUE(Touch(kFileName)); EXPECT_EQ(0, disk_.RemoveFile(kFileName)); EXPECT_EQ(1, disk_.RemoveFile(kFileName)); EXPECT_EQ(1, disk_.RemoveFile("does not exist")); -- cgit v0.12