1 #include <darwintest.h> 2 #include <darwintest_utils.h> 3 4 #include <mach/mach.h> 5 #include <mach/mach_types.h> 6 #include <mach/mach_port.h> 7 #include <mach/message.h> 8 #include <mach/mach_error.h> 9 10 11 T_GLOBAL_META( 12 T_META_NAMESPACE("xnu.ipc"), 13 T_META_RUN_CONCURRENTLY(TRUE), 14 T_META_RADAR_COMPONENT_NAME("xnu"), 15 T_META_RADAR_COMPONENT_VERSION("IPC")); 16 17 T_DECL(mach_port_peek, "Test mach port peeking") 18 { 19 mach_port_t port; 20 kern_return_t kr; 21 struct msg { 22 mach_msg_header_t header; 23 char data[512]; 24 char trailer[128]; 25 } msg; 26 27 mach_msg_id_t outgoing_id; 28 mach_msg_size_t send_size; 29 30 kr = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &port); 31 T_QUIET; T_ASSERT_EQ(kr, KERN_SUCCESS, "mach_port_allocate"); 32 33 outgoing_id = 0x41414141; 34 send_size = sizeof(msg) - 128; /* minus trailer space */ 35 36 msg.header.msgh_local_port = MACH_PORT_NULL; 37 msg.header.msgh_remote_port = port; 38 msg.header.msgh_id = outgoing_id; 39 msg.header.msgh_bits = MACH_MSGH_BITS_SET(MACH_MSG_TYPE_MAKE_SEND, 0, 0, 0); 40 msg.header.msgh_size = send_size; 41 42 kr = mach_msg(&msg.header, MACH_SEND_MSG, msg.header.msgh_size, 0, 43 MACH_PORT_NULL, 44 MACH_MSG_TIMEOUT_NONE, 45 MACH_PORT_NULL); 46 T_ASSERT_EQ(kr, KERN_SUCCESS, "Message sent to port"); 47 48 mach_port_seqno_t seqno = 0; 49 mach_msg_trailer_type_t tlrtype = 50 MACH_RCV_TRAILER_TYPE(MACH_MSG_TRAILER_FORMAT_0) 51 | MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_AUDIT); 52 mach_msg_audit_trailer_t audit_trailer; 53 mach_msg_type_number_t size = sizeof(audit_trailer); 54 mach_msg_type_number_t incoming_size = 0; 55 mach_msg_id_t incoming_id; 56 57 kr = mach_port_peek(mach_task_self(), port, tlrtype, &seqno, &incoming_size, &incoming_id, &audit_trailer, &size); 58 T_ASSERT_EQ(kr, KERN_SUCCESS, "mach_port_peek"); 59 60 T_ASSERT_EQ(incoming_id, outgoing_id, "Peek must return correct msgh_id"); 61 62 #define USER_HEADER_SIZE_DELTA 8 /* sizeof(mach_msg_header_t) - sizeof(mach_msg_user_header_t) */ 63 T_ASSERT_EQ(incoming_size, send_size + USER_HEADER_SIZE_DELTA, "Peek must return correct msg size"); 64 65 kr = mach_msg(&msg.header, MACH_RCV_MSG, 0, 66 sizeof(msg), port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); 67 T_ASSERT_EQ(kr, KERN_SUCCESS, "Message receive success after peek."); 68 } 69