#include <mach/message.h> also included by <mach/mach.h>

mach/message.h

includes: stddef.h, stdint.h, machine/limits.h, machine/types.h, mach/port.h, mach/boolean.h, mach/kern_return.h, mach/machine/vm_types.h, sys/cdefs.h, sys/appleapiopts.h, Availability.h
174 macros · 47 typedefs · 25 structs · 3 functions · 2 unions · 2 variables

typedefmach_msg_timeout_t

typedef natural_t mach_msg_timeout_t

macroMACH_MSG_TIMEOUT_NONE

#define MACH_MSG_TIMEOUT_NONE ((mach_msg_timeout_t) 0)

macroMACH_MSGH_BITS_ZERO

#define MACH_MSGH_BITS_ZERO 0x00000000

macroMACH_MSGH_BITS_REMOTE_MASK

#define MACH_MSGH_BITS_REMOTE_MASK 0x0000001f

macroMACH_MSGH_BITS_LOCAL_MASK

#define MACH_MSGH_BITS_LOCAL_MASK 0x00001f00

macroMACH_MSGH_BITS_VOUCHER_MASK

#define MACH_MSGH_BITS_VOUCHER_MASK 0x001f0000

macroMACH_MSGH_BITS_COMPLEX

#define MACH_MSGH_BITS_COMPLEX 0x80000000U
message is complex

macroMACH_MSGH_BITS_USER

#define MACH_MSGH_BITS_USER 0x801f1f1fU
allowed bits user->kernel

macroMACH_MSGH_BITS_RAISEIMP

#define MACH_MSGH_BITS_RAISEIMP 0x20000000U
importance raised due to msg

macroMACH_MSGH_BITS_DENAP

#define MACH_MSGH_BITS_DENAP MACH_MSGH_BITS_RAISEIMP

macroMACH_MSGH_BITS_IMPHOLDASRT

#define MACH_MSGH_BITS_IMPHOLDASRT 0x10000000U
assertion help, userland private

macroMACH_MSGH_BITS_DENAPHOLDASRT

#define MACH_MSGH_BITS_DENAPHOLDASRT MACH_MSGH_BITS_IMPHOLDASRT

macroMACH_MSGH_BITS_CIRCULAR

#define MACH_MSGH_BITS_CIRCULAR 0x10000000U
message circular, kernel private

macroMACH_MSGH_BITS_USED

#define MACH_MSGH_BITS_USED 0xb01f1f1fU

macroMACH_MSGH_BITS

setter macros for the bits
#define MACH_MSGH_BITS(remote, local) /* legacy */
	        ((remote) | ((local) << 8))

macroMACH_MSGH_BITS_SET_PORTS

#define MACH_MSGH_BITS_SET_PORTS(remote, local, voucher) (((remote) & MACH_MSGH_BITS_REMOTE_MASK) |
	 (((local) << 8) & MACH_MSGH_BITS_LOCAL_MASK) |
	 (((voucher) << 16) & MACH_MSGH_BITS_VOUCHER_MASK))

macroMACH_MSGH_BITS_SET

#define MACH_MSGH_BITS_SET(remote, local, voucher, other) (MACH_MSGH_BITS_SET_PORTS((remote), (local), (voucher))
	 | ((other) &~ MACH_MSGH_BITS_PORTS_MASK))

macroMACH_MSGH_BITS_REMOTE

getter macros for pulling values out of the bits field
#define MACH_MSGH_BITS_REMOTE(bits) ((bits) & MACH_MSGH_BITS_REMOTE_MASK)

macroMACH_MSGH_BITS_LOCAL

#define MACH_MSGH_BITS_LOCAL(bits) (((bits) & MACH_MSGH_BITS_LOCAL_MASK) >> 8)

macroMACH_MSGH_BITS_VOUCHER

#define MACH_MSGH_BITS_VOUCHER(bits) (((bits) & MACH_MSGH_BITS_VOUCHER_MASK) >> 16)

macroMACH_MSGH_BITS_PORTS

#define MACH_MSGH_BITS_PORTS(bits) ((bits) & MACH_MSGH_BITS_PORTS_MASK)

macroMACH_MSGH_BITS_OTHER

#define MACH_MSGH_BITS_OTHER(bits) ((bits) &~ MACH_MSGH_BITS_PORTS_MASK)

macroMACH_MSGH_BITS_HAS_REMOTE

checking macros
#define MACH_MSGH_BITS_HAS_REMOTE(bits) (MACH_MSGH_BITS_REMOTE(bits) != MACH_MSGH_BITS_ZERO)

macroMACH_MSGH_BITS_HAS_LOCAL

#define MACH_MSGH_BITS_HAS_LOCAL(bits) (MACH_MSGH_BITS_LOCAL(bits) != MACH_MSGH_BITS_ZERO)

macroMACH_MSGH_BITS_HAS_VOUCHER

#define MACH_MSGH_BITS_HAS_VOUCHER(bits) (MACH_MSGH_BITS_VOUCHER(bits) != MACH_MSGH_BITS_ZERO)

macroMACH_MSGH_BITS_IS_COMPLEX

#define MACH_MSGH_BITS_IS_COMPLEX(bits) (((bits) & MACH_MSGH_BITS_COMPLEX) != MACH_MSGH_BITS_ZERO)

macroMACH_MSGH_BITS_RAISED_IMPORTANCE

importance checking macros
#define MACH_MSGH_BITS_RAISED_IMPORTANCE(bits) (((bits) & MACH_MSGH_BITS_RAISEIMP) != MACH_MSGH_BITS_ZERO)

macroMACH_MSGH_BITS_HOLDS_IMPORTANCE_ASSERTION

#define MACH_MSGH_BITS_HOLDS_IMPORTANCE_ASSERTION(bits) (((bits) & MACH_MSGH_BITS_IMPHOLDASRT) != MACH_MSGH_BITS_ZERO)

typedefmach_msg_bits_t

typedef unsigned int mach_msg_bits_t

typedefmach_msg_size_t

typedef natural_t mach_msg_size_t

typedefmach_msg_id_t

typedef integer_t mach_msg_id_t

macroMACH_MSG_SIZE_NULL

#define MACH_MSG_SIZE_NULL (mach_msg_size_t *) 0

typedefmach_msg_priority_t

typedef unsigned int mach_msg_priority_t

macroMACH_MSG_PRIORITY_UNSPECIFIED

#define MACH_MSG_PRIORITY_UNSPECIFIED (mach_msg_priority_t) 0

typedefmach_msg_type_name_t

typedef unsigned int mach_msg_type_name_t

macroMACH_MSG_TYPE_MOVE_RECEIVE

#define MACH_MSG_TYPE_MOVE_RECEIVE 16
Must hold receive right

macroMACH_MSG_TYPE_MOVE_SEND

#define MACH_MSG_TYPE_MOVE_SEND 17
Must hold send right(s)

macroMACH_MSG_TYPE_MOVE_SEND_ONCE

#define MACH_MSG_TYPE_MOVE_SEND_ONCE 18
Must hold sendonce right

macroMACH_MSG_TYPE_COPY_SEND

#define MACH_MSG_TYPE_COPY_SEND 19
Must hold send right(s)

macroMACH_MSG_TYPE_MAKE_SEND

#define MACH_MSG_TYPE_MAKE_SEND 20
Must hold receive right

macroMACH_MSG_TYPE_MAKE_SEND_ONCE

#define MACH_MSG_TYPE_MAKE_SEND_ONCE 21
Must hold receive right

macroMACH_MSG_TYPE_COPY_RECEIVE

#define MACH_MSG_TYPE_COPY_RECEIVE 22
NOT VALID

macroMACH_MSG_TYPE_DISPOSE_RECEIVE

#define MACH_MSG_TYPE_DISPOSE_RECEIVE 24
must hold receive right

macroMACH_MSG_TYPE_DISPOSE_SEND

#define MACH_MSG_TYPE_DISPOSE_SEND 25
must hold send right(s)

macroMACH_MSG_TYPE_DISPOSE_SEND_ONCE

#define MACH_MSG_TYPE_DISPOSE_SEND_ONCE 26
must hold sendonce right

typedefmach_msg_copy_options_t

typedef unsigned int mach_msg_copy_options_t

macroMACH_MSG_PHYSICAL_COPY

#define MACH_MSG_PHYSICAL_COPY 0

macroMACH_MSG_VIRTUAL_COPY

