blob: 7ab3b174d2645c2723a636d2cdcce77b4fc5a44b [file] [log] [blame]
//===-- FileSystem.cpp ----------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
#include "llbuild/Basic/FileSystem.h"
#include "llbuild/Basic/PlatformUtility.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/MemoryBuffer.h"
#include <cassert>
#include <cstring>
using namespace llbuild;
using namespace llbuild::basic;
FileSystem::~FileSystem() {}
bool FileSystem::createDirectories(const std::string& path) {
// Attempt to create the final directory first, to optimize for the common
// case where we don't need to recurse.
if (createDirectory(path))
return true;
// If that failed, attempt to create the parent.
StringRef parent = llvm::sys::path::parent_path(path);
if (parent.empty())
return false;
return createDirectories(parent) && createDirectory(path);
}
namespace {
class LocalFileSystem : public FileSystem {
public:
LocalFileSystem() {}
virtual bool
createDirectory(const std::string& path) override {
if (!sys::mkdir(path.c_str())) {
if (errno != EEXIST) {
return false;
}
}
return true;
}
virtual std::unique_ptr<llvm::MemoryBuffer>
getFileContents(const std::string& path) override {
auto result = llvm::MemoryBuffer::getFile(path);
if (result.getError()) {
return nullptr;
}
return std::unique_ptr<llvm::MemoryBuffer>(result->release());
}
virtual bool remove(const std::string& path) override {
// Assume `path` is a regular file.
if (sys::unlink(path.c_str()) == 0) {
return true;
}
// Error can't be that `path` is actually a directory.
if (errno != EPERM) {
return false;
}
// Check if `path` is a directory.
struct stat statbuf;
if (sys::stat(path.c_str(), &statbuf) != 0) {
return false;
}
if (S_ISDIR(statbuf.st_mode)) {
return sys::rmdir(path.c_str()) == 0;
}
return false;
}
virtual FileInfo getFileInfo(const std::string& path) override {
return FileInfo::getInfoForPath(path);
}
virtual FileInfo getLinkInfo(const std::string& path) override {
return FileInfo::getInfoForPath(path, /*isLink:*/ true);
}
};
}
std::unique_ptr<FileSystem> basic::createLocalFileSystem() {
return llvm::make_unique<LocalFileSystem>();
}