summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2013-06-20 20:56:14 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2013-06-20 20:56:14 +0000
commit11ca2e508c2152732c364d02e5b381e61c851084 (patch)
treeb8cd1edf3f8767cca4cdd3460364f6e64f792666
parentdeda39dbdf2a8b07940183e5f3ed9ea89e2ae053 (diff)
downloadllvm-11ca2e508c2152732c364d02e5b381e61c851084.tar.gz
llvm-11ca2e508c2152732c364d02e5b381e61c851084.tar.bz2
llvm-11ca2e508c2152732c364d02e5b381e61c851084.tar.xz
Add a setLastModificationAndAccessTime to PathV2.
With this we can remove the last use of PathV1 from llvm-ar.cpp. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@184464 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/Support/FileSystem.h2
-rw-r--r--lib/Support/Unix/PathV2.inc10
-rw-r--r--lib/Support/Windows/PathV2.inc11
-rw-r--r--tools/llvm-ar/llvm-ar.cpp54
4 files changed, 58 insertions, 19 deletions
diff --git a/include/llvm/Support/FileSystem.h b/include/llvm/Support/FileSystem.h
index c9ecc30efb..08727d7f79 100644
--- a/include/llvm/Support/FileSystem.h
+++ b/include/llvm/Support/FileSystem.h
@@ -482,6 +482,8 @@ error_code status(const Twine &path, file_status &result);
/// platform specific error_code.
error_code permissions(const Twine &path, perms prms);
+error_code setLastModificationAndAccessTime(int FD, TimeValue Time);
+
/// @brief Is status available?
///
/// @param s Input file status.
diff --git a/lib/Support/Unix/PathV2.inc b/lib/Support/Unix/PathV2.inc
index 4b922da718..e9cb6e7562 100644
--- a/lib/Support/Unix/PathV2.inc
+++ b/lib/Support/Unix/PathV2.inc
@@ -441,6 +441,16 @@ error_code permissions(const Twine &path, perms prms) {
return error_code::success();
}
+error_code setLastModificationAndAccessTime(int FD, TimeValue Time) {
+ timeval Times[2];
+ Times[0].tv_sec = Time.toPosixTime();
+ Times[0].tv_usec = 0;
+ Times[1] = Times[0];
+ if (::futimes(FD, Times))
+ return error_code(errno, system_category());
+ return error_code::success();
+}
+
// Since this is most often used for temporary files, mode defaults to 0600.
error_code unique_file(const Twine &model, int &result_fd,
SmallVectorImpl<char> &result_path,
diff --git a/lib/Support/Windows/PathV2.inc b/lib/Support/Windows/PathV2.inc
index 006e31a5bd..5e0375fcf9 100644
--- a/lib/Support/Windows/PathV2.inc
+++ b/lib/Support/Windows/PathV2.inc
@@ -585,6 +585,17 @@ error_code permissions(const Twine &path, perms prms) {
return error_code::success();
}
+error_code setLastModificationAndAccessTime(int FD, TimeValue Time) {
+ ULARGE_INTEGER UI;
+ UI.QuadPart = Time.toWin32Time();
+ FILETIME FT;
+ FT.dwLowDateTime = UI.LowPart;
+ FT.dwHighDateTime = UI.HighPart;
+ HANDLE FileHandle = reinterpret_cast<HANDLE>(_get_osfhandle(FD));
+ if (!SetFileTime(FileHandle, NULL, &FT, &FT))
+ return windows_error(::GetLastError());
+ return error_code::success();
+}
// FIXME: mode should be used here and default to user r/w only,
// it currently comes in as a UNIX mode.
diff --git a/tools/llvm-ar/llvm-ar.cpp b/tools/llvm-ar/llvm-ar.cpp
index b1b175f4a7..b7328e1300 100644
--- a/tools/llvm-ar/llvm-ar.cpp
+++ b/tools/llvm-ar/llvm-ar.cpp
@@ -19,13 +19,20 @@
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/ManagedStatic.h"
-#include "llvm/Support/PathV1.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cstdlib>
+#include <fcntl.h>
#include <memory>
+
+#if !defined(_MSC_VER) && !defined(__MINGW32__)
+#include <unistd.h>
+#else
+#include <io.h>
+#endif
+
using namespace llvm;
// Option for compatibility with AIX, not used but must allow it to be present.
@@ -399,32 +406,41 @@ doExtract(std::string* ErrMsg) {
(std::find(Paths.begin(), Paths.end(), I->getPath()) != Paths.end())) {
// Open up a file stream for writing
- std::string Err;
- raw_fd_ostream file(I->getPath().str().c_str(), Err,
- raw_fd_ostream::F_Binary);
- if (!Err.empty())
- fail(Err);
+ int OpenFlags = O_TRUNC | O_WRONLY | O_CREAT;
+#ifdef O_BINARY
+ OpenFlags |= O_BINARY;
+#endif
- // Get the data and its length
- const char* data = reinterpret_cast<const char*>(I->getData());
- unsigned len = I->getSize();
+ int FD = open(I->getPath().str().c_str(), OpenFlags, 0664);
+ if (FD < 0)
+ return true;
- // Write the data.
- file.write(data,len);
- file.close();
+ {
+ raw_fd_ostream file(FD, false);
- sys::PathWithStatus PWS(I->getPath());
- sys::FileStatus Status = *PWS.getFileStatus();
+ // Get the data and its length
+ const char* data = reinterpret_cast<const char*>(I->getData());
+ unsigned len = I->getSize();
+
+ // Write the data.
+ file.write(data, len);
+ }
// Retain the original mode.
- Status.mode = I->getMode();
+ sys::fs::perms Mode = sys::fs::perms(I->getMode());
+ error_code EC = sys::fs::permissions(I->getPath(), Mode);
+ if (EC)
+ fail(EC.message());
// If we're supposed to retain the original modification times, etc. do so
// now.
- if (OriginalDates)
- Status.modTime = I->getModTime();
-
- PWS.setStatusInfoOnDisk(Status);
+ if (OriginalDates) {
+ EC = sys::fs::setLastModificationAndAccessTime(FD, I->getModTime());
+ if (EC)
+ fail(EC.message());
+ }
+ if (close(FD))
+ return true;
}
}
return false;