// Copyright 2014 The Crashpad Authors. All rights reserved. // // 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 "base/stl_util.h" #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(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(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(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 ChildPortServer::MachMessageServerRequestIDs() { static constexpr mach_msg_id_t request_ids[] = {kMachMessageIDChildPortCheckIn}; return std::set(&request_ids[0], &request_ids[base::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