#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"
// 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();
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()] = '/';
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)
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;
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
// 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));
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
// 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) {
}
// 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;
// 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;
}
// 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;
}