blob: f632b6dcbf551c86411a3e56e39f48510f89fffb [file] [log] [blame]
// Copyright 2018 The Chromium OS 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 "diagnostics/common/mojo_utils.h"
#include <unistd.h>
#include <cstring>
#include <utility>
#include <base/files/file.h>
#include <base/memory/shared_memory_handle.h>
#include <mojo/public/c/system/types.h>
#include <mojo/public/cpp/system/platform_handle.h>
namespace diagnostics {
std::unique_ptr<base::SharedMemory> GetReadOnlySharedMemoryFromMojoHandle(
mojo::ScopedHandle handle) {
base::PlatformFile platform_file;
auto result = mojo::UnwrapPlatformFile(std::move(handle), &platform_file);
if (result != MOJO_RESULT_OK) {
return nullptr;
}
const int fd(HANDLE_EINTR(dup(platform_file)));
if (fd < 0) {
return nullptr;
}
const int64_t file_size = base::File(fd).GetLength();
if (file_size <= 0) {
return nullptr;
}
auto shared_memory = std::make_unique<base::SharedMemory>(
base::SharedMemoryHandle(
base::FileDescriptor(platform_file, true /* iauto_close */),
file_size, base::UnguessableToken::Create()),
true /* read_only */);
if (!shared_memory->Map(file_size)) {
return nullptr;
}
return shared_memory;
}
mojo::ScopedHandle CreateReadOnlySharedMemoryMojoHandle(
base::StringPiece content) {
if (content.empty())
return mojo::ScopedHandle();
base::SharedMemory shared_memory;
base::SharedMemoryCreateOptions options;
options.size = content.length();
options.share_read_only = true;
if (!shared_memory.Create(base::SharedMemoryCreateOptions(options)) ||
!shared_memory.Map(content.length())) {
return mojo::ScopedHandle();
}
memcpy(shared_memory.memory(), content.data(), content.length());
base::SharedMemoryHandle handle = shared_memory.GetReadOnlyHandle();
if (!handle.IsValid()) {
return mojo::ScopedHandle();
}
return mojo::WrapPlatformFile(handle.GetHandle());
}
} // namespace diagnostics