#define MACH_MSG_VIRTUAL_COPY 1

macroMACH_MSG_ALLOCATE

#define MACH_MSG_ALLOCATE 2

macroMACH_MSG_OVERWRITE

#define MACH_MSG_OVERWRITE 3
deprecated

macroMACH_MSG_GUARD_FLAGS_NONE

#define MACH_MSG_GUARD_FLAGS_NONE 0x0000

macroMACH_MSG_GUARD_FLAGS_IMMOVABLE_RECEIVE

#define MACH_MSG_GUARD_FLAGS_IMMOVABLE_RECEIVE 0x0001
Move the receive right and mark it as immovable

macroMACH_MSG_GUARD_FLAGS_UNGUARDED_ON_SEND

#define MACH_MSG_GUARD_FLAGS_UNGUARDED_ON_SEND 0x0002
Verify that the port is unguarded

macroMACH_MSG_GUARD_FLAGS_MASK

#define MACH_MSG_GUARD_FLAGS_MASK 0x0003
Valid flag bits

typedefmach_msg_guard_flags_t

typedef unsigned int mach_msg_guard_flags_t

typedefmach_msg_descriptor_type_t

typedef unsigned int mach_msg_descriptor_type_t

macroMACH_MSG_PORT_DESCRIPTOR

#define MACH_MSG_PORT_DESCRIPTOR 0

macroMACH_MSG_OOL_DESCRIPTOR

#define MACH_MSG_OOL_DESCRIPTOR 1

macroMACH_MSG_OOL_PORTS_DESCRIPTOR

#define MACH_MSG_OOL_PORTS_DESCRIPTOR 2

macroMACH_MSG_OOL_VOLATILE_DESCRIPTOR

#define MACH_MSG_OOL_VOLATILE_DESCRIPTOR 3

macroMACH_MSG_GUARDED_PORT_DESCRIPTOR

#define MACH_MSG_GUARDED_PORT_DESCRIPTOR 4

macroMACH_MSG_DESCRIPTOR_MAX

#define MACH_MSG_DESCRIPTOR_MAX MACH_MSG_GUARDED_PORT_DESCRIPTOR

structmach_msg_type_descriptor_t

size 12, align 4
natural_tpad1
mach_msg_size_tpad2
unsigned int:24pad3
mach_msg_descriptor_type_t:8type

typedefmach_msg_type_descriptor_t

typedef struct mach_msg_type_descriptor_t mach_msg_type_descriptor_t;

structmach_msg_port_descriptor_t

size 12, align 4
mach_port_tname
mach_msg_size_tpad1
unsigned int:16pad2
mach_msg_type_name_t:8disposition
mach_msg_descriptor_type_t:8type

typedefmach_msg_port_descriptor_t

typedef struct mach_msg_port_descriptor_t mach_msg_port_descriptor_t;

structmach_msg_ool_descriptor32_t

size 12, align 4
uint32_taddress
mach_msg_size_tsize
boolean_t:8deallocate
mach_msg_copy_options_t:8copy
unsigned int:8pad1
mach_msg_descriptor_type_t:8type

typedefmach_msg_ool_descriptor32_t

typedef struct mach_msg_ool_descriptor32_t mach_msg_ool_descriptor32_t;

structmach_msg_ool_descriptor64_t

size 16, align 4
uint64_taddress
boolean_t:8deallocate
mach_msg_copy_options_t:8copy
unsigned int:8pad1
mach_msg_descriptor_type_t:8type
mach_msg_size_tsize

typedefmach_msg_ool_descriptor64_t

typedef struct mach_msg_ool_descriptor64_t mach_msg_ool_descriptor64_t;

structmach_msg_ool_descriptor_t

size 16, align 4
void *address
boolean_t:8deallocate
mach_msg_copy_options_t:8copy
unsigned int:8pad1
mach_msg_descriptor_type_t:8type
mach_msg_size_tsize

typedefmach_msg_ool_descriptor_t

typedef struct mach_msg_ool_descriptor_t mach_msg_ool_descriptor_t;

typedefmach_msg_ool_ports_descriptor32_t

typedef struct mach_msg_ool_ports_descriptor32_t mach_msg_ool_ports_descriptor32_t;

typedefmach_msg_ool_ports_descriptor64_t

typedef struct mach_msg_ool_ports_descriptor64_t mach_msg_ool_ports_descriptor64_t;

typedefmach_msg_ool_ports_descriptor_t

typedef struct mach_msg_ool_ports_descriptor_t mach_msg_ool_ports_descriptor_t;

typedefmach_msg_guarded_port_descriptor32_t

typedef struct mach_msg_guarded_port_descriptor32_t mach_msg_guarded_port_descriptor32_t;

typedefmach_msg_guarded_port_descriptor64_t

typedef struct mach_msg_guarded_port_descriptor64_t mach_msg_guarded_port_descriptor64_t;

typedefmach_msg_guarded_port_descriptor_t

typedef struct mach_msg_guarded_port_descriptor_t mach_msg_guarded_port_descriptor_t;

unionmach_msg_descriptor_t

LP64support - This union definition is not really appropriate in LP64 mode because not all descriptors are of the same size in that environment.
size 16, align 4
mach_msg_port_descriptor_tport
mach_msg_ool_descriptor_tout_of_line
mach_msg_ool_ports_descriptor_tool_ports
mach_msg_type_descriptor_ttype
mach_msg_guarded_port_descriptor_tguarded_port

typedefmach_msg_descriptor_t

typedef union mach_msg_descriptor_t mach_msg_descriptor_t;

structmach_msg_body_t

size 4, align 4
mach_msg_size_tmsgh_descriptor_count

typedefmach_msg_body_t

typedef struct mach_msg_body_t mach_msg_body_t;

macroMACH_MSG_BODY_NULL

#define MACH_MSG_BODY_NULL ((mach_msg_body_t *) 0)

macroMACH_MSG_DESCRIPTOR_NULL

#define MACH_MSG_DESCRIPTOR_NULL ((mach_msg_descriptor_t *) 0)

structmach_msg_header_t

size 24, align 4
mach_msg_bits_tmsgh_bits
mach_msg_size_tmsgh_size
mach_port_tmsgh_remote_port
mach_port_tmsgh_local_port
mach_port_name_tmsgh_voucher_port
mach_msg_id_tmsgh_id

typedefmach_msg_header_t

typedef struct mach_msg_header_t mach_msg_header_t;

macromsgh_reserved

#define msgh_reserved msgh_voucher_port

macroMACH_MSG_NULL

#define MACH_MSG_NULL ((mach_msg_header_t *) 0)

structmach_msg_base_t

size 28, align 4
mach_msg_header_theader
mach_msg_body_tbody

typedefmach_msg_base_t

typedef struct mach_msg_base_t mach_msg_base_t;

typedefmach_msg_trailer_type_t

typedef unsigned int mach_msg_trailer_type_t

macroMACH_MSG_TRAILER_FORMAT_0

#define MACH_MSG_TRAILER_FORMAT_0 0

typedefmach_msg_trailer_size_t

typedef unsigned int mach_msg_trailer_size_t

typedefmach_msg_trailer_info_t

typedef char *mach_msg_trailer_info_t

structmach_msg_trailer_t

size 8, align 4
mach_msg_trailer_type_tmsgh_trailer_type
mach_msg_trailer_size_tmsgh_trailer_size

typedefmach_msg_trailer_t

typedef struct mach_msg_trailer_t mach_msg_trailer_t;

structmach_msg_seqno_trailer_t

The msgh_seqno field carries a sequence number associated with the received-from port. A port's sequence number is incremented every time a message is received from it and included in the received trailer to help put messages back in sequence if multiple threads receive and/or process received messages.
size 12, align 4
mach_msg_trailer_type_tmsgh_trailer_type
mach_msg_trailer_size_tmsgh_trailer_size
mach_port_seqno_tmsgh_seqno

typedefmach_msg_seqno_trailer_t

typedef struct mach_msg_seqno_trailer_t mach_msg_seqno_trailer_t;

structsecurity_token_t

size 8, align 4
unsigned int[2]val

typedefsecurity_token_t

typedef struct security_token_t security_token_t;

structmach_msg_security_trailer_t

size 20, align 4
mach_msg_trailer_type_tmsgh_trailer_type
mach_msg_trailer_size_tmsgh_trailer_size
mach_port_seqno_tmsgh_seqno
security_token_tmsgh_sender

typedefmach_msg_security_trailer_t

