MachIPC.h revision a599ae80aa44f2f6dbe8c5b86d2e503a8c7b6639
13ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// Copyright (c) 2007, Google Inc. 23ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// All rights reserved. 33ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// 43ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// Redistribution and use in source and binary forms, with or without 53ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// modification, are permitted provided that the following conditions are 63ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// met: 73ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// 83ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// * Redistributions of source code must retain the above copyright 93ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// notice, this list of conditions and the following disclaimer. 103ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// * Redistributions in binary form must reproduce the above 113ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// copyright notice, this list of conditions and the following disclaimer 123ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// in the documentation and/or other materials provided with the 133ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// distribution. 143ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// * Neither the name of Google Inc. nor the names of its 153ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// contributors may be used to endorse or promote products derived from 163ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// this software without specific prior written permission. 173ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// 183ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 193ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 203ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 213ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 223ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 233ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 243ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 253ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 263ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 273ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 283ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 293ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// 303ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// MachIPC.h 313ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// 323ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// Some helpful wrappers for using Mach IPC calls 333ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 343ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid#ifndef MACH_IPC_H__ 353ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid#define MACH_IPC_H__ 363ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 373ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid#import <mach/mach.h> 383ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid#import <mach/message.h> 393ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid#import <servers/bootstrap.h> 403ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid#import <sys/types.h> 413ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 423ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid#import <CoreServices/CoreServices.h> 433ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 443ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid//============================================================================== 453ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// DISCUSSION: 463ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// 473ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// The three main classes of interest are 483ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// 493ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// MachMessage: a wrapper for a mach message of the following form 503ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// mach_msg_header_t 513ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// mach_msg_body_t 523ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// optional descriptors 533ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// optional extra message data 543ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// 553ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// MachReceiveMessage and MachSendMessage subclass MachMessage 563ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// and are used instead of MachMessage which is an abstract base class 573ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// 583ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// ReceivePort: 593ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// Represents a mach port for which we have receive rights 603ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// 613ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// MachPortSender: 623ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// Represents a mach port for which we have send rights 633ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// 643ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// Here's an example to receive a message on a server port: 653ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// 663ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// // This creates our named server port 673ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// ReceivePort receivePort("com.Google.MyService"); 683ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// 693ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// MachReceiveMessage message; 703ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// kern_return_t result = receivePort.WaitForMessage(&message, 0); 713ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// 723ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// if (result == KERN_SUCCESS && message.GetMessageID() == 57) { 733ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// mach_port_t task = message.GetTranslatedPort(0); 743ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// mach_port_t thread = message.GetTranslatedPort(1); 753ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// 763ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// char *messageString = message.GetData(); 773ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// 783ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// printf("message string = %s\n", messageString); 793ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// } 803ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// 813ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// Here is an example of using these classes to send a message to this port: 823ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// 833ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// // send to already named port 843ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// MachPortSender sender("com.Google.MyService"); 853ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// MachSendMessage message(57); // our message ID is 57 863ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// 873ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// // add some ports to be translated for us 883ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// message.AddDescriptor(mach_task_self()); // our task 893ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// message.AddDescriptor(mach_thread_self()); // this thread 903ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// 913ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// char messageString[] = "Hello server!\n"; 923ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// message.SetData(messageString, strlen(messageString)+1); 933ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// 943ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// kern_return_t result = sender.SendMessage(message, 1000); // timeout 1000ms 953ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// 963ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 97a599ae80aa44f2f6dbe8c5b86d2e503a8c7b6639ted.mielczarek@gmail.comnamespace google_breakpad { 983ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid#define PRINT_MACH_RESULT(result_, message_) \ 993ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid printf(message_" %s (%d)\n", mach_error_string(result_), result_ ); 1003ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 1013ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid//============================================================================== 1023ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// A wrapper class for mach_msg_port_descriptor_t (with same memory layout) 1033ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// with convenient constructors and accessors 1043ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsidclass MachMsgPortDescriptor : public mach_msg_port_descriptor_t { 1053ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid public: 1063ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid // General-purpose constructor 1073ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid MachMsgPortDescriptor(mach_port_t in_name, 1083ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid mach_msg_type_name_t in_disposition) { 1093ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid name = in_name; 1103ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid pad1 = 0; 1113ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid pad2 = 0; 1123ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid disposition = in_disposition; 1133ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid type = MACH_MSG_PORT_DESCRIPTOR; 1143ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid } 1153ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 1163ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid // For passing send rights to a port 1173ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid MachMsgPortDescriptor(mach_port_t in_name) { 1183ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid name = in_name; 1193ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid pad1 = 0; 1203ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid pad2 = 0; 1213ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid disposition = MACH_MSG_TYPE_COPY_SEND; 1223ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid type = MACH_MSG_PORT_DESCRIPTOR; 1233ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid } 1243ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 1253ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid // Copy constructor 1263ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid MachMsgPortDescriptor(const MachMsgPortDescriptor& desc) { 1273ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid name = desc.name; 1283ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid pad1 = desc.pad1; 1293ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid pad2 = desc.pad2; 1303ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid disposition = desc.disposition; 1313ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid type = desc.type; 1323ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid } 1333ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 1343ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid mach_port_t GetMachPort() const { 1353ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid return name; 1363ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid } 1373ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 1383ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid mach_msg_type_name_t GetDisposition() const { 1393ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid return disposition; 1403ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid } 1413ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 1423ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid // We're just a simple wrapper for mach_msg_port_descriptor_t 1433ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid // and have the same memory layout 1443ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid operator mach_msg_port_descriptor_t&() { 1453ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid return *this; 1463ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid } 1473ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 1483ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid // For convenience 1493ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid operator mach_port_t() const { 1503ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid return GetMachPort(); 1513ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid } 1523ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid}; 1533ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 1543ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid//============================================================================== 1553ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// MachMessage: a wrapper for a mach message 1563ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// (mach_msg_header_t, mach_msg_body_t, extra data) 1573ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// 1583ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// This considerably simplifies the construction of a message for sending 1593ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// and the getting at relevant data and descriptors for the receiver. 1603ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// 1613ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// Currently the combined size of the descriptors plus data must be 1623ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// less than 1024. But as a benefit no memory allocation is necessary. 1633ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// 1643ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// TODO: could consider adding malloc() support for very large messages 1653ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// 1663ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// A MachMessage object is used by ReceivePort::WaitForMessage 1673ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// and MachPortSender::SendMessage 1683ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// 1693ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsidclass MachMessage { 1703ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid public: 1713ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 1723ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid // The receiver of the message can retrieve the raw data this way 1733ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid u_int8_t *GetData() { 1743ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid return GetDataLength() > 0 ? GetDataPacket()->data : NULL; 1753ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid } 1763ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 1773ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid u_int32_t GetDataLength() { 1783ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid return EndianU32_LtoN(GetDataPacket()->data_length); 1793ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid } 1803ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 1813ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid // The message ID may be used as a code identifying the type of message 1823ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid void SetMessageID(int32_t message_id) { 1833ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid GetDataPacket()->id = EndianU32_NtoL(message_id); 1843ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid } 1853ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 1863ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid int32_t GetMessageID() { return EndianU32_LtoN(GetDataPacket()->id); } 1873ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 1883ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid // Adds a descriptor (typically a mach port) to be translated 1893ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid // returns true if successful, otherwise not enough space 1903ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid bool AddDescriptor(const MachMsgPortDescriptor &desc); 1913ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 1923ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid int GetDescriptorCount() const { return body.msgh_descriptor_count; } 1933ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid MachMsgPortDescriptor *GetDescriptor(int n); 1943ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 1953ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid // Convenience method which gets the mach port described by the descriptor 1963ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid mach_port_t GetTranslatedPort(int n); 1973ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 1983ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid // A simple message is one with no descriptors 1993ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid bool IsSimpleMessage() const { return GetDescriptorCount() == 0; } 2003ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 2013ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid // Sets raw data for the message (returns false if not enough space) 2023ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid bool SetData(void *data, int32_t data_length); 2033ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 2043ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid protected: 2053ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid // Consider this an abstract base class - must create an actual instance 2063ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid // of MachReceiveMessage or MachSendMessage 2073ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 2083ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid MachMessage() { 2093ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid memset(this, 0, sizeof(MachMessage)); 2103ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid } 2113ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 2123ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid friend class ReceivePort; 2133ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid friend class MachPortSender; 2143ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 2153ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid // Represents raw data in our message 2163ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid struct MessageDataPacket { 2173ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid int32_t id; // little-endian 2183ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid int32_t data_length; // little-endian 2193ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid u_int8_t data[1]; // actual size limited by sizeof(MachMessage) 2203ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid }; 2213ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 2223ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid MessageDataPacket* GetDataPacket(); 2233ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 2243ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid void SetDescriptorCount(int n); 2253ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid void SetDescriptor(int n, const MachMsgPortDescriptor &desc); 2263ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 2273ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid // Returns total message size setting msgh_size in the header to this value 2284ac61acb3a7dad6ce722fe07564be8ec92713228dmaclach mach_msg_size_t CalculateSize(); 2293ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 2303ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid mach_msg_header_t head; 2313ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid mach_msg_body_t body; 2323ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid u_int8_t padding[1024]; // descriptors and data may be embedded here 2333ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid}; 2343ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 2353ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid//============================================================================== 2363ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// MachReceiveMessage and MachSendMessage are useful to separate the idea 2373ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// of a mach message being sent and being received, and adds increased type 2383ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// safety: 2393ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// ReceivePort::WaitForMessage() only accepts a MachReceiveMessage 2403ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// MachPortSender::SendMessage() only accepts a MachSendMessage 2413ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 2423ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid//============================================================================== 2433ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsidclass MachReceiveMessage : public MachMessage { 2443ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid public: 2453ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid MachReceiveMessage() : MachMessage() {}; 2463ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid}; 2473ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 2483ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid//============================================================================== 2493ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsidclass MachSendMessage : public MachMessage { 2503ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid public: 2513ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid MachSendMessage(int32_t message_id); 2523ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid}; 2533ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 2543ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid//============================================================================== 2553ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// Represents a mach port for which we have receive rights 2563ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsidclass ReceivePort { 2573ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid public: 2583ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid // Creates a new mach port for receiving messages and registers a name for it 259315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com explicit ReceivePort(const char *receive_port_name); 2603ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 2613ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid // Given an already existing mach port, use it. We take ownership of the 2623ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid // port and deallocate it in our destructor. 263315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com explicit ReceivePort(mach_port_t receive_port); 2643ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 2653ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid // Create a new mach port for receiving messages 2663ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid ReceivePort(); 2673ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 2683ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid ~ReceivePort(); 2693ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 2703ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid // Waits on the mach port until message received or timeout 2713ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid kern_return_t WaitForMessage(MachReceiveMessage *out_message, 2723ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid mach_msg_timeout_t timeout); 2733ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 2743ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid // The underlying mach port that we wrap 2753ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid mach_port_t GetPort() const { return port_; } 2763ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 2773ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid private: 2783ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid ReceivePort(const ReceivePort&); // disable copy c-tor 2793ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 2803ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid mach_port_t port_; 2813ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid kern_return_t init_result_; 2823ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid}; 2833ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 2843ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid//============================================================================== 2853ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// Represents a mach port for which we have send rights 2863ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsidclass MachPortSender { 2873ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid public: 2883ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid // get a port with send rights corresponding to a named registered service 289315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com explicit MachPortSender(const char *receive_port_name); 2903ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 2913ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 2923ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid // Given an already existing mach port, use it. 293315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com explicit MachPortSender(mach_port_t send_port); 2943ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 2953ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid kern_return_t SendMessage(MachSendMessage &message, 2963ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid mach_msg_timeout_t timeout); 2973ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 2983ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid private: 2993ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid MachPortSender(const MachPortSender&); // disable copy c-tor 3003ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 3013ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid mach_port_t send_port_; 3023ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid kern_return_t init_result_; 3033ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid}; 3043ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 305a599ae80aa44f2f6dbe8c5b86d2e503a8c7b6639ted.mielczarek@gmail.com} // namespace google_breakpad 306a599ae80aa44f2f6dbe8c5b86d2e503a8c7b6639ted.mielczarek@gmail.com 3073ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid#endif // MACH_IPC_H__ 308