// Copyright 2014 The Crashpad Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "util/mach/child_port_server.h"
#include <iterator>
#include "util/mach/child_portServer.h"
#include "util/mach/mach_message.h"
namespace {
// There is no predefined constant for this.
enum MachMessageID : mach_msg_id_t {
kMachMessageIDChildPortCheckIn = 10011,
};
// The MIG-generated __MIG_check__Request__*() functions are not declared as
// accepting const data, but they could have been because they in fact do not
// modify the data. This wrapper function is provided to bridge the const gap
// between the code in this file, which is const-correct and treats request
// message data as const, and the generated function.
kern_return_t MIGCheckRequestChildPortCheckIn(
const __Request__child_port_check_in_t* in_request) {
using Request = __Request__child_port_check_in_t;
return __MIG_check__Request__child_port_check_in_t(
const_cast<Request*>(in_request));
}
} // namespace
namespace crashpad {
ChildPortServer::ChildPortServer(ChildPortServer::Interface* interface)
: MachMessageServer::Interface(),
interface_(interface) {
}
bool ChildPortServer::MachMessageServerFunction(
const mach_msg_header_t* in_header,
mach_msg_header_t* out_header,
bool* destroy_complex_request) {
PrepareMIGReplyFromRequest(in_header, out_header);
const mach_msg_trailer_t* in_trailer =
MachMessageTrailerFromHeader(in_header);
switch (in_header->msgh_id) {
case kMachMessageIDChildPortCheckIn: {
// child_port_check_in(), handle_child_port_check_in().
using Request = __Request__child_port_check_in_t;
const Request* in_request = reinterpret_cast<const Request*>(in_header);
kern_return_t kr = MIGCheckRequestChildPortCheckIn(in_request);
if (kr != MACH_MSG_SUCCESS) {
SetMIGReplyError(out_header, kr);
return true;
}
using Reply = __Reply__child_port_check_in_t;
Reply* out_reply = reinterpret_cast<Reply*>(out_header);
out_reply->RetCode =
interface_->HandleChildPortCheckIn(in_header->msgh_local_port,
in_request->token,
in_request->port.name,
in_request->port.disposition,
in_trailer,
destroy_complex_request);
return true;
}
default: {
SetMIGReplyError(out_header, MIG_BAD_ID);
return false;
}
}
}
std::set<mach_msg_id_t> ChildPortServer::MachMessageServerRequestIDs() {
static constexpr mach_msg_id_t request_ids[] =
{kMachMessageIDChildPortCheckIn};
return std::set<mach_msg_id_t>(&request_ids[0],
&request_ids[std::size(request_ids)]);
}
mach_msg_size_t ChildPortServer::MachMessageServerRequestSize() {
return sizeof(__RequestUnion__handle_child_port_subsystem);
}
mach_msg_size_t ChildPortServer::MachMessageServerReplySize() {
return sizeof(__ReplyUnion__handle_child_port_subsystem);
}
} // namespace crashpad