From: Rafael Espindola Date: Thu, 20 Jun 2013 20:56:14 +0000 (+0000) Subject: Add a setLastModificationAndAccessTime to PathV2. X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=11ca2e508c2152732c364d02e5b381e61c851084;p=oota-llvm.git 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 --- diff --git a/include/llvm/Support/FileSystem.h b/include/llvm/Support/FileSystem.h index c9ecc30efbf..08727d7f79c 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 4b922da7186..e9cb6e75627 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 &result_path, diff --git a/lib/Support/Windows/PathV2.inc b/lib/Support/Windows/PathV2.inc index 006e31a5bd2..5e0375fcf9a 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(_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 b1b175f4a7b..b7328e1300f 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 #include +#include #include + +#if !defined(_MSC_VER) && !defined(__MINGW32__) +#include +#else +#include +#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(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(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;