typedef struct mach_msg_security_trailer_t mach_msg_security_trailer_t;

structaudit_token_t

The audit token is an opaque token which identifies Mach tasks and senders of Mach messages as subjects to the BSM audit system. Only the appropriate BSM library routines should be used to interpret the contents of the audit token as the representation of the subject identity within the token may change over time.
size 32, align 4
unsigned int[8]val

typedefaudit_token_t

typedef struct audit_token_t audit_token_t;

macroINVALID_AUDIT_TOKEN_VALUE

Safe initializer for audit_token_t. Variables holding unset audit tokens should generally be initialized to INVALID_AUDIT_TOKEN_VALUE, to allow unset audit tokens be distinguished from the kernel's audit token, KERNEL_AUDIT_TOKEN_VALUE. It is `safe' in that it limits potential damage if such an unset audit token, or one of its fields, were ever to be interpreted as valid by mistake. Notably, the pid is outside of range of valid pids, and none of the fields correspond to privileged users or groups.
#define INVALID_AUDIT_TOKEN_VALUE {{
	UINT_MAX, UINT_MAX, UINT_MAX, UINT_MAX,
	UINT_MAX, UINT_MAX, UINT_MAX, UINT_MAX }}

structmach_msg_audit_trailer_t

size 52, align 4
mach_msg_trailer_type_tmsgh_trailer_type
mach_msg_trailer_size_tmsgh_trailer_size
mach_port_seqno_tmsgh_seqno
security_token_tmsgh_sender
audit_token_tmsgh_audit

typedefmach_msg_audit_trailer_t

typedef struct mach_msg_audit_trailer_t mach_msg_audit_trailer_t;

structmach_msg_context_trailer_t

size 60, align 4
mach_msg_trailer_type_tmsgh_trailer_type
mach_msg_trailer_size_tmsgh_trailer_size
mach_port_seqno_tmsgh_seqno
security_token_tmsgh_sender
audit_token_tmsgh_audit
mach_port_context_tmsgh_context

typedefmach_msg_context_trailer_t

typedef struct mach_msg_context_trailer_t mach_msg_context_trailer_t;

structmsg_labels_t

size 4, align 4
mach_port_name_tsender

typedefmsg_labels_t

typedef struct msg_labels_t msg_labels_t;

typedefmach_msg_filter_id

typedef int mach_msg_filter_id

macroMACH_MSG_FILTER_POLICY_ALLOW

#define MACH_MSG_FILTER_POLICY_ALLOW (mach_msg_filter_id)0

structmach_msg_mac_trailer_t

size 68, align 4
mach_msg_trailer_type_tmsgh_trailer_type
mach_msg_trailer_size_tmsgh_trailer_size
mach_port_seqno_tmsgh_seqno
security_token_tmsgh_sender
audit_token_tmsgh_audit
mach_port_context_tmsgh_context
mach_msg_filter_idmsgh_ad
msg_labels_tmsgh_labels

typedefmach_msg_mac_trailer_t

typedef struct mach_msg_mac_trailer_t mach_msg_mac_trailer_t;

macroMACH_MSG_TRAILER_MINIMUM_SIZE

#define MACH_MSG_TRAILER_MINIMUM_SIZE sizeof(mach_msg_trailer_t)

typedefmach_msg_max_trailer_t

typedef mach_msg_mac_trailer_t mach_msg_max_trailer_t

macroMAX_TRAILER_SIZE

#define MAX_TRAILER_SIZE ((mach_msg_size_t)sizeof(mach_msg_max_trailer_t))

typedefmach_msg_format_0_trailer_t

Legacy requirements keep us from ever updating these defines (even when the format_0 trailers gain new option data fields in the future). Therefore, they shouldn't be used going forward. Instead, the sizes should be compared against the specific element size requested using REQUESTED_TRAILER_SIZE.
typedef mach_msg_security_trailer_t mach_msg_format_0_trailer_t

macroMACH_MSG_TRAILER_FORMAT_0_SIZE

#define MACH_MSG_TRAILER_FORMAT_0_SIZE sizeof(mach_msg_format_0_trailer_t)

macroKERNEL_SECURITY_TOKEN_VALUE

#define KERNEL_SECURITY_TOKEN_VALUE { {0, 1} }

variableKERNEL_SECURITY_TOKEN

extern const security_token_t KERNEL_SECURITY_TOKEN

macroKERNEL_AUDIT_TOKEN_VALUE

#define KERNEL_AUDIT_TOKEN_VALUE { {0, 0, 0, 0, 0, 0, 0, 0} }

variableKERNEL_AUDIT_TOKEN

extern const audit_token_t KERNEL_AUDIT_TOKEN

typedefmach_msg_options_t

typedef integer_t mach_msg_options_t

macroMACH_MSG_HEADER_EMPTY

#define MACH_MSG_HEADER_EMPTY (mach_msg_header_t){ }

structmach_msg_empty_send_t

size 24, align 4
mach_msg_header_theader

typedefmach_msg_empty_send_t

typedef struct mach_msg_empty_send_t mach_msg_empty_send_t;

typedefmach_msg_empty_rcv_t

typedef struct mach_msg_empty_rcv_t mach_msg_empty_rcv_t;

typedefmach_msg_empty_t

typedef union mach_msg_empty_t mach_msg_empty_t;

macroround_msg

utility to round the message size - will become machine dependent
#define round_msg(x) (((mach_msg_size_t)(x) + sizeof (natural_t) - 1) &
	                        ~(sizeof (natural_t) - 1))

macroMACH_MSG_SIZE_MAX

There is no fixed upper bound to the size of Mach messages.
#define MACH_MSG_SIZE_MAX ((mach_msg_size_t) ~0)

macroMACH_MSG_SIZE_RELIABLE

But architectural limits of a given implementation, or temporal conditions may cause unpredictable send failures for messages larger than MACH_MSG_SIZE_RELIABLE. In either case, waiting for memory is [currently] outside the scope of send timeout values provided to IPC.
#define MACH_MSG_SIZE_RELIABLE ((mach_msg_size_t) 256 * 1024)

macroMACH_MSGH_KIND_NORMAL

Compatibility definitions, for code written when there was a msgh_kind instead of msgh_seqno.
#define MACH_MSGH_KIND_NORMAL 0x00000000

macroMACH_MSGH_KIND_NOTIFICATION

#define MACH_MSGH_KIND_NOTIFICATION 0x00000001

macromsgh_kind

#define msgh_kind msgh_seqno

macromach_msg_kind_t

#define mach_msg_kind_t mach_port_seqno_t

typedefmach_msg_type_size_t

typedef natural_t mach_msg_type_size_t

typedefmach_msg_type_number_t

typedef natural_t mach_msg_type_number_t

macroMACH_MSG_TYPE_PORT_NONE

#define MACH_MSG_TYPE_PORT_NONE 0

macroMACH_MSG_TYPE_PORT_NAME

#define MACH_MSG_TYPE_PORT_NAME 15

macroMACH_MSG_TYPE_PORT_RECEIVE

#define MACH_MSG_TYPE_PORT_RECEIVE MACH_MSG_TYPE_MOVE_RECEIVE

macroMACH_MSG_TYPE_PORT_SEND

#define MACH_MSG_TYPE_PORT_SEND MACH_MSG_TYPE_MOVE_SEND

macroMACH_MSG_TYPE_PORT_SEND_ONCE

#define MACH_MSG_TYPE_PORT_SEND_ONCE MACH_MSG_TYPE_MOVE_SEND_ONCE

macroMACH_MSG_TYPE_LAST

#define MACH_MSG_TYPE_LAST 22
Last assigned

macroMACH_MSG_TYPE_POLYMORPHIC

#define MACH_MSG_TYPE_POLYMORPHIC ((mach_msg_type_name_t) -1)

macroMACH_MSG_TYPE_PORT_ANY

#define MACH_MSG_TYPE_PORT_ANY(x) (((x) >= MACH_MSG_TYPE_MOVE_RECEIVE) &&
	 ((x) <= MACH_MSG_TYPE_MAKE_SEND_ONCE))

macroMACH_MSG_TYPE_PORT_ANY_SEND

#define MACH_MSG_TYPE_PORT_ANY_SEND(x) (((x) >= MACH_MSG_TYPE_MOVE_SEND) &&
	 ((x) <= MACH_MSG_TYPE_MAKE_SEND_ONCE))

