X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=tools%2Fllvm-ar%2FArchiveWriter.cpp;h=bdccf3e0d91d1ecfef0c75feb7b2a5ac00da98d9;hb=0a230e0d985625a3909cb78fd867a3abaf434565;hp=135ed5665f597c25175dfb3479cf741e9c417408;hpb=122c57c0b82d125f33d2f036a67e96339e95c402;p=oota-llvm.git diff --git a/tools/llvm-ar/ArchiveWriter.cpp b/tools/llvm-ar/ArchiveWriter.cpp index 135ed5665f5..bdccf3e0d91 100644 --- a/tools/llvm-ar/ArchiveWriter.cpp +++ b/tools/llvm-ar/ArchiveWriter.cpp @@ -18,7 +18,6 @@ #include "llvm/IR/Module.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/PathV1.h" #include "llvm/Support/Process.h" #include "llvm/Support/Signals.h" #include "llvm/Support/system_error.h" @@ -81,7 +80,7 @@ Archive* Archive::CreateEmpty(StringRef FilePath, LLVMContext& C) { // compressed. bool Archive::fillHeader(const ArchiveMember &mbr, ArchiveMemberHeader& hdr, - int sz, bool TruncateNames) const { + int sz) const { // Set the permissions mode, uid and gid hdr.init(); @@ -108,18 +107,6 @@ Archive::fillHeader(const ArchiveMember &mbr, ArchiveMemberHeader& hdr, memcpy(hdr.name,ARFILE_SVR4_SYMTAB_NAME,16); } else if (mbr.isBSD4SymbolTable()) { memcpy(hdr.name,ARFILE_BSD4_SYMTAB_NAME,16); - } else if (TruncateNames) { - const char* nm = mbrPath.c_str(); - unsigned len = mbrPath.length(); - size_t slashpos = mbrPath.rfind('/'); - if (slashpos != std::string::npos) { - nm += slashpos + 1; - len -= slashpos +1; - } - if (len > 15) - len = 15; - memcpy(hdr.name,nm,len); - hdr.name[len] = '/'; } else if (mbrPath.length() < 16 && mbrPath.find('/') == std::string::npos) { memcpy(hdr.name,mbrPath.c_str(),mbrPath.length()); hdr.name[mbrPath.length()] = '/'; @@ -160,17 +147,22 @@ bool Archive::addFileBefore(StringRef filePath, iterator where, mbr->data = 0; mbr->path = filePath; - sys::PathWithStatus PWS(filePath); - const sys::FileStatus *FSInfo = PWS.getFileStatus(false, ErrMsg); - if (!FSInfo) { + sys::fs::file_status Status; + error_code EC = sys::fs::status(filePath, Status); + if (EC) { + delete mbr; + return true; + } + mbr->User = Status.getUser(); + mbr->Group = Status.getGroup(); + mbr->Mode = Status.permissions(); + mbr->ModTime = Status.getLastModificationTime(); + // FIXME: On posix this is a second stat. + EC = sys::fs::file_size(filePath, mbr->Size); + if (EC) { delete mbr; return true; } - mbr->User = FSInfo->getUser(); - mbr->Group = FSInfo->getGroup(); - mbr->Mode = FSInfo->getMode(); - mbr->ModTime = FSInfo->getTimestamp(); - mbr->Size = FSInfo->getSize(); unsigned flags = 0; if (sys::path::filename(filePath).size() > 15) @@ -179,13 +171,6 @@ bool Archive::addFileBefore(StringRef filePath, iterator where, sys::fs::file_magic type; if (sys::fs::identify_magic(mbr->path, type)) type = sys::fs::file_magic::unknown; - switch (type) { - case sys::fs::file_magic::bitcode: - flags |= ArchiveMember::BitcodeFlag; - break; - default: - break; - } mbr->flags = flags; members.insert(where,mbr); return false; @@ -195,12 +180,11 @@ bool Archive::addFileBefore(StringRef filePath, iterator where, bool Archive::writeMember( const ArchiveMember& member, - std::ofstream& ARFile, - bool TruncateNames, + raw_fd_ostream& ARFile, std::string* ErrMsg ) { - unsigned filepos = ARFile.tellp(); + uint64_t filepos = ARFile.tell(); filepos -= 8; // Get the data and its size either from the @@ -224,7 +208,7 @@ Archive::writeMember( // Compute the fields of the header ArchiveMemberHeader Hdr; - bool writeLongName = fillHeader(member,Hdr,hdrSize,TruncateNames); + bool writeLongName = fillHeader(member,Hdr,hdrSize); // Write header to archive file ARFile.write((char*)&Hdr, sizeof(Hdr)); @@ -239,7 +223,7 @@ Archive::writeMember( ARFile.write(data,fSize); // Make sure the member is an even length - if ((ARFile.tellp() & 1) == 1) + if ((ARFile.tell() & 1) == 1) ARFile << ARFILE_PAD; // Close the mapped file if it was opened @@ -251,7 +235,7 @@ Archive::writeMember( // This writes to a temporary file first. Options are for creating a symbol // table, flattening the file names (no directories, 15 chars max) and // compressing each archive member. -bool Archive::writeToDisk(bool TruncateNames, std::string *ErrMsg) { +bool Archive::writeToDisk(std::string *ErrMsg) { // Make sure they haven't opened up the file, not loaded it, // but are now trying to write it which would wipe out the file. if (members.empty() && mapfile && mapfile->getBufferSize() > 8) { @@ -261,25 +245,18 @@ bool Archive::writeToDisk(bool TruncateNames, std::string *ErrMsg) { } // Create a temporary file to store the archive in - sys::Path TmpArchive(archPath); - if (TmpArchive.createTemporaryFileOnDisk(ErrMsg)) + int TmpArchiveFD; + SmallString<128> TmpArchive; + error_code EC = sys::fs::createUniqueFile( + archPath + ".temp-archive-%%%%%%%.a", TmpArchiveFD, TmpArchive); + if (EC) return true; // Make sure the temporary gets removed if we crash - sys::RemoveFileOnSignal(TmpArchive.str()); + sys::RemoveFileOnSignal(TmpArchive); // Create archive file for output. - std::ios::openmode io_mode = std::ios::out | std::ios::trunc | - std::ios::binary; - std::ofstream ArchiveFile(TmpArchive.c_str(), io_mode); - - // Check for errors opening or creating archive file. - if (!ArchiveFile.is_open() || ArchiveFile.bad()) { - TmpArchive.eraseFromDisk(); - if (ErrMsg) - *ErrMsg = "Error opening archive file: " + archPath; - return true; - } + raw_fd_ostream ArchiveFile(TmpArchiveFD, true); // Write magic string to archive. ArchiveFile << ARFILE_MAGIC; @@ -287,8 +264,8 @@ bool Archive::writeToDisk(bool TruncateNames, std::string *ErrMsg) { // Loop over all member files, and write them out. Note that this also // builds the symbol table, symTab. for (MembersList::iterator I = begin(), E = end(); I != E; ++I) { - if (writeMember(*I, ArchiveFile, TruncateNames, ErrMsg)) { - TmpArchive.eraseFromDisk(); + if (writeMember(*I, ArchiveFile, ErrMsg)) { + sys::fs::remove(Twine(TmpArchive)); ArchiveFile.close(); return true; } @@ -302,15 +279,10 @@ bool Archive::writeToDisk(bool TruncateNames, std::string *ErrMsg) { // this because we cannot replace an open file on Windows. cleanUpMemory(); - if (TmpArchive.renamePathOnDisk(sys::Path(archPath), ErrMsg)) - return true; - - // Set correct read and write permissions after temporary file is moved - // to final destination path. - if (sys::Path(archPath).makeReadableOnDisk(ErrMsg)) - return true; - if (sys::Path(archPath).makeWriteableOnDisk(ErrMsg)) + if (sys::fs::rename(Twine(TmpArchive), archPath)) { + *ErrMsg = EC.message(); return true; + } return false; }