diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp index 0c62d77e08d7..68eb5616a5c6 100644 --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -912,9 +912,11 @@ template void LinkerDriver::link(opt::InputArgList &Args) { // Fail early if the output file or map file is not writable. If a user has a // long link, e.g. due to a large LTO link, they do not wish to run it and // find that it failed because there was a mistake in their command-line. - if (!isFileWritable(Config->OutputFile, "output file")) - return; - if (!isFileWritable(Config->MapFile, "map file")) + if (auto E = tryCreateFile(Config->OutputFile)) + error("cannot open output file " + Config->OutputFile + ": " + E.message()); + if (auto E = tryCreateFile(Config->MapFile)) + error("cannot open map file " + Config->MapFile + ": " + E.message()); + if (ErrorCount) return; // Use default entry point name if no name was given via the command diff --git a/lld/ELF/Filesystem.cpp b/lld/ELF/Filesystem.cpp index 75f7bda75a23..0b9cea92bd4d 100644 --- a/lld/ELF/Filesystem.cpp +++ b/lld/ELF/Filesystem.cpp @@ -13,7 +13,6 @@ #include "Filesystem.h" #include "Config.h" -#include "Error.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/FileOutputBuffer.h" #include @@ -58,22 +57,18 @@ void elf::unlinkAsync(StringRef Path) { std::thread([=] { ::remove(TempPath.str().str().c_str()); }).detach(); } -// Returns true if a given file seems to be writable. +// Simulate file creation to see if Path is writable. // // Determining whether a file is writable or not is amazingly hard, // and after all the only reliable way of doing that is to actually // create a file. But we don't want to do that in this function // because LLD shouldn't update any file if it will end in a failure. -// We also don't want to reimplement heuristics. So we'll let -// FileOutputBuffer do the work. +// We also don't want to reimplement heuristics to determine if a +// file is writable. So we'll let FileOutputBuffer do the work. // // FileOutputBuffer doesn't touch a desitnation file until commit() // is called. We use that class without calling commit() to predict // if the given file is writable. -bool elf::isFileWritable(StringRef Path, StringRef Desc) { - if (auto EC = FileOutputBuffer::create(Path, 1).getError()) { - error("cannot open " + Desc + " " + Path + ": " + EC.message()); - return false; - } - return true; +std::error_code elf::tryCreateFile(StringRef Path) { + return FileOutputBuffer::create(Path, 1).getError(); } diff --git a/lld/ELF/Filesystem.h b/lld/ELF/Filesystem.h index a33dc3651a4a..d56d067f7378 100644 --- a/lld/ELF/Filesystem.h +++ b/lld/ELF/Filesystem.h @@ -15,7 +15,7 @@ namespace lld { namespace elf { void unlinkAsync(StringRef Path); -bool isFileWritable(StringRef Path, StringRef FileDescription); +std::error_code tryCreateFile(StringRef Path); } }