|
Ninja
|
00001 // Copyright 2011 Google Inc. All Rights Reserved. 00002 // 00003 // Licensed under the Apache License, Version 2.0 (the "License"); 00004 // you may not use this file except in compliance with the License. 00005 // You may obtain a copy of the License at 00006 // 00007 // http://www.apache.org/licenses/LICENSE-2.0 00008 // 00009 // Unless required by applicable law or agreed to in writing, software 00010 // distributed under the License is distributed on an "AS IS" BASIS, 00011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00012 // See the License for the specific language governing permissions and 00013 // limitations under the License. 00014 00015 #include "disk_interface.h" 00016 00017 #include <errno.h> 00018 #include <stdio.h> 00019 #include <string.h> 00020 #include <sys/stat.h> 00021 00022 #include "util.h" 00023 00024 namespace { 00025 00026 std::string DirName(const std::string& path) { 00027 #ifdef WIN32 00028 const char kPathSeparator = '\\'; 00029 #else 00030 const char kPathSeparator = '/'; 00031 #endif 00032 00033 std::string::size_type slash_pos = path.rfind(kPathSeparator); 00034 if (slash_pos == std::string::npos) 00035 return std::string(); // Nothing to do. 00036 while (slash_pos > 0 && path[slash_pos - 1] == kPathSeparator) 00037 --slash_pos; 00038 return path.substr(0, slash_pos); 00039 } 00040 00041 } // namespace 00042 00043 // DiskInterface --------------------------------------------------------------- 00044 00045 bool DiskInterface::MakeDirs(const std::string& path) { 00046 std::string dir = DirName(path); 00047 if (dir.empty()) 00048 return true; // Reached root; assume it's there. 00049 int mtime = Stat(dir); 00050 if (mtime < 0) 00051 return false; // Error. 00052 if (mtime > 0) 00053 return true; // Exists already; we're done. 00054 00055 // Directory doesn't exist. Try creating its parent first. 00056 bool success = MakeDirs(dir); 00057 if (!success) 00058 return false; 00059 return MakeDir(dir); 00060 } 00061 00062 // RealDiskInterface ----------------------------------------------------------- 00063 00064 int RealDiskInterface::Stat(const std::string& path) { 00065 struct stat st; 00066 if (stat(path.c_str(), &st) < 0) { 00067 if (errno == ENOENT) { 00068 return 0; 00069 } else { 00070 Error("stat(%s): %s", path.c_str(), strerror(errno)); 00071 return -1; 00072 } 00073 } 00074 00075 return st.st_mtime; 00076 return true; 00077 } 00078 00079 bool RealDiskInterface::MakeDir(const std::string& path) { 00080 if (::MakeDir(path) < 0) { 00081 Error("mkdir(%s): %s", path.c_str(), strerror(errno)); 00082 return false; 00083 } 00084 return true; 00085 } 00086 00087 std::string RealDiskInterface::ReadFile(const std::string& path, 00088 std::string* err) { 00089 std::string contents; 00090 int ret = ::ReadFile(path, &contents, err); 00091 if (ret == -ENOENT) { 00092 // Swallow ENOENT. 00093 err->clear(); 00094 } 00095 return contents; 00096 } 00097 00098 int RealDiskInterface::RemoveFile(const std::string& path) { 00099 if (remove(path.c_str()) < 0) { 00100 switch (errno) { 00101 case ENOENT: 00102 return 1; 00103 default: 00104 Error("remove(%s): %s", path.c_str(), strerror(errno)); 00105 return -1; 00106 } 00107 } else { 00108 return 0; 00109 } 00110 }
1.7.5.1