summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPeter Collingbourne <peter@pcc.me.uk>2012-03-05 01:45:04 (GMT)
committerPeter Collingbourne <peter@pcc.me.uk>2012-03-07 23:11:17 (GMT)
commit1d25f6b54773c739340361902b7d1412f53ef7fc (patch)
treeec6be3e6812bce1ff6241a3cff4bdd5e57ee7c25 /src
parent2338d9340bb2c13746805b4b878c889008850962 (diff)
downloadNinja-1d25f6b54773c739340361902b7d1412f53ef7fc.zip
Ninja-1d25f6b54773c739340361902b7d1412f53ef7fc.tar.gz
Ninja-1d25f6b54773c739340361902b7d1412f53ef7fc.tar.bz2
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.
Diffstat (limited to 'src')
-rw-r--r--src/disk_interface.cc2
-rw-r--r--src/disk_interface_test.cc26
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"));