windows: use _WIN32 define everywhere
[platform/upstream/ninja.git] / src / disk_interface.cc
1 // Copyright 2011 Google Inc. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "disk_interface.h"
16
17 #include <errno.h>
18 #include <stdio.h>
19 #include <string.h>
20 #include <sys/stat.h>
21
22 #ifdef _WIN32
23 #include <windows.h>
24 #endif
25
26 #include "util.h"
27
28 namespace {
29
30 string DirName(const string& path) {
31 #ifdef _WIN32
32   const char kPathSeparator = '\\';
33 #else
34   const char kPathSeparator = '/';
35 #endif
36
37   string::size_type slash_pos = path.rfind(kPathSeparator);
38   if (slash_pos == string::npos)
39     return string();  // Nothing to do.
40   while (slash_pos > 0 && path[slash_pos - 1] == kPathSeparator)
41     --slash_pos;
42   return path.substr(0, slash_pos);
43 }
44
45 }  // namespace
46
47 // DiskInterface ---------------------------------------------------------------
48
49 bool DiskInterface::MakeDirs(const string& path) {
50   string dir = DirName(path);
51   if (dir.empty())
52     return true;  // Reached root; assume it's there.
53   TimeStamp mtime = Stat(dir);
54   if (mtime < 0)
55     return false;  // Error.
56   if (mtime > 0)
57     return true;  // Exists already; we're done.
58
59   // Directory doesn't exist.  Try creating its parent first.
60   bool success = MakeDirs(dir);
61   if (!success)
62     return false;
63   return MakeDir(dir);
64 }
65
66 // RealDiskInterface -----------------------------------------------------------
67
68 TimeStamp RealDiskInterface::Stat(const string& path) {
69 #ifdef _WIN32
70   _WIN32_FILE_ATTRIBUTE_DATA attrs;
71   if (!GetFileAttributesEx(path.c_str(), GetFileExInfoStandard, &attrs)) {
72     DWORD err = GetLastError();
73     if (err == ERROR_FILE_NOT_FOUND || err == ERROR_PATH_NOT_FOUND)
74       return 0;
75     Error("GetFileAttributesEx(%s): %s", path.c_str(),
76           GetLastErrorString().c_str());
77     return -1;
78   }
79   const FILETIME& filetime = attrs.ftLastWriteTime;
80   // FILETIME is in 100-nanosecond increments since the Windows epoch.
81   // We don't much care about epoch correctness but we do want the
82   // resulting value to fit in an integer.
83   uint64_t mtime = ((uint64_t)filetime.dwHighDateTime << 32) |
84     ((uint64_t)filetime.dwLowDateTime);
85   mtime /= 1000000000LL / 100; // 100ns -> s.
86   mtime -= 12622770400LL;  // 1600 epoch -> 2000 epoch (subtract 400 years).
87   return (TimeStamp)mtime;
88 #else
89   struct stat st;
90   if (stat(path.c_str(), &st) < 0) {
91     if (errno == ENOENT)
92       return 0;
93     Error("stat(%s): %s", path.c_str(), strerror(errno));
94     return -1;
95   }
96   return st.st_mtime;
97 #endif
98 }
99
100 bool RealDiskInterface::MakeDir(const string& path) {
101   if (::MakeDir(path) < 0) {
102     Error("mkdir(%s): %s", path.c_str(), strerror(errno));
103     return false;
104   }
105   return true;
106 }
107
108 string RealDiskInterface::ReadFile(const string& path, string* err) {
109   string contents;
110   int ret = ::ReadFile(path, &contents, err);
111   if (ret == -ENOENT) {
112     // Swallow ENOENT.
113     err->clear();
114   }
115   return contents;
116 }
117
118 int RealDiskInterface::RemoveFile(const string& path) {
119   if (remove(path.c_str()) < 0) {
120     switch (errno) {
121       case ENOENT:
122         return 1;
123       default:
124         Error("remove(%s): %s", path.c_str(), strerror(errno));
125         return -1;
126     }
127   } else {
128     return 0;
129   }
130 }