macroMACH_MSG_TYPE_PORT_ANY_SEND_ONCE

#define MACH_MSG_TYPE_PORT_ANY_SEND_ONCE(x) (((x) == MACH_MSG_TYPE_MOVE_SEND_ONCE) ||
	 ((x) == MACH_MSG_TYPE_MAKE_SEND_ONCE))

macroMACH_MSG_TYPE_PORT_ANY_RIGHT

#define MACH_MSG_TYPE_PORT_ANY_RIGHT(x) (((x) >= MACH_MSG_TYPE_MOVE_RECEIVE) &&
	 ((x) <= MACH_MSG_TYPE_MOVE_SEND_ONCE))

typedefmach_msg_option_t

typedef integer_t mach_msg_option_t

macroMACH_MSG_OPTION_NONE

#define MACH_MSG_OPTION_NONE 0x00000000

macroMACH_SEND_MSG

#define MACH_SEND_MSG 0x00000001

macroMACH_RCV_MSG

#define MACH_RCV_MSG 0x00000002

macroMACH_RCV_LARGE

#define MACH_RCV_LARGE 0x00000004
report large message sizes

macroMACH_RCV_LARGE_IDENTITY

#define MACH_RCV_LARGE_IDENTITY 0x00000008
identify source of large messages

macroMACH_SEND_TIMEOUT

#define MACH_SEND_TIMEOUT 0x00000010
timeout value applies to send

macroMACH_SEND_OVERRIDE

#define MACH_SEND_OVERRIDE 0x00000020
priority override for send

macroMACH_SEND_INTERRUPT

#define MACH_SEND_INTERRUPT 0x00000040
don't restart interrupted sends

macroMACH_SEND_NOTIFY

#define MACH_SEND_NOTIFY 0x00000080
arm send-possible notify

macroMACH_SEND_ALWAYS

#define MACH_SEND_ALWAYS 0x00010000
ignore qlimits - kernel only

macroMACH_SEND_FILTER_NONFATAL

#define MACH_SEND_FILTER_NONFATAL 0x00010000
rejection by message filter should return failure - user only

macroMACH_SEND_TRAILER

#define MACH_SEND_TRAILER 0x00020000
sender-provided trailer

macroMACH_SEND_NOIMPORTANCE

#define MACH_SEND_NOIMPORTANCE 0x00040000
msg won't carry importance

macroMACH_SEND_NODENAP

#define MACH_SEND_NODENAP MACH_SEND_NOIMPORTANCE

macroMACH_SEND_IMPORTANCE

#define MACH_SEND_IMPORTANCE 0x00080000
msg carries importance - kernel only

macroMACH_SEND_SYNC_OVERRIDE

#define MACH_SEND_SYNC_OVERRIDE 0x00100000
msg should do sync IPC override (on legacy kernels)

macroMACH_SEND_PROPAGATE_QOS

#define MACH_SEND_PROPAGATE_QOS 0x00200000
IPC should propagate the caller's QoS

macroMACH_SEND_SYNC_USE_THRPRI

#define MACH_SEND_SYNC_USE_THRPRI MACH_SEND_PROPAGATE_QOS
obsolete name

macroMACH_SEND_KERNEL

#define MACH_SEND_KERNEL 0x00400000
full send from kernel space - kernel only

macroMACH_SEND_SYNC_BOOTSTRAP_CHECKIN

#define MACH_SEND_SYNC_BOOTSTRAP_CHECKIN 0x00800000
special reply port should boost thread doing sync bootstrap checkin

macroMACH_RCV_TIMEOUT

#define MACH_RCV_TIMEOUT 0x00000100
timeout value applies to receive

macroMACH_RCV_NOTIFY

#define MACH_RCV_NOTIFY 0x00000000
legacy name (value was: 0x00000200)

macroMACH_RCV_INTERRUPT

#define MACH_RCV_INTERRUPT 0x00000400
don't restart interrupted receive

macroMACH_RCV_VOUCHER

#define MACH_RCV_VOUCHER 0x00000800
willing to receive voucher port

macroMACH_RCV_OVERWRITE

#define MACH_RCV_OVERWRITE 0x00000000
scatter receive (deprecated)

macroMACH_RCV_GUARDED_DESC

#define MACH_RCV_GUARDED_DESC 0x00001000
Can receive new guarded descriptor

macroMACH_RCV_SYNC_WAIT

#define MACH_RCV_SYNC_WAIT 0x00004000
sync waiter waiting for rcv

macroMACH_RCV_SYNC_PEEK

#define MACH_RCV_SYNC_PEEK 0x00008000
sync waiter waiting to peek

macroMACH_MSG_STRICT_REPLY

#define MACH_MSG_STRICT_REPLY 0x00000200
Enforce specific properties about the reply port, and the context in which a thread replies to a message. This flag must be passed on both the SEND and RCV

macroMACH_RCV_TRAILER_NULL

NOTE: a 0x00------ RCV mask implies to ask for a MACH_MSG_TRAILER_FORMAT_0 with 0 Elements, which is equivalent to a mach_msg_trailer_t. XXXMAC: unlike the rest of the MACH_RCV_* flags, MACH_RCV_TRAILER_LABELS needs its own private bit since we only calculate its fields when absolutely required.
#define MACH_RCV_TRAILER_NULL 0

macroMACH_RCV_TRAILER_SEQNO

#define MACH_RCV_TRAILER_SEQNO 1

macroMACH_RCV_TRAILER_SENDER

#define MACH_RCV_TRAILER_SENDER 2

macroMACH_RCV_TRAILER_AUDIT

#define MACH_RCV_TRAILER_AUDIT 3

macroMACH_RCV_TRAILER_CTX

#define MACH_RCV_TRAILER_CTX 4

macroMACH_RCV_TRAILER_AV

#define MACH_RCV_TRAILER_AV 7

macroMACH_RCV_TRAILER_LABELS

#define MACH_RCV_TRAILER_LABELS 8

macroMACH_RCV_TRAILER_TYPE

#define MACH_RCV_TRAILER_TYPE(x) (((x) & 0xf) << 28)

macroMACH_RCV_TRAILER_ELEMENTS

#define MACH_RCV_TRAILER_ELEMENTS(x) (((x) & 0xf) << 24)

macroMACH_RCV_TRAILER_MASK

#define MACH_RCV_TRAILER_MASK ((0xf << 24))

macroGET_RCV_ELEMENTS

#define GET_RCV_ELEMENTS(y) (((y) >> 24) & 0xf)

macroREQUESTED_TRAILER_SIZE

#define REQUESTED_TRAILER_SIZE(y) REQUESTED_TRAILER_SIZE_NATIVE(y)

typedefmach_msg_return_t

typedef kern_return_t mach_msg_return_t

macroMACH_MSG_SUCCESS

#define MACH_MSG_SUCCESS 0x00000000

macroMACH_MSG_MASK

#define MACH_MSG_MASK 0x00003e00

macroMACH_MSG_IPC_SPACE

All special error code bits defined below.
#define MACH_MSG_IPC_SPACE 0x00002000

macroMACH_MSG_VM_SPACE

No room in IPC name space for another capability name.
#define MACH_MSG_VM_SPACE 0x00001000

macroMACH_MSG_IPC_KERNEL

No room in VM address space for out-of-line memory.
#define MACH_MSG_IPC_KERNEL 0x00000800

macroMACH_MSG_VM_KERNEL

Kernel resource shortage handling an IPC capability.
#define MACH_MSG_VM_KERNEL 0x00000400

macroMACH_SEND_IN_PROGRESS

#define MACH_SEND_IN_PROGRESS 0x10000001

macroMACH_SEND_INVALID_DATA

Thread is waiting to send. (Internal use only.)
#define MACH_SEND_INVALID_DATA 0x10000002

macroMACH_SEND_INVALID_DEST

Bogus in-line data.
#define MACH_SEND_INVALID_DEST 0x10000003

macroMACH_SEND_TIMED_OUT

Bogus destination port.
#define MACH_SEND_TIMED_OUT 0x10000004

macroMACH_SEND_INVALID_VOUCHER

Message not sent before timeout expired.
#define MACH_SEND_INVALID_VOUCHER 0x10000005

macroMACH_SEND_INTERRUPTED

Bogus voucher port.
#define MACH_SEND_INTERRUPTED 0x10000007

macroMACH_SEND_MSG_TOO_SMALL

Software interrupt.
#define MACH_SEND_MSG_TOO_SMALL 0x10000008

macroMACH_SEND_INVALID_REPLY

Data doesn't contain a complete message.
#define MACH_SEND_INVALID_REPLY 0x10000009

macroMACH_SEND_INVALID_RIGHT

Bogus reply port.
#define MACH_SEND_INVALID_RIGHT 0x1000000a

macroMACH_SEND_INVALID_NOTIFY

Bogus port rights in the message body.
#define MACH_SEND_INVALID_NOTIFY 0x1000000b

macroMACH_SEND_INVALID_MEMORY

Bogus notify port argument.
#define MACH_SEND_INVALID_MEMORY 0x1000000c

macroMACH_SEND_NO_BUFFER

Invalid out-of-line memory pointer.
#define MACH_SEND_NO_BUFFER 0x1000000d

macroMACH_SEND_TOO_LARGE

No message buffer is available.
#define MACH_SEND_TOO_LARGE 0x1000000e

macroMACH_SEND_INVALID_TYPE

Send is too large for port
#define MACH_SEND_INVALID_TYPE 0x1000000f

macroMACH_SEND_INVALID_HEADER

Invalid msg-type specification.
#define MACH_SEND_INVALID_HEADER 0x10000010

macroMACH_SEND_INVALID_TRAILER

A field in the header had a bad value.
#define MACH_SEND_INVALID_TRAILER 0x10000011

macroMACH_SEND_INVALID_CONTEXT

The trailer to be sent does not match kernel format.
#define MACH_SEND_INVALID_CONTEXT 0x10000012

macroMACH_SEND_INVALID_OPTIONS

The sending thread context did not match the context on the dest port
#define MACH_SEND_INVALID_OPTIONS 0x10000013

macroMACH_SEND_INVALID_RT_OOL_SIZE

Send options are invalid.
#define MACH_SEND_INVALID_RT_OOL_SIZE 0x10000015

macroMACH_SEND_NO_GRANT_DEST

compatibility: no longer a returned error
#define MACH_SEND_NO_GRANT_DEST 0x10000016

macroMACH_SEND_MSG_FILTERED

compatibility: no longer a returned error
#define MACH_SEND_MSG_FILTERED 0x10000017

macroMACH_SEND_AUX_TOO_SMALL

Message send was rejected by message filter
#define MACH_SEND_AUX_TOO_SMALL 0x10000018

macroMACH_SEND_AUX_TOO_LARGE

Message auxiliary data is too small
#define MACH_SEND_AUX_TOO_LARGE 0x10000019

macroMACH_RCV_IN_PROGRESS

#define MACH_RCV_IN_PROGRESS 0x10004001

macroMACH_RCV_INVALID_NAME

Thread is waiting for receive. (Internal use only.)
#define MACH_RCV_INVALID_NAME 0x10004002

macroMACH_RCV_TIMED_OUT

Bogus name for receive port/port-set.
#define MACH_RCV_TIMED_OUT 0x10004003

macroMACH_RCV_TOO_LARGE

Didn't get a message within the timeout value.
#define MACH_RCV_TOO_LARGE 0x10004004

macroMACH_RCV_INTERRUPTED

Message buffer is not large enough for inline data.
#define MACH_RCV_INTERRUPTED 0x10004005

macroMACH_RCV_PORT_CHANGED

Software interrupt.
#define MACH_RCV_PORT_CHANGED 0x10004006

macroMACH_RCV_INVALID_NOTIFY

compatibility: no longer a returned error
#define MACH_RCV_INVALID_NOTIFY 0x10004007

macroMACH_RCV_INVALID_DATA

Bogus notify port argument.
#define MACH_RCV_INVALID_DATA 0x10004008

macroMACH_RCV_PORT_DIED

Bogus message buffer for inline data.
#define MACH_RCV_PORT_DIED 0x10004009

macroMACH_RCV_IN_SET

Port/set was sent away/died during receive.
#define MACH_RCV_IN_SET 0x1000400a

macroMACH_RCV_HEADER_ERROR

compatibility: no longer a returned error
#define MACH_RCV_HEADER_ERROR 0x1000400b

macroMACH_RCV_BODY_ERROR

Error receiving message header. See special bits.
#define MACH_RCV_BODY_ERROR 0x1000400c

macroMACH_RCV_INVALID_TYPE

Error receiving message body. See special bits.
#define MACH_RCV_INVALID_TYPE 0x1000400d

macroMACH_RCV_SCATTER_SMALL

Invalid msg-type specification in scatter list.
#define MACH_RCV_SCATTER_SMALL 0x1000400e

macroMACH_RCV_INVALID_TRAILER

Out-of-line overwrite region is not large enough
#define MACH_RCV_INVALID_TRAILER 0x1000400f

macroMACH_RCV_IN_PROGRESS_TIMED

trailer type or number of trailer elements not supported
#define MACH_RCV_IN_PROGRESS_TIMED 0x10004011

macroMACH_RCV_INVALID_REPLY

Waiting for receive with timeout. (Internal use only.)
#define MACH_RCV_INVALID_REPLY 0x10004012

macroMACH_RCV_INVALID_ARGUMENTS

invalid reply port used in a STRICT_REPLY message
#define MACH_RCV_INVALID_ARGUMENTS 0x10004013

functionmach_msg_overwrite

__WATCHOS_PROHIBITED __TVOS_PROHIBITED
extern mach_msg_return_t mach_msg_overwrite(
	mach_msg_header_t *msg,
	mach_msg_option_t option,
	mach_msg_size_t send_size,
	mach_msg_size_t rcv_size,
	mach_port_name_t rcv_name,
	mach_msg_timeout_t timeout,
	mach_port_name_t notify,
	mach_msg_header_t *rcv_msg,
	mach_msg_size_t rcv_limit
)
Routine: mach_msg_overwrite Purpose: Send and/or receive a message. If the message operation is interrupted, and the user did not request an indication of that fact, then restart the appropriate parts of the operation silently (trap version does not restart). Distinct send and receive buffers may be specified. If no separate receive buffer is specified, the msg parameter will be used for both send and receive operations. In addition to a distinct receive buffer, that buffer may already contain scatter control information to direct the receiving of the message.

functionmach_msg

__WATCHOS_PROHIBITED __TVOS_PROHIBITED
extern mach_msg_return_t mach_msg(
	mach_msg_header_t *msg,
	mach_msg_option_t option,
	mach_msg_size_t send_size,
	mach_msg_size_t rcv_size,
	mach_port_name_t rcv_name,
	mach_msg_timeout_t timeout,
	mach_port_name_t notify
)
Routine: mach_msg Purpose: Send and/or receive a message. If the message operation is interrupted, and the user did not request an indication of that fact, then restart the appropriate parts of the operation silently (trap version does not restart).
CMU/MIT Mach reference · manual page · © Carnegie Mellon
Send and/or receive a message from the target port.
The mach_msg system call sends and receives Mach messages. Mach messages contain data, which can include port rights and addresses of large regions of memory. mach_msg uses the same buffer for sending and receiving a message; the other calls permit separate send and receive buffers (although they may be specified to be the same). If the option argument contains MACH_SEND_MSG, the call sends a message. The send_size argument specifies the size of the message buffer (header and body) to send. The msgh_remote_port field of the message header specifies the destination of the message. If the option argument contains MACH_RCV_MSG, it receives a message. The receive_limit argument specifies the size of a buffer that will receive the message; messages that are larger are not received. The receive_name argument specifies the port or port set from which to receive. If the option argument contains both MACH_SEND_MSG and MACH_RCV_MSG, then mach_msg does both send and receive operations (in that order). If the send operation encounters an error (any return code other than MACH_MSG_SUCCESS), the call returns immediately without attempting the receive operation. Semantically the combined call is equivalent to separate send and receive calls, but it saves a system call and enables other internal optimizations. If the option argument specifies neither MACH_SEND_MSG nor MACH_RCV_MSG, mach_msg does nothing. Some options, like MACH_SEND_TIMEOUT and MACH_RCV_TIMEOUT, share a supporting argument. If these options are used together, they make independent use of the supporting argument's value.
Notes. The Mach kernel provides message-oriented, capability-based inter-process communication. The inter-process communication (IPC) primitives efficiently support many different styles of interaction, including remote procedure calls, object-oriented distributed programming, streaming of data, and sending very large amounts of data.
Major Concepts
The IPC primitives operate on three abstractions: messages, ports, and port sets. User tasks access all other kernel services and abstractions via the IPC primitives. The message primitives let tasks send and receive messages. Tasks send messages to ports. Messages sent to a port are delivered reliably (messages may not be lost) and are received in the order in which they were sent via send rights by a given sending task (or a given kernel). (Messages sent to send-once rights are unordered.) Messages contain a fixed-size header and a variable-sized message body containing kernel and user data, and a variable-size trailer of kernel appended message attributes. The header describes the destination and the size of the message (header plus body). The message body contains descriptions of additional port rights to be transmitted, descriptions of "out-of-line" memory regions to be sent and a variable amount of user data, which typically includes type conversion information. The out-of-line memory regions (including out-of-line port arrays) are (typically) disjoint from the message body. The IPC implementation makes use of the VM system to efficiently transfer large amounts of data. The message can contain the addresses of regions of the sender's address space which should be transferred as part of the message. When a task receives a message containing such out-of-line regions of data, the data can appear in unused portions or overwrite an existing portion of the receiver's address space (depending on the requested receive options). Under favorable circumstances, the transmission of out-of-line data is optimized so that sender and receiver share the physical pages of data copy-on-write, and no actual data copy occurs unless the pages are written. Regions of memory up to 4 gigabytes may be sent in this manner. Ports hold a queue of messages. Tasks operate on a port to send and receive messages by exercising capabilities (rights) for the port. Multiple tasks can hold send rights for a port. Tasks can also hold send-once rights, which grant the ability to send a single message. Only one task can hold the receive capability (receive right) for a port. Port rights can be transferred between tasks via messages. The sender of a message can specify in the message that the message contains a port right. If a message contains a receive right for a port, the receive right is removed from the sender of the message and transferred to the receiver of the message. While the receive right is in transit, tasks holding send rights can still send messages to the port, and they are queued until a task acquires the receive right and uses it to receive the messages. Tasks can receive messages from ports and port sets. The port set abstraction allows a single thread to wait for a message from any of several ports. Tasks manipulate port sets with a port set name, which is taken from the same name space as are the port rights. The port-set name may not be transferred in a message. A port set holds receive rights, and a receive operation on a port set blocks waiting for a message sent to any of the constituent ports. A port may not be- long to more than one port set, and if a port is a member of a port set, the holder of the receive right can't receive directly from the port. Port rights are a secure, location-independent way of naming ports. The port queue is a protected data structure, only accessible via the kernel's exported message primitives. Rights are also protected by the kernel; there is no way for a malicious user task to guess a port's internal name and send a message to a port to which it shouldn't have access. Port rights do not carry any location in- formation. When a receive right for a port moves from task to task, and even between tasks on different machines, the send rights for the port remain unchanged and continue to function.
Port Rights
Each task has its own space of port rights. Port rights are named with positive (unsigned) integers. For all architectures, sizeof (mach_port_t) = sizeof (mach_port_name_t) = sizeof (void*) and so user space addresses may be used as port names, except for the reserved values MACH_PORT_NULL (0) and MACH_PORT_DEAD (all 1 bits). When the kernel chooses a name for a new right, however, it is free to pick any unused name (one which denotes no right) in the space. There are three basic kinds of rights: receive rights, send rights and send-once rights. A port name can name any of these types of rights, or name a port-set, be a dead name, or name nothing. Dead names are not capabilities. They act as place-holders to prevent a name from being otherwise used. A port is destroyed, or dies, when its receive right is de-allocated. When a port dies, send and send-once rights for the port turn into dead names. Any messages queued at the port are destroyed, which de-allocates the port rights and out-of-line memory in the messages. Each send-once right held by a task has a different name. In contrast, when a task holds send rights or a receive right for a port, the rights share a single name. Tasks may hold multiple user-references for send rights. When a task receives a send right which it already holds, the kernel increments the right's user-reference count. When a task de-allocates a send right, the kernel decrements its user-reference count, and the task only loses the send right when the count goes to zero. Send-once rights always have a user reference count of one. Tasks may hold multiple user references for dead names. Each send-once right generated guarantees the receipt of a single message, either a message sent to that send-once right or, if the send-once right is in any way destroyed, a send-once notification. A message can carry port rights; the msgh_remote or msgh_local fields in the message header or the disposition field in a message body descriptor specify the type of port right and how the port right is to be extracted from the caller. The values MACH_PORT_NULL and MACH_PORT_DEAD are valid in place of a port right in a message body. In a sent message, the following mach_msg_type_name_t values denote port rights: MACH_MSG_TYPE_MAKE_SEND The message will carry a send right, but the caller must supply a receive right. The send right is created from the receive right, and the receive right's make-send count is incremented. MACH_MSG_TYPE_COPY_SEND The message will carry a send right, and the caller must supply a send right. The user reference count for the supplied send right is not changed. The caller may also supply a dead name and the receiving task will get MACH_PORT_DEAD. MACH_MSG_TYPE_MOVE_SEND The message will carry a send right, and the caller must supply a send right. The user reference count for the supplied send right is decremented, and the right is destroyed if the count becomes zero. Unless a receive right remains, the name becomes available for recycling. The caller may also supply a dead name, which loses a user reference, and the receiving task will get MACH_PORT_DEAD. MACH_MSG_TYPE_MAKE_SEND_ONCE The message will carry a send-once right, but the caller must supply a receive right. The send-once right is created from the receive right. Note that send once rights can only be created from the receive right. MACH_MSG_TYPE_MOVE_SEND_ONCE The message will carry a send-once right, and the caller must supply a send-once right. The caller loses the supplied send-once right. The caller may also supply a dead name, which loses a user reference, and the receiving task will get MACH_PORT_DEAD. MACH_MSG_TYPE_MOVE_RECEIVE The message will carry a receive right, and the caller must supply a receive right. The caller loses the supplied receive right, but retains any send rights with the same name. The make-send count and sequence number of the receive right are reset to zero and no-more-senders notification requests are cancelled (with a send-once notification being sent to the no-more-senders notification right), but the port retains other attributes like queued messages and extant send and send-once rights. If a message carries a send or send-once right, and the port dies while the message is in transit, then the receiving task will get MACH_PORT_DEAD instead of a right. The following mach_msg_type_name_t values in a received message indicate that it carries port rights: MACH_MSG_TYPE_PORT_SEND This value is an alias for MACH_MSG_TYPE_MOVE_SEND. The message carried a send right. If the receiving task already has send and/ or receive rights for the port, then that name for the port will be reused. Otherwise, the right will have a new, previously unused, name. If the task already has send rights, it gains a user reference for the right (un- less this would cause the user-reference count to overflow). Otherwise, it acquires send rights, with a user-reference count of one. MACH_MSG_TYPE_PORT_SEND_ONCE This value is an alias for MACH_MSG_TYPE_MOVE_SEND_ONCE. The message carried a send-once right. The right will have a new, previously unused, name. MACH_MSG_TYPE_PORT_RECEIVE This value is an alias for MACH_MSG_TYPE_MOVE_RECEIVE. The message carried a receive right. If the receiving task already has send rights for the port, then that name for the port will be reused; otherwise, the right will have a new, previously unused name. It is also possible to send a (nearly unbounded) array of port rights "out-of-line". All of the rights named by the array must be of the same type. The array is physically copied with the message body proper. The array of port right (names) can be received by the receiver using the same options available for out-of-line data reception described below.
Memory
A message can contain one or more regions of the sender's address space which are to be transferred as part of the message. The message carries a logical copy of the memory. For this "out-of-line" memory, the kernel can copy the data or use virtual memory techniques to defer any actual page copies unless the sender or the receiver modifies the data, the physical pages remain shared. The sender of the message must explicitly request an out-of-line transfer. Such a region is described as an arbitrary region of the sender's address space. The sender always sees this memory as being copied to the receiver. For each region, the sender has a de-allocate option. If the option is set and the out-of-line memory region is not null, then the region is implicitly de-allocated from the sender, as if by vm_deallocate. In particular, the start address is truncated down and the end address rounded up so that every page overlapped by the memory region is de-allocated (thereby possibly de-allocating more memory than is effectively transmitted). The use of this option effectively changes the memory copy to a memory movement. Aside from possibly optimizing the sender's use of memory, the de-allocation option allows the kernel to more efficiently handle the transfer of memory. For each region, the sender has the choice of permitting the kernel to choose a transmission strategy or the choice of requiring physical copy: MACH_MSG_VIRTUAL_COPY In a sent message, this flag allows the kernel to choose any mechanism to transmit the data. For large regions, this involves constructing a virtual copy of the pages containing the region. The portion of the first page preceding the data and the portion of the last page following the data are not copied (and will appear as zero if the virtual copy is dynamically allocated in the receiver). In a received message, this flag indicates that the kernel transmitted a virtual copy. Access to the received memory may involve interactions with the memory manager managing the sender's original data. Integri- ty-conscious receivers should exercise caution when dealing with out- of-line memory from un-trustworthy sources. Receivers concerned about deterministic access time should also exercise caution. The dynamic allocation option guarantees that the virtual copy will not be di- rectly referenced during the act of receiving the message. MACH_MSG_PHYSICAL_COPY In a sent message, this flag requires that the kernel construct an actual copy of the memory (either into wired kernel memory or default memory managed space). There is a (fairly large) limit on the amount of data that can be physically copied in a message. Port arrays always assume this option when sent. In a received message, this flag indicates that the kernel did transmit a physical copy. The receiver has two options for the reception of out-of-line memory (or "out-of-line" port arrays): allocation and overwrite. In the absence of the MACH_RCV_OVERWRITE option, all out-of-line re- gions are dynamically allocated. Allocated out-of-line memory arrives somewhere in the receiver's address space as new memory. It has the same inheritance and protection attributes as newly vm_allocate'ed memory. The receiver has the responsibility of de-allocating (with vm_deallocate) the memory when it is no longer needed. If the message contains more than one region, each will be allocated its own region, not necessarily contiguously. If the sender's data was transmitted as a virtual copy the allocated region will have the same data alignment within the page; otherwise, the received data will appear starting at the beginning of a page. If the MACH_RCV_OVERWRITE option is set, the receiver can specify how each received region is to be processed (dynamically allocated as described above, or written over existing memory). With this option, the contents of the receive buffer (receive_msg) are examined by the kernel. The kernel scans the descriptors in the receive buffer "message" to determine how to handle each out-of-line region. (Note: whereas receive_limit is the maximum size of the receive buffer, receive_msg_size is the amount filled in with this "message".) The kernel uses each out-of-line data descriptor (in order) to specify the processing for each received data region in turn, each out-of-line port array descriptor is used correspondingly. (Intermingled port descriptors are ignored when matching descriptors between the incoming message and the receive buffer list.) The copy option in the matching descriptor specifies the processing: MACH_MSG_OVERWRITE This flag indicates that the region should write over a specified region of the receiver's address space, as indicated by the address and size/ count fields of the descriptor. The full range overwritten must already exist (be allocated or mapped) in the receiver's address space. Depending on the nature of the data transmission this overwrite may involve virtual memory manipulations or it may involve actual data copy. MACH_MSG_ALLOCATE This flag indicates that the region is to be dynamically allocated. No other descriptor values are relevant. If not enough descriptors appear in the receive buffer to describe all received regions, additional regions are dynamically allocated. If the receiver specifies more descriptors than there are regions in the received message, the additional descriptors are ignored (and do not appear in the final received message). Note that the receive buffer descriptors will be overwritten: The size fields in descriptors will be updated (when scanned, they specified the maximum sizes of regions, when received, they specify the actual sizes of received regions). The copy fields in descriptors will be updated (when scanned, they specified allocate versus overwrite, when received, they indicate whether the region was physically or virtually copied). The descriptors may appear in different positions (given intermingled port descriptors). Descriptors that were not used (because there were not that many received regions) will be discarded. Null out-of-line memory is legal. If the out-of-line region size is zero, then the region's specified address is ignored. A receive allocated null out-of-line memory region always has a zero address. Unaligned addresses and region sizes that are not page multiples are legal. A received message can also contain regions with unaligned addresses and sizes which are not multiples of the page size.
Message Send
The send operation queues a message to a port. The message carries a copy of the caller's data. After the send, the caller can freely modify the message buffer or the out-of-line memory regions and the message contents will remain unchanged. The message carries with it the security ID of the sender, which the receiver can request in the message trailer. Message delivery is reliable and sequenced. Reception of a message guarantees that all messages previously sent to the port by a single task (or a single kernel) via send rights have been received and that they are received in the order in which they were sent. Messages sent to send-once rights are unordered. If the destination port's queue is full, several things can happen. If the message is sent to a send-once right (msgh_remote_port carries a send-once right), then the kernel ignores the queue limit and delivers the message. Otherwise the caller blocks until there is room in the queue, unless the MACH_SEND_TIMEOUT option is used. If a port has several blocked senders, then any of them may queue the next message when space in the queue becomes available, with the proviso that a blocked sender will not be indefinitely starved. These options modify MACH_SEND_MSG. If MACH_SEND_MSG is not also specified, they are ignored. MACH_SEND_TIMEOUT The timeout argument should specify a maximum time (in milliseconds) for the call to block before giving up. If the message can't be queued before the timeout interval elapses, then the call returns MACH_SEND_TIMED_OUT. A zero timeout is legitimate. MACH_SEND_INTERRUPT If specified, the mach_msg call will return MACH_SEND_INTERRUPTED if a software interrupt aborts the call. Otherwise, the send operation will be retried. MACH_SEND_TRAILER If set, the kernel, instead of determining the message attributes itself, will accept a formatted message trailer from the sender. The supplied trailer must be of the latest version supported by the kernel, and must contain all message attributes defined by the kernel. Only tasks with a security ID of KERNEL_SECURITY_ID can use this option; the intended use of this option is in support of the Net Message server. The trailer must follow the message in memory as it would appear in a received message. (The send_size argument to mach_msg still indicates the size of the message proper, not including this trailer.) The queueing of a message carrying receive rights may create a circular loop of receive rights and messages, which can never be received. For example, a message carrying a receive right can be sent to that receive right. This situation is not an error, but the kernel will garbage-collect such loops, destroying the messages. Some return codes, like MACH_SEND_TIMED_OUT, imply that the message was almost sent, but could not be queued. In these situations, the kernel tries to return the message contents to the caller with a pseudo-receive operation. This prevents the loss of port rights or memory which only exist in the message, for example, a receive right which was moved into the message, or out-of-line memory sent with the de-allocate option. The intent of the pseudo-receive operation is to restore, as best as possible, the state prior to attempting the send. This involves restoring the port rights and out-of-line memory regions contained in the message. The port right names and out-of-line addresses in the message send buffer are updated to reflect the new values resulting from their effective reception. The pseudo-receive handles the des- tination and reply rights as any other rights; they are not reversed as is the appearance in a normal received message. Also, no trailer is appended to the message. After the pseudo-receive, the message is ready to be resent. If the message is not resent, note that out-of-line memory regions may have moved and some port rights may have changed names. Although unlikely, the pseudo-receive operation may encounter resource shortages. This is similar to a MACH_RCV_BODY_ERROR return code from a receive operation. When this happens, the normal send return codes are augmented with the MACH_MSG_IPC_SPACE, MACH_MSG_VM_SPACE, MACH_MSG_IPC_KERNEL and MACH_MSG_VM_KERNEL bits to indicate the nature of the resource shortage.
Message Receive
The receive operation de-queues a message from a port. The receiving task acquires the port rights and out-of-line memory regions carried in the message. The receive_name argument specifies a port or port set from which to receive. If a port is specified, the caller must possess the receive right for the port and the port must not be a member of a port set. If no message is present, the call blocks, subject to the MACH_RCV_TIMEOUT option. If a port set is specified, the call will receive a message sent to any of the member ports. It is permissible for the port set to have no member ports, and ports may be added and removed while a receive from the port set is in progress. The received message can come from any of the member ports which have messages, with the proviso that a member port with messages will not be indefinitely starved. The msgh_local_port field in the received message header specifies from which port in the port set the message came. The receive_limit argument specifies the size of the caller's message buffer (which must be big enough for the message header, body and trailer); the msgh_size field of the received message indicates the actual size of the received message header and body. The mach_msg call will not receive a message larger than receive_limit. Messages that are too large are destroyed, unless the MACH_RCV_LARGE option is used. Following the received data, at the next natural boundary, is a message trailer. The msgh_size field of the received message does not include the length of this trailer; the trailer's length is given by the msgh_trailer_size field within the trailer. The receiver of a message is given a choice as to what trailer format is desired, and, within that format, which of the leading trailer attributes are desired (that is, to get trailer element three, the receiver must also accept elements one and two). For any given trailer format (of which there is currently only one), the trailer is compatibly extended by adding additional elements to the end. Received messages are stamped (in the trailer) with a sequence number, taken from the port from which the message was received. (Messages received from a port set are stamped with a sequence number from the appropriate member port.) Newly created ports start with a zero sequence number, and the sequence number is reset to zero whenever the port's receive right moves between tasks. When a message is de-queued from the port, it is stamped with the port's sequence number and the port's sequence number is then incremented. (Note that this occurs whether or not the receiver requests the sequence number in the trail- er.) The de-queue and increment operations are atomic, so that multiple threads receiving messages from a port can use the msgh_seqno field to reconstruct the original order of the messages. The destination and reply ports are reversed in a received message header. The msgh_local_port field carries the name of the destination port, from which the message was received, and the msgh_remote_port field carries the reply port right. The bits in msgh_bits are also reversed. The MACH_MSGH_BITS_LOCAL bits have a value of MACH_MSG_TYPE_PORT_SEND_ONCE or MACH_MSG_TYPE_PORT_SEND depending on the type of right to which the message was sent. The MACH_MSGH_BITS_REMOTE bits describe the reply port right. A received message can contain port rights and out-of-line memory. The msgh_local_port field does not carry a port right; the act of receiving the message consumes the send or send-once right for the destination port. The msgh_remote_port field does carry a port right, and the message can carry additional port rights and memory if the MACH_MSGH_BITS_COMPLEX bit is set. Received port rights and memory should be consumed or de-allocated in some fashion. In almost all cases, msgh_local_port will specify the name of a receive right, either receive_name, or, if receive_name is a port set, a member of receive_name. If other threads are concurrently manipulating the receive right, the situation is more complicated. If the receive right is renamed during the call, then msgh_local_port specifies the right's new name. If the caller loses the receive right after the message was de-queued from it, then mach_msg will proceed instead of returning MACH_RCV_PORT_DIED. If the receive right was destroyed, then msgh_local_port specifies MACH_PORT_DEAD. If the receive right still exists, but isn't held by the caller, then msgh_local_port specifies MACH_PORT_NULL. The following options modify MACH_RCV_MSG. If MACH_RCV_MSG is not also specified, they are ignored. MACH_RCV_TIMEOUT The timeout argument should specify a maximum time (in milliseconds) for the call to block before giving up. If no message arrives before the timeout interval elapses, then the call returns MACH_RCV_TIMED_OUT. A zero timeout is legitimate. MACH_RCV_NOTIFY The notify argument should specify a receive right for a notify port. If receiving the reply port creates a new port right in the caller, then the notify port is used to request a dead-name notification for the new port right. MACH_RCV_INTERRUPT If specified, the mach_msg call will return MACH_RCV_INTERRUPTED if a software interrupt aborts the call. Otherwise, the receive operation will be retried. MACH_RCV_OVERWRITE If specified, the message buffer specified by receive_msg (or msg), of length receive_msg_size, will be scanned for out-of-line descriptors to specify the processing to be done when receiving out-of-line regions. This option is only allowed for mach_msg_overwrite. MACH_RCV_LARGE If the message is larger than receive_limit or an out-of-line region is larger than the size allowed by a corresponding receive descriptor (MACH_RCV_OVERWRITE), the message remains queued instead of being destroyed. If the header, trailer and body would not fit into receive_limit, only the message header (mach_msg_header) and trailer header (mach_msg_trailer) are returned with the actual size of the message returned in the msgh_size field, the actual size of the trailer returned in the msgh_trailer_size field and an error return value of MACH_RCV_TOO_LARGE. If receive_limit is sufficient but an out-of-line descriptor is not, the message header, trailer and body are received, with out-of-line descriptors set to indicate the nature and size of the out-of-line regions, with an error return of MACH_RCV_SCATTER_SMALL. No out-of-line regions or port rights (including the reply right) will be received. If this option is not specified, messages too large will be de-queued and then destroyed; the caller receives the message header, with all fields correct, including the destination port but excepting the reply port, which is MACH_PORT_NULL and an empty (no additional element) message trailer. MACH_RCV_TRAILER_TYPE(value) This macro encodes the type of trailer the kernel must return with the message. If the kernel does not recognize this type, it returns MACH_RCV_INVALID_TRAILER. Currently, only MACH_MSG_TRAILER_FORMAT_0 is supported. MACH_RCV_TRAILER_ELEMENTS(value) This macro encodes the number of trailer elements desired. If the ker- nel does not support this number for the requested trailer type, the kernel returns MACH_RCV_INVALID_TRAILER. Zero is a legal value. The following trailer elements are supported: MACH_RCV_TRAILER_SEQNO Returns the sequence number of the message relative to its port. This value is of type mach_port_seqno_t. MACH_RCV_TRAILER_SENDER Returns the security ID of the task that sent the message. This value is of type security_id_t. If a resource shortage prevents the reception of a port right, the port right is destroyed and the caller sees the name MACH_PORT_NULL. If a resource shortage prevents the reception of an out-of-line memory region, the region is destroyed and the caller sees a zero address. In addition, the corresponding element in the size array is set to zero. A task never receives port rights or memory for which it is not told. The MACH_RCV_HEADER_ERROR return code indicates a resource shortage in the reception of the message header. The reply port and all port rights and memory in the message are destroyed. The caller receives the message header with all fields correct except for the reply port. The MACH_RCV_BODY_ERROR return code indicates a resource shortage in the reception of the message body. The message header, including the reply port, is correct. The kernel attempts to transfer all port rights and memory regions in the body, and only destroys those that can't be transferred.
Atomicity
The mach_msg call handles port rights in the message header atomically. Out-of-line memory and port rights in the message body do not enjoy this atomicity guarantee. These elements may be processed front-to-back, back-to-front, in some random order, or even atomically. For example, consider sending a message with the destination port specified as MACH_MSG_TYPE_MOVE_SEND and the reply port specified as MACH_MSG_TYPE_COPY_SEND. The same send right, with one user-refer- ence, is supplied for both the msgh_remote_port and msgh_local_port fields. Because mach_msg processes the port rights atomically, this succeeds. If msgh_remote_port were processed before msgh_local_port, then mach_msg would return MACH_SEND_INVALID_REPLY in this situation. On the other hand, suppose the destination and reply port are both specified as MACH_MSG_TYPE_MOVE_SEND, and again the same send right with one user-reference is supplied for both. Now the send operation fails, but because it processes the rights atomically, mach_msg can return either MACH_SEND_INVALID_DEST or MACH_SEND_INVALID_REPLY. For example, consider receiving a message at the same time another thread is deallocating the destination receive right. Suppose the reply port field carries a send right for the destination port. If the de-allocation happens before the dequeuing, the receiver gets MACH_RCV_PORT_DIED. If the de-allocation happens after the receive, the msgh_local_port and the msgh_remote_port fields both specify the same right, which becomes a dead name when the receive right is de-allocated. If the de-allocation happens between the de-queue and the receive, the msgh_local_port and msgh_remote_port fields both specify MACH_PORT_DEAD. Because the rights are processed atomically, it is not possible for just one of the two fields to hold MACH_PORT_DEAD. The MACH_RCV_NOTIFY option provides a more likely example. Suppose a message carrying a send-once right reply port is received with MACH_RCV_NOTIFY at the same time the reply port is destroyed. If the reply port is destroyed first, then msgh_remote_port specifies MACH_PORT_DEAD and the kernel does not generate a dead-name notification. If the reply port is destroyed after it is received, then msgh_remote_port specifies a dead name for which the kernel generates a dead-name notification. Either the reply port is dead on arrival or notification is requested.
Implementation
mach_msg and mach_msg_overwrite are wrappers for a system call. They have the responsibility for repeating the interrupted system call.
Cautions. If MACH_RCV_TIMEOUT is used without MACH_RCV_INTERRUPT, then the timeout duration might not be accurate. When the call is interrupted and automatically retried, the original timeout is used. If interrupts occur frequently enough, the timeout interval might never expire. MACH_SEND_TIMEOUT without MACH_SEND_INTERRUPT suffers from the same problem.

functionmach_voucher_deallocate

__WATCHOS_PROHIBITED __TVOS_PROHIBITED
extern kern_return_t mach_voucher_deallocate(mach_port_name_t voucher)
Routine: mach_voucher_deallocate Purpose: Deallocate a mach voucher created or received in a message. Drops one (send right) reference to the voucher.