summaryrefslogtreecommitdiff
path: root/base/files
diff options
context:
space:
mode:
authorAlex Vakulenko <avakulenko@google.com>2016-01-25 12:28:19 -0800
committerAlex Vakulenko <avakulenko@google.com>2016-01-25 12:54:42 -0800
commit1ac3a5e3e15a0a3db48c4cb13736ce38033831fe (patch)
tree024c351584392fb462e4352e4cafeec57e033b0f /base/files
parent24854748fba09df2a29f0d08d558c3acea70e7a1 (diff)
downloadlibchrome-1ac3a5e3e15a0a3db48c4cb13736ce38033831fe.tar.gz
libchrome: Add files needed by some veyron variants on Chrome OS
These files are needed for Chrome IPC. These will be compiled on Chrome OS, so no impact on AOSP. BUG: 26772882 TEST: make -j32 for dragonboard ./build_packages on CrOS for various boards. Change-Id: Ibca0a04692a59f245cab2d5c9707cff109ca144f
Diffstat (limited to 'base/files')
-rw-r--r--base/files/memory_mapped_file.cc95
-rw-r--r--base/files/memory_mapped_file_posix.cc91
2 files changed, 186 insertions, 0 deletions
diff --git a/base/files/memory_mapped_file.cc b/base/files/memory_mapped_file.cc
new file mode 100644
index 0000000000..0fd9d6796b
--- /dev/null
+++ b/base/files/memory_mapped_file.cc
@@ -0,0 +1,95 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/files/memory_mapped_file.h"
+
+#include <utility>
+
+#include "base/files/file_path.h"
+#include "base/logging.h"
+#include "base/sys_info.h"
+#include "build/build_config.h"
+
+namespace base {
+
+const MemoryMappedFile::Region MemoryMappedFile::Region::kWholeFile = {0, 0};
+
+bool MemoryMappedFile::Region::operator==(
+ const MemoryMappedFile::Region& other) const {
+ return other.offset == offset && other.size == size;
+}
+
+bool MemoryMappedFile::Region::operator!=(
+ const MemoryMappedFile::Region& other) const {
+ return other.offset != offset || other.size != size;
+}
+
+MemoryMappedFile::~MemoryMappedFile() {
+ CloseHandles();
+}
+
+#if !defined(OS_NACL)
+bool MemoryMappedFile::Initialize(const FilePath& file_name) {
+ if (IsValid())
+ return false;
+
+ file_.Initialize(file_name, File::FLAG_OPEN | File::FLAG_READ);
+
+ if (!file_.IsValid()) {
+ DLOG(ERROR) << "Couldn't open " << file_name.AsUTF8Unsafe();
+ return false;
+ }
+
+ if (!MapFileRegionToMemory(Region::kWholeFile)) {
+ CloseHandles();
+ return false;
+ }
+
+ return true;
+}
+
+bool MemoryMappedFile::Initialize(File file) {
+ return Initialize(std::move(file), Region::kWholeFile);
+}
+
+bool MemoryMappedFile::Initialize(File file, const Region& region) {
+ if (IsValid())
+ return false;
+
+ if (region != Region::kWholeFile) {
+ DCHECK_GE(region.offset, 0);
+ DCHECK_GT(region.size, 0);
+ }
+
+ file_ = std::move(file);
+
+ if (!MapFileRegionToMemory(region)) {
+ CloseHandles();
+ return false;
+ }
+
+ return true;
+}
+
+bool MemoryMappedFile::IsValid() const {
+ return data_ != NULL;
+}
+
+// static
+void MemoryMappedFile::CalculateVMAlignedBoundaries(int64_t start,
+ int64_t size,
+ int64_t* aligned_start,
+ int64_t* aligned_size,
+ int32_t* offset) {
+ // Sadly, on Windows, the mmap alignment is not just equal to the page size.
+ const int64_t mask =
+ static_cast<int64_t>(SysInfo::VMAllocationGranularity()) - 1;
+ DCHECK_LT(mask, std::numeric_limits<int32_t>::max());
+ *offset = start & mask;
+ *aligned_start = start & ~mask;
+ *aligned_size = (size + *offset + mask) & ~mask;
+}
+#endif
+
+} // namespace base
diff --git a/base/files/memory_mapped_file_posix.cc b/base/files/memory_mapped_file_posix.cc
new file mode 100644
index 0000000000..1067fdc9ac
--- /dev/null
+++ b/base/files/memory_mapped_file_posix.cc
@@ -0,0 +1,91 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/files/memory_mapped_file.h"
+
+#include <stddef.h>
+#include <stdint.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "base/logging.h"
+#include "base/threading/thread_restrictions.h"
+#include "build/build_config.h"
+
+namespace base {
+
+MemoryMappedFile::MemoryMappedFile() : data_(NULL), length_(0) {
+}
+
+#if !defined(OS_NACL)
+bool MemoryMappedFile::MapFileRegionToMemory(
+ const MemoryMappedFile::Region& region) {
+ ThreadRestrictions::AssertIOAllowed();
+
+ off_t map_start = 0;
+ size_t map_size = 0;
+ int32_t data_offset = 0;
+
+ if (region == MemoryMappedFile::Region::kWholeFile) {
+ int64_t file_len = file_.GetLength();
+ if (file_len == -1) {
+ DPLOG(ERROR) << "fstat " << file_.GetPlatformFile();
+ return false;
+ }
+ map_size = static_cast<size_t>(file_len);
+ length_ = map_size;
+ } else {
+ // The region can be arbitrarily aligned. mmap, instead, requires both the
+ // start and size to be page-aligned. Hence, we map here the page-aligned
+ // outer region [|aligned_start|, |aligned_start| + |size|] which contains
+ // |region| and then add up the |data_offset| displacement.
+ int64_t aligned_start = 0;
+ int64_t aligned_size = 0;
+ CalculateVMAlignedBoundaries(region.offset,
+ region.size,
+ &aligned_start,
+ &aligned_size,
+ &data_offset);
+
+ // Ensure that the casts in the mmap call below are sane.
+ if (aligned_start < 0 || aligned_size < 0 ||
+ aligned_start > std::numeric_limits<off_t>::max() ||
+ static_cast<uint64_t>(aligned_size) >
+ std::numeric_limits<size_t>::max() ||
+ static_cast<uint64_t>(region.size) >
+ std::numeric_limits<size_t>::max()) {
+ DLOG(ERROR) << "Region bounds are not valid for mmap";
+ return false;
+ }
+
+ map_start = static_cast<off_t>(aligned_start);
+ map_size = static_cast<size_t>(aligned_size);
+ length_ = static_cast<size_t>(region.size);
+ }
+
+ data_ = static_cast<uint8_t*>(mmap(NULL, map_size, PROT_READ, MAP_SHARED,
+ file_.GetPlatformFile(), map_start));
+ if (data_ == MAP_FAILED) {
+ DPLOG(ERROR) << "mmap " << file_.GetPlatformFile();
+ return false;
+ }
+
+ data_ += data_offset;
+ return true;
+}
+#endif
+
+void MemoryMappedFile::CloseHandles() {
+ ThreadRestrictions::AssertIOAllowed();
+
+ if (data_ != NULL)
+ munmap(data_, length_);
+ file_.Close();
+
+ data_ = NULL;
+ length_ = 0;
+}
+
+} // namespace base