#include "config.h"
#include "MachMessage.h"
#if PLATFORM(COCOA)
#include <mach/mach.h>
namespace IPC {
static inline CheckedSize safeRoundMsg(CheckedSize value)
{
constexpr size_t alignment = sizeof(natural_t);
return ((value + (alignment - 1)) / alignment) * alignment;
}
std::unique_ptr<MachMessage> MachMessage::create(MessageName messageName, size_t size)
{
auto bufferSize = CheckedSize(sizeof(MachMessage)) + size;
if (bufferSize.hasOverflowed())
return nullptr;
void* memory = WTF::fastZeroedMalloc(bufferSize.unsafeGet());
return std::unique_ptr<MachMessage> { new (NotNull, memory) MachMessage { messageName, size } };
}
MachMessage::MachMessage(MessageName messageName, size_t size)
: m_messageName { messageName }
, m_size { size }
{
}
MachMessage::~MachMessage()
{
if (m_shouldFreeDescriptors)
::mach_msg_destroy(header());
}
CheckedSize MachMessage::messageSize(size_t bodySize, size_t portDescriptorCount, size_t memoryDescriptorCount)
{
CheckedSize messageSize = sizeof(mach_msg_header_t);
messageSize += bodySize;
if (portDescriptorCount || memoryDescriptorCount) {
messageSize += sizeof(mach_msg_body_t);
messageSize += (portDescriptorCount * sizeof(mach_msg_port_descriptor_t));
messageSize += (memoryDescriptorCount * sizeof(mach_msg_ool_descriptor_t));
}
return safeRoundMsg(messageSize);
}
void MachMessage::leakDescriptors()
{
m_shouldFreeDescriptors = false;
}
}
#endif // PLATFORM(COCOA)