summaryrefslogtreecommitdiffstats
path: root/lib/Support/MemoryBuffer.cpp
diff options
context:
space:
mode:
authorrdivacky <rdivacky@FreeBSD.org>2010-04-02 08:54:30 +0000
committerrdivacky <rdivacky@FreeBSD.org>2010-04-02 08:54:30 +0000
commit20e856b2a58d12231aa42d5d13888b15ac03e5a4 (patch)
treecf5763d092b81cecc168fa28032247ee495d06e2 /lib/Support/MemoryBuffer.cpp
parent2f2afc1aae898651e26987a5c71f3febb19bca98 (diff)
downloadFreeBSD-src-20e856b2a58d12231aa42d5d13888b15ac03e5a4.zip
FreeBSD-src-20e856b2a58d12231aa42d5d13888b15ac03e5a4.tar.gz
Update LLVM to r100181.
Diffstat (limited to 'lib/Support/MemoryBuffer.cpp')
-rw-r--r--lib/Support/MemoryBuffer.cpp43
1 files changed, 26 insertions, 17 deletions
diff --git a/lib/Support/MemoryBuffer.cpp b/lib/Support/MemoryBuffer.cpp
index 345a78c..4f135ea 100644
--- a/lib/Support/MemoryBuffer.cpp
+++ b/lib/Support/MemoryBuffer.cpp
@@ -14,6 +14,7 @@
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/System/Errno.h"
#include "llvm/System/Path.h"
#include "llvm/System/Process.h"
#include "llvm/System/Program.h"
@@ -167,6 +168,14 @@ public:
sys::Path::UnMapFilePages(getBufferStart(), getBufferSize());
}
};
+
+/// FileCloser - RAII object to make sure an FD gets closed properly.
+class FileCloser {
+ int FD;
+public:
+ FileCloser(int FD) : FD(FD) {}
+ ~FileCloser() { ::close(FD); }
+};
}
MemoryBuffer *MemoryBuffer::getFile(StringRef Filename, std::string *ErrStr,
@@ -178,9 +187,10 @@ MemoryBuffer *MemoryBuffer::getFile(StringRef Filename, std::string *ErrStr,
SmallString<256> PathBuf(Filename.begin(), Filename.end());
int FD = ::open(PathBuf.c_str(), O_RDONLY|OpenFlags);
if (FD == -1) {
- if (ErrStr) *ErrStr = strerror(errno);
+ if (ErrStr) *ErrStr = sys::StrError();
return 0;
}
+ FileCloser FC(FD); // Close FD on return.
// If we don't know the file size, use fstat to find out. fstat on an open
// file descriptor is cheaper than stat on a random path.
@@ -190,8 +200,7 @@ MemoryBuffer *MemoryBuffer::getFile(StringRef Filename, std::string *ErrStr,
// TODO: This should use fstat64 when available.
if (fstat(FD, FileInfoPtr) == -1) {
- if (ErrStr) *ErrStr = strerror(errno);
- ::close(FD);
+ if (ErrStr) *ErrStr = sys::StrError();
return 0;
}
FileSize = FileInfoPtr->st_size;
@@ -208,7 +217,6 @@ MemoryBuffer *MemoryBuffer::getFile(StringRef Filename, std::string *ErrStr,
(FileSize & (sys::Process::GetPageSize()-1)) != 0) {
if (const char *Pages = sys::Path::MapInFilePages(FD, FileSize)) {
// Close the file descriptor, now that the whole file is in memory.
- ::close(FD);
return new MemoryBufferMMapFile(Filename, Pages, FileSize);
}
}
@@ -217,30 +225,31 @@ MemoryBuffer *MemoryBuffer::getFile(StringRef Filename, std::string *ErrStr,
if (!Buf) {
// Failed to create a buffer.
if (ErrStr) *ErrStr = "could not allocate buffer";
- ::close(FD);
return 0;
}
OwningPtr<MemoryBuffer> SB(Buf);
char *BufPtr = const_cast<char*>(SB->getBufferStart());
-
+
size_t BytesLeft = FileSize;
while (BytesLeft) {
ssize_t NumRead = ::read(FD, BufPtr, BytesLeft);
- if (NumRead > 0) {
- BytesLeft -= NumRead;
- BufPtr += NumRead;
- } else if (NumRead == -1 && errno == EINTR) {
- // try again
- } else {
- // error reading.
- if (ErrStr) *ErrStr = strerror(errno);
- close(FD);
+ if (NumRead == -1) {
+ if (errno == EINTR)
+ continue;
+ // Error while reading.
+ if (ErrStr) *ErrStr = sys::StrError();
return 0;
+ } else if (NumRead == 0) {
+ // We hit EOF early, truncate and terminate buffer.
+ Buf->BufferEnd = BufPtr;
+ *BufPtr = 0;
+ return SB.take();
}
+ BytesLeft -= NumRead;
+ BufPtr += NumRead;
}
- close(FD);
-
+
return SB.take();
}
OpenPOWER on IntegriCloud