summaryrefslogtreecommitdiff
path: root/libsanitizer/sanitizer_common/sanitizer_file.cc
diff options
context:
space:
mode:
Diffstat (limited to 'libsanitizer/sanitizer_common/sanitizer_file.cc')
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_file.cc59
1 files changed, 49 insertions, 10 deletions
diff --git a/libsanitizer/sanitizer_common/sanitizer_file.cc b/libsanitizer/sanitizer_common/sanitizer_file.cc
index 8740dbb5b6f..61fcc9f90d7 100644
--- a/libsanitizer/sanitizer_common/sanitizer_file.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_file.cc
@@ -93,32 +93,40 @@ void ReportFile::SetReportPath(const char *path) {
bool ReadFileToBuffer(const char *file_name, char **buff, uptr *buff_size,
uptr *read_len, uptr max_len, error_t *errno_p) {
- uptr PageSize = GetPageSizeCached();
- uptr kMinFileLen = PageSize;
*buff = nullptr;
*buff_size = 0;
*read_len = 0;
+ if (!max_len)
+ return true;
+ uptr PageSize = GetPageSizeCached();
+ uptr kMinFileLen = Min(PageSize, max_len);
+
// The files we usually open are not seekable, so try different buffer sizes.
- for (uptr size = kMinFileLen; size <= max_len; size *= 2) {
- fd_t fd = OpenFile(file_name, RdOnly, errno_p);
- if (fd == kInvalidFd) return false;
+ for (uptr size = kMinFileLen;; size = Min(size * 2, max_len)) {
UnmapOrDie(*buff, *buff_size);
*buff = (char*)MmapOrDie(size, __func__);
*buff_size = size;
+ fd_t fd = OpenFile(file_name, RdOnly, errno_p);
+ if (fd == kInvalidFd) {
+ UnmapOrDie(*buff, *buff_size);
+ return false;
+ }
*read_len = 0;
// Read up to one page at a time.
bool reached_eof = false;
- while (*read_len + PageSize <= size) {
+ while (*read_len < size) {
uptr just_read;
- if (!ReadFromFile(fd, *buff + *read_len, PageSize, &just_read, errno_p)) {
+ if (!ReadFromFile(fd, *buff + *read_len, size - *read_len, &just_read,
+ errno_p)) {
UnmapOrDie(*buff, *buff_size);
+ CloseFile(fd);
return false;
}
- if (just_read == 0) {
+ *read_len += just_read;
+ if (just_read == 0 || *read_len == max_len) {
reached_eof = true;
break;
}
- *read_len += just_read;
}
CloseFile(fd);
if (reached_eof) // We've read the whole file.
@@ -127,6 +135,37 @@ bool ReadFileToBuffer(const char *file_name, char **buff, uptr *buff_size,
return true;
}
+bool ReadFileToVector(const char *file_name,
+ InternalMmapVectorNoCtor<char> *buff, uptr max_len,
+ error_t *errno_p) {
+ buff->clear();
+ if (!max_len)
+ return true;
+ uptr PageSize = GetPageSizeCached();
+ fd_t fd = OpenFile(file_name, RdOnly, errno_p);
+ if (fd == kInvalidFd)
+ return false;
+ uptr read_len = 0;
+ while (read_len < max_len) {
+ if (read_len >= buff->size())
+ buff->resize(Min(Max(PageSize, read_len * 2), max_len));
+ CHECK_LT(read_len, buff->size());
+ CHECK_LE(buff->size(), max_len);
+ uptr just_read;
+ if (!ReadFromFile(fd, buff->data() + read_len, buff->size() - read_len,
+ &just_read, errno_p)) {
+ CloseFile(fd);
+ return false;
+ }
+ read_len += just_read;
+ if (!just_read)
+ break;
+ }
+ CloseFile(fd);
+ buff->resize(read_len);
+ return true;
+}
+
static const char kPathSeparator = SANITIZER_WINDOWS ? ';' : ':';
char *FindPathToBinary(const char *name) {
@@ -138,7 +177,7 @@ char *FindPathToBinary(const char *name) {
if (!path)
return nullptr;
uptr name_len = internal_strlen(name);
- InternalScopedBuffer<char> buffer(kMaxPathLength);
+ InternalMmapVector<char> buffer(kMaxPathLength);
const char *beg = path;
while (true) {
const char *end = internal_strchrnul(beg, kPathSeparator);