[llvm] 79c1991 - [llvm-objcopy][NFC] refactor restoreStatOnFile out of llvm-objcopy.
Alexey Lapshin via llvm-commits
llvm-commits at lists.llvm.org
Fri Apr 22 10:08:08 PDT 2022
Author: Alexey Lapshin
Date: 2022-04-22T20:06:01+03:00
New Revision: 79c1991010bda4eb2950e164ba0df4bde4fafa76
URL: https://github.com/llvm/llvm-project/commit/79c1991010bda4eb2950e164ba0df4bde4fafa76
DIFF: https://github.com/llvm/llvm-project/commit/79c1991010bda4eb2950e164ba0df4bde4fafa76.diff
LOG: [llvm-objcopy][NFC] refactor restoreStatOnFile out of llvm-objcopy.
Functionality of restoreStatOnFile may be reused. Move it into
FileUtilities.cpp. Create helper class FilePermissionsApplier
to store and apply permissions.
Differential Revision: https://reviews.llvm.org/D123821
Added:
Modified:
llvm/include/llvm/Support/FileUtilities.h
llvm/lib/Support/FileUtilities.cpp
llvm/tools/llvm-objcopy/llvm-objcopy.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/Support/FileUtilities.h b/llvm/include/llvm/Support/FileUtilities.h
index f8a37fe1177d9..0033638c6804a 100644
--- a/llvm/include/llvm/Support/FileUtilities.h
+++ b/llvm/include/llvm/Support/FileUtilities.h
@@ -110,6 +110,27 @@ namespace llvm {
llvm::Error
writeFileAtomically(StringRef TempPathModel, StringRef FinalPath,
std::function<llvm::Error(llvm::raw_ostream &)> Writer);
+
+ /// FilePermssionsApplier helps to copy permissions from an input file to
+ /// an output one. It memorizes the status of the input file and can apply
+ /// permissions and dates to the output file.
+ class FilePermissionsApplier {
+ public:
+ static Expected<FilePermissionsApplier> create(StringRef InputFilename);
+
+ /// Apply stored permissions to the \p OutputFilename.
+ /// Copy LastAccess and ModificationTime if \p CopyDates is true.
+ /// Overwrite stored permissions if \p OverwritePermissions is specified.
+ Error apply(StringRef OutputFilename, bool CopyDates = false,
+ Optional<sys::fs::perms> OverwritePermissions = None);
+
+ private:
+ FilePermissionsApplier(StringRef InputFilename, sys::fs::file_status Status)
+ : InputFilename(InputFilename), InputStatus(Status) {}
+
+ StringRef InputFilename;
+ sys::fs::file_status InputStatus;
+ };
} // End llvm namespace
#endif
diff --git a/llvm/lib/Support/FileUtilities.cpp b/llvm/lib/Support/FileUtilities.cpp
index 489b8d119e6f3..eda3eb044901d 100644
--- a/llvm/lib/Support/FileUtilities.cpp
+++ b/llvm/lib/Support/FileUtilities.cpp
@@ -17,6 +17,7 @@
#include "llvm/Support/Error.h"
#include "llvm/Support/ErrorOr.h"
#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Process.h"
#include "llvm/Support/raw_ostream.h"
#include <cstdint>
#include <cstdlib>
@@ -323,4 +324,69 @@ llvm::Error llvm::writeFileAtomically(
return Error::success();
}
+Expected<FilePermissionsApplier>
+FilePermissionsApplier::create(StringRef InputFilename) {
+ sys::fs::file_status Status;
+
+ if (InputFilename != "-") {
+ if (auto EC = sys::fs::status(InputFilename, Status))
+ return createFileError(InputFilename, EC);
+ } else {
+ Status.permissions(static_cast<sys::fs::perms>(0777));
+ }
+
+ return FilePermissionsApplier(InputFilename, Status);
+}
+
+Error FilePermissionsApplier::apply(
+ StringRef OutputFilename, bool CopyDates,
+ Optional<sys::fs::perms> OverwritePermissions) {
+ sys::fs::file_status Status = InputStatus;
+
+ if (OverwritePermissions)
+ Status.permissions(*OverwritePermissions);
+
+ int FD = 0;
+
+ // Writing to stdout should not be treated as an error here, just
+ // do not set access/modification times or permissions.
+ if (OutputFilename == "-")
+ return Error::success();
+
+ if (std::error_code EC = sys::fs::openFileForWrite(OutputFilename, FD,
+ sys::fs::CD_OpenExisting))
+ return createFileError(OutputFilename, EC);
+
+ if (CopyDates)
+ if (std::error_code EC = sys::fs::setLastAccessAndModificationTime(
+ FD, Status.getLastAccessedTime(), Status.getLastModificationTime()))
+ return createFileError(OutputFilename, EC);
+
+ sys::fs::file_status OStat;
+ if (std::error_code EC = sys::fs::status(FD, OStat))
+ return createFileError(OutputFilename, EC);
+ if (OStat.type() == sys::fs::file_type::regular_file) {
+#ifndef _WIN32
+ // Keep ownership if llvm-objcopy is called under root.
+ if (OutputFilename == InputFilename && OStat.getUser() == 0)
+ sys::fs::changeFileOwnership(FD, Status.getUser(), Status.getGroup());
+#endif
+
+ sys::fs::perms Perm = Status.permissions();
+ if (OutputFilename != InputFilename)
+ Perm = static_cast<sys::fs::perms>(Perm & ~sys::fs::getUmask() & ~06000);
+#ifdef _WIN32
+ if (std::error_code EC = sys::fs::setPermissions(OutputFilename, Perm))
+#else
+ if (std::error_code EC = sys::fs::setPermissions(FD, Perm))
+#endif
+ return createFileError(OutputFilename, EC);
+ }
+
+ if (std::error_code EC = sys::Process::SafelyCloseFileDescriptor(FD))
+ return createFileError(OutputFilename, EC);
+
+ return Error::success();
+}
+
char llvm::AtomicFileWriteError::ID;
diff --git a/llvm/tools/llvm-objcopy/llvm-objcopy.cpp b/llvm/tools/llvm-objcopy/llvm-objcopy.cpp
index 00712664eab27..2aaeea670952a 100644
--- a/llvm/tools/llvm-objcopy/llvm-objcopy.cpp
+++ b/llvm/tools/llvm-objcopy/llvm-objcopy.cpp
@@ -41,6 +41,7 @@
#include "llvm/Support/Error.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/ErrorOr.h"
+#include "llvm/Support/FileUtilities.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/InitLLVM.h"
#include "llvm/Support/Memory.h"
@@ -131,66 +132,16 @@ static Error executeObjcopyOnRawBinary(ConfigManager &ConfigMgr,
llvm_unreachable("unsupported output format");
}
-static Error restoreStatOnFile(StringRef Filename,
- const sys::fs::file_status &Stat,
- const ConfigManager &ConfigMgr) {
- int FD;
- const CommonConfig &Config = ConfigMgr.getCommonConfig();
-
- // Writing to stdout should not be treated as an error here, just
- // do not set access/modification times or permissions.
- if (Filename == "-")
- return Error::success();
-
- if (auto EC =
- sys::fs::openFileForWrite(Filename, FD, sys::fs::CD_OpenExisting))
- return createFileError(Filename, EC);
-
- if (Config.PreserveDates)
- if (auto EC = sys::fs::setLastAccessAndModificationTime(
- FD, Stat.getLastAccessedTime(), Stat.getLastModificationTime()))
- return createFileError(Filename, EC);
-
- sys::fs::file_status OStat;
- if (std::error_code EC = sys::fs::status(FD, OStat))
- return createFileError(Filename, EC);
- if (OStat.type() == sys::fs::file_type::regular_file) {
-#ifndef _WIN32
- // Keep ownership if llvm-objcopy is called under root.
- if (Config.InputFilename == Config.OutputFilename && OStat.getUser() == 0)
- sys::fs::changeFileOwnership(FD, Stat.getUser(), Stat.getGroup());
-#endif
-
- sys::fs::perms Perm = Stat.permissions();
- if (Config.InputFilename != Config.OutputFilename)
- Perm = static_cast<sys::fs::perms>(Perm & ~sys::fs::getUmask() & ~06000);
-#ifdef _WIN32
- if (auto EC = sys::fs::setPermissions(Filename, Perm))
-#else
- if (auto EC = sys::fs::setPermissions(FD, Perm))
-#endif
- return createFileError(Filename, EC);
- }
-
- if (auto EC = sys::Process::SafelyCloseFileDescriptor(FD))
- return createFileError(Filename, EC);
-
- return Error::success();
-}
-
/// The function executeObjcopy does the higher level dispatch based on the type
/// of input (raw binary, archive or single object file) and takes care of the
/// format-agnostic modifications, i.e. preserving dates.
static Error executeObjcopy(ConfigManager &ConfigMgr) {
CommonConfig &Config = ConfigMgr.Common;
- sys::fs::file_status Stat;
- if (Config.InputFilename != "-") {
- if (auto EC = sys::fs::status(Config.InputFilename, Stat))
- return createFileError(Config.InputFilename, EC);
- } else {
- Stat.permissions(static_cast<sys::fs::perms>(0777));
- }
+ Expected<FilePermissionsApplier> PermsCarrier =
+ FilePermissionsApplier::create(Config.InputFilename);
+ if (!PermsCarrier)
+ return PermsCarrier.takeError();
std::function<Error(raw_ostream & OutFile)> ObjcopyFunc;
@@ -259,14 +210,14 @@ static Error executeObjcopy(ConfigManager &ConfigMgr) {
}
}
- if (Error E = restoreStatOnFile(Config.OutputFilename, Stat, ConfigMgr))
+ if (Error E =
+ PermsCarrier->apply(Config.OutputFilename, Config.PreserveDates))
return E;
- if (!Config.SplitDWO.empty()) {
- Stat.permissions(static_cast<sys::fs::perms>(0666));
- if (Error E = restoreStatOnFile(Config.SplitDWO, Stat, ConfigMgr))
+ if (!Config.SplitDWO.empty())
+ if (Error E = PermsCarrier->apply(Config.SplitDWO, Config.PreserveDates,
+ static_cast<sys::fs::perms>(0666)))
return E;
- }
return Error::success();
}
More information about the llvm-commits
mailing list