#include "mojo/public/cpp/platform/platform_channel.h"
#include <cstddef>
#include <cstdint>
#include <string>
#include <tuple>
#include <utility>
#include "base/logging.h"
#include "base/numerics/clamped_math.h"
#include "build/build_config.h"
#include "mojo/buildflags.h"
#include "mojo/core/embedder/features.h"
#if BUILDFLAG(IS_WIN)
#include <windows.h>
#include "base/win/scoped_handle.h"
#include "mojo/public/cpp/platform/named_platform_channel.h"
#elif BUILDFLAG(IS_FUCHSIA)
#include <lib/zx/channel.h>
#include <zircon/process.h>
#include <zircon/processargs.h>
#include "base/fuchsia/fuchsia_logging.h"
#elif BUILDFLAG(IS_POSIX)
#include <fcntl.h>
#include <sys/types.h>
#include <unistd.h>
#include "base/files/scoped_file.h"
#include "base/posix/global_descriptors.h"
#endif
#if BUILDFLAG(MOJO_USE_APPLE_CHANNEL)
#include <mach/port.h>
#include "base/apple/mach_logging.h"
#include "base/apple/scoped_mach_port.h"
#endif
#if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_NACL)
#include <sys/socket.h>
#elif BUILDFLAG(IS_NACL)
#include "native_client/src/public/imc_syscalls.h"
#endif
#if BUILDFLAG(IS_ANDROID)
#include "base/android/binder.h"
#include "mojo/public/cpp/platform/binder_exchange.h"
#endif
namespace mojo {
namespace {
#if BUILDFLAG(IS_WIN)
void CreateChannel(PlatformHandle* local_endpoint,
PlatformHandle* remote_endpoint) {
std::wstring pipe_name = NamedPlatformChannel::GetPipeNameFromServerName(
NamedPlatformChannel::GenerateRandomServerName());
DWORD kOpenMode =
PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED | FILE_FLAG_FIRST_PIPE_INSTANCE;
const DWORD kPipeMode = PIPE_TYPE_BYTE | PIPE_READMODE_BYTE;
*local_endpoint = PlatformHandle(base::win::ScopedHandle(
::CreateNamedPipeW(pipe_name.c_str(), kOpenMode, kPipeMode,
1,
4096,
4096,
5000,
nullptr)));
PCHECK(local_endpoint->is_valid());
const DWORD kDesiredAccess = GENERIC_READ | GENERIC_WRITE;
DWORD kFlags =
SECURITY_SQOS_PRESENT | SECURITY_ANONYMOUS | FILE_FLAG_OVERLAPPED;
SECURITY_ATTRIBUTES security_attributes = {sizeof(SECURITY_ATTRIBUTES),
nullptr, TRUE};
*remote_endpoint = PlatformHandle(base::win::ScopedHandle(
::CreateFileW(pipe_name.c_str(), kDesiredAccess, 0, &security_attributes,
OPEN_EXISTING, kFlags, nullptr)));
PCHECK(remote_endpoint->is_valid());
CHECK(!::ConnectNamedPipe(local_endpoint->GetHandle().Get(), nullptr));
PCHECK(::GetLastError() == ERROR_PIPE_CONNECTED);
}
#elif BUILDFLAG(IS_FUCHSIA)
void CreateChannel(PlatformHandle* local_endpoint,
PlatformHandle* remote_endpoint) {
zx::channel handles[2];
zx_status_t result = zx::channel::create(0, &handles[0], &handles[1]);
ZX_CHECK(result == ZX_OK, result);
*local_endpoint = PlatformHandle(std::move(handles[0]));
*remote_endpoint = PlatformHandle(std::move(handles[1]));
DCHECK(local_endpoint->is_valid());
DCHECK(remote_endpoint->is_valid());
}
#elif BUILDFLAG(MOJO_USE_APPLE_CHANNEL)
void CreateChannel(PlatformHandle* local_endpoint,
PlatformHandle* remote_endpoint) {
base::apple::ScopedMachReceiveRight receive;
base::apple::ScopedMachSendRight send;
CHECK(base::apple::CreateMachPort(&receive, &send, MACH_PORT_QLIMIT_LARGE));
*local_endpoint = PlatformHandle(std::move(send));
*remote_endpoint = PlatformHandle(std::move(receive));
}
#elif BUILDFLAG(IS_POSIX)
void CreateChannel(PlatformHandle* local_endpoint,
PlatformHandle* remote_endpoint) { … }
#else
#error "Unsupported platform."
#endif
}
const char PlatformChannel::kHandleSwitch[] = …;
PlatformChannel::PlatformChannel() { … }
PlatformChannel::PlatformChannel(PlatformChannelEndpoint local,
PlatformChannelEndpoint remote)
: … { … }
PlatformChannel::PlatformChannel(PlatformChannel&& other) = default;
PlatformChannel& PlatformChannel::operator=(PlatformChannel&& other) = default;
PlatformChannel::~PlatformChannel() = default;
void PlatformChannel::PrepareToPassRemoteEndpoint(HandlePassingInfo* info,
std::string* value) { … }
std::string PlatformChannel::PrepareToPassRemoteEndpoint(
base::LaunchOptions& options) { … }
void PlatformChannel::PrepareToPassRemoteEndpoint(
HandlePassingInfo* info,
base::CommandLine* command_line) { … }
void PlatformChannel::PrepareToPassRemoteEndpoint(
base::LaunchOptions* options,
base::CommandLine* command_line) { … }
void PlatformChannel::RemoteProcessLaunchAttempted() { … }
PlatformChannelEndpoint PlatformChannel::RecoverPassedEndpointFromString(
std::string_view value) { … }
PlatformChannelEndpoint PlatformChannel::RecoverPassedEndpointFromCommandLine(
const base::CommandLine& command_line) { … }
bool PlatformChannel::CommandLineHasPassedEndpoint(
const base::CommandLine& command_line) { … }
}