+<h2>mach_msg</h2>
+<hr>
+<p>
+<strong>System Trap</strong> / <strong>Function</strong> - Send and/or receive a message from the target port.
+<h3>SYNOPSIS</h3>
+<pre>
+<strong>mach_msg_return_t mach_msg</strong>
+ <strong>(mach_msg_header_t</strong> <var>msg</var>,
+ <strong>mach_msg_option_t</strong> <var>option</var>,
+ <strong>mach_msg_size_t</strong> <var>send_size</var>,
+ <strong>mach_msg_size_t</strong> <var>receive_limit</var>,
+ <strong>mach_port_t</strong> <var>receive_name</var>,
+ <strong>mach_msg_timeout_t</strong> <var>timeout</var>,
+ <strong>mach_port_t</strong> <var>notify</var><strong>);</strong>
+
+<strong>mach_msg_return_t mach_msg_overwrite</strong>
+ <strong>(mach_msg_header_t*</strong> <var>send_msg</var>,
+ <strong>mach_msg_option_t</strong> <var>option</var>,
+ <strong>mach_msg_size_t</strong> <var>send_size</var>,
+ <strong>mach_msg_size_t</strong> <var>receive_limit</var>,
+ <strong>mach_port_t</strong> <var>receive_name</var>,
+ <strong>mach_msg_timeout_t</strong> <var>timeout</var>,
+ <strong>mach_port_t</strong> <var>notify</var>,
+ <strong>mach_msg_header_t</strong> <var>*receive_msg</var>,
+ <strong>mach_msg_size_t</strong> <var>receive_msg_size</var><strong>);</strong>
+</pre>
+<h3>PARAMETERS</h3>
+<dl>
+<p>
+<dt> <var>msg</var>
+<dd>
+[pointer to in/out structure containing random and reply rights] A
+message buffer used by <strong>mach_msg</strong> both for send and receive. This must
+be naturally aligned.
+<p>
+<dt> <var>send_msg</var>
+<dd>
+[pointer to in structure containing random and reply rights] The mes-
+sage buffer to be sent. This must be naturally aligned.
+<p>
+<dt> <var>option</var>
+<dd>
+[in scalar] Message options are bit values, combined with bitwise-or.
+One or both of MACH_SEND_MSG and MACH_RCV_MSG should be used. Other
+options act as modifiers.
+<p>
+<dt> <var>send_size</var>
+<dd>
+[in scalar] When sending a message, specifies the size of the message
+buffer to be sent (the size of the header and body) in
+bytes. Otherwise zero should be supplied.
+<p>
+<dt> <var>receive_limit</var>
+<dd>
+[in scalar] When receiving a message, specifies the maximum size of
+the msg or receive_msg buffer in bytes. Otherwise zero should be sup-
+plied.
+<p>
+<dt> <var>receive_name</var>
+<dd>
+[in random right] When receiving a message, specifies the port or port
+set. Otherwise MACH_PORT_NULL should be supplied.
+<p>
+<dt> <var>timeout</var>
+<dd>
+[in scalar] When using the MACH_SEND_TIMEOUT and MACH_RCV_TIMEOUT
+options, specifies the time in milliseconds to wait before giving
+up. Otherwise MACH_MSG_TIMEOUT_NONE should be supplied.
+<p>
+<dt> <var>notify</var>
+<dd>
+[in notify receive right] When using the MACH_SEND_CANCEL and
+MACH_RCV_NOTIFY options, specifies the port used for the
+notification. Otherwise MACH_PORT_NULL should be supplied.
+<p>
+<dt> <var>receive_msg</var>
+<dd>
+[pointer to in/out structure] A message buffer into which a message
+(header and body) will be received. This must be naturally aligned. By
+default (<strong>mach_msg</strong>), any received message will overwrite the send
+message buffer. This buffer is in/out only if the MACH_RCV_OVERWRITE
+option is used; otherwise this buffer is out only.
+<p>
+<dt> <var>receive_msg_size</var>
+<dd>
+[in scalar] When using the MACH_RCV_OVERWRITE option, specifies the
+size (in bytes) of the receive "message" that is to be used by
+<strong>mach_msg</strong> to indicate the disposition of received out-of-line regions.
+</dl>
+<h3>DESCRIPTION</h3>
+<p>
+The <strong>mach_msg</strong> system call sends and receives Mach messages. Mach
+messages contain data, which can include port rights and addresses of
+large regions of memory. <strong>mach_msg</strong> 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 <var>send_size</var> 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.
+<p>
+If the option argument contains both MACH_SEND_MSG and MACH_RCV_MSG,
+then <strong>mach_msg</strong> 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, <strong>mach_msg</strong> 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.
+<h3>NOTES</h3>
+<p>
+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.
+<h4>Major Concepts</h4>
+<p>
+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.
+<p>
+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.)
+<p>
+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.
+<p>
+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.
+<p>
+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.
+<p>
+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.
+<p>
+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.
+<p>
+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.
+<h4>Port Rights</h4>
+<p>
+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.
+<p>
+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.
+<p>
+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.
+<p>
+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.
+<p>
+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.
+<p>
+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.
+<p>
+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.
+<p>
+In a sent message, the following mach_msg_type_name_t values denote
+port rights:
+<dl>
+<dt> MACH_MSG_TYPE_MAKE_SEND
+ <dd>
+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.
+<dt> MACH_MSG_TYPE_COPY_SEND
+ <dd>
+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.
+<dt> MACH_MSG_TYPE_MOVE_SEND
+ <dd>
+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.
+<dt> MACH_MSG_TYPE_MAKE_SEND_ONCE
+<dd>
+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.
+<dt> MACH_MSG_TYPE_MOVE_SEND_ONCE
+ <dd>
+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.
+<dt> MACH_MSG_TYPE_MOVE_RECEIVE
+ <dd>
+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.
+ </dl>
+ <p>
+The following mach_msg_type_name_t values in a received message
+indicate that it carries port rights:
+ <dl>
+<dt> MACH_MSG_TYPE_PORT_SEND
+ <dd>
+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.
+<dt> MACH_MSG_TYPE_PORT_SEND_ONCE
+ <dd>
+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.
+<dt> MACH_MSG_TYPE_PORT_RECEIVE
+ <dd>
+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.
+ </dl>
+ <p>
+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.
+<h4>Memory</h4>
+ <p>
+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.
+<p>
+ 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.
+<p>
+ 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.
+ <p>
+For each region, the sender has the choice of permitting the kernel to
+choose a transmission strategy or the choice of requiring physical
+copy:
+ <dl>
+<dt> MACH_MSG_VIRTUAL_COPY
+ <dd>
+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).
+ <p>
+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.
+<dt> MACH_MSG_PHYSICAL_COPY
+ <dd>
+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.
+ <p>
+In a received message, this flag indicates that the kernel did
+transmit a physical copy.
+ </dl>
+ <p>
+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.
+ <p>
+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.)
+<p>
+The copy option in the
+matching descriptor specifies the processing:
+ <dl>
+<dt> MACH_MSG_OVERWRITE
+ <dd>
+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.
+<dt> MACH_MSG_ALLOCATE
+ <dd>
+This flag indicates that the region is to be dynamically allocated. No
+other descriptor values are relevant.
+ </dl>
+ <p>
+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).
+ <p>
+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.
+ <p>
+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.
+<h4>Message Send</h4>
+ <p>
+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.
+ <p>
+The message carries with it the security ID of the sender, which the
+receiver can request in the message trailer.
+ <p>
+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.
+ <p>
+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.
+<dl>
+<dt> MACH_SEND_TIMEOUT
+ <dd>
+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.
+<dt> MACH_SEND_INTERRUPT
+ <dd>
+If specified, the <strong>mach_msg</strong> call will return
+MACH_SEND_INTERRUPTED if a software interrupt aborts the call.
+Otherwise, the send operation will be retried.
+<dt> MACH_SEND_TRAILER
+ <dd>
+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
+<strong>mach_msg</strong> still indicates the size of the message proper, not including
+this trailer.)
+ </dl>
+ <p>
+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.
+ <p>
+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.
+ <p>
+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.
+<h4>Message Receive</h4>
+ <p>
+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.
+<p>
+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.
+<p>
+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 <strong>mach_msg</strong> 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.
+<p>
+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.
+<p>
+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.
+<p>
+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.
+<p>
+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 <strong>mach_msg</strong> 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.
+<p>
+The following options modify MACH_RCV_MSG. If MACH_RCV_MSG is not also
+specified, they are ignored.
+<dl>
+<dt> MACH_RCV_TIMEOUT
+ <dd>
+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.
+<dt> MACH_RCV_NOTIFY
+ <dd>
+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.
+<dt> MACH_RCV_INTERRUPT
+ <dd>
+If specified, the <strong>mach_msg</strong> call will return MACH_RCV_INTERRUPTED if a
+software interrupt aborts the call. Otherwise, the receive operation
+will be retried.
+<dt> MACH_RCV_OVERWRITE
+ <dd>
+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 <strong>mach_msg_overwrite</strong>.
+<dt> MACH_RCV_LARGE
+ <dd>
+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.
+<dt> MACH_RCV_TRAILER_TYPE(value)
+ <dd>
+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.
+<dt> MACH_RCV_TRAILER_ELEMENTS(value)
+ <dd>
+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.
+ </dl>
+ <p>
+ The following trailer elements are supported:
+ <dl>
+<dt> MACH_RCV_TRAILER_SEQNO
+ <dd>
+Returns the sequence number of the message relative to its port. This
+value is of type mach_port_seqno_t.
+<dt> MACH_RCV_TRAILER_SENDER
+ <dd>
+Returns the security ID of the task that sent the message. This value
+is of type security_id_t.
+ </dl>
+ <p>
+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.
+ <p>
+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.
+ <p>
+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.
+<h4>Atomicity</h4>
+ <p>
+The <strong>mach_msg</strong> 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.
+ <p>
+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 <strong>mach_msg</strong> processes the port rights atomically, this
+succeeds. If msgh_remote_port were processed before msgh_local_port,
+then <strong>mach_msg</strong> would return MACH_SEND_INVALID_REPLY in this situation.
+ <p>
+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, <strong>mach_msg</strong> can
+return either MACH_SEND_INVALID_DEST or MACH_SEND_INVALID_REPLY.
+<p>
+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.
+<p>
+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.
+<h4>Implementation</h4>
+<p>
+<strong>mach_msg</strong> and <strong>mach_msg_overwrite</strong> are wrappers for a system call. They
+have the responsibility for repeating the interrupted system call.
+<h3>CAUTIONS</h3>
+<p>
+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.
+<h3>RETURN VALUES</h3>
+<p>
+The send operation can generate the following return codes. These
+return codes imply that the call did nothing:
+<dl>
+<p>
+<dt> MACH_SEND_MSG_TOO_SMALL
+ <dd>
+The specified send_size was smaller than the minimum size for a
+message.
+<p>
+<dt> MACH_SEND_NO_BUFFER
+ <dd>
+A resource shortage prevented the kernel from allocating a message
+buffer.
+<p>
+<dt> MACH_SEND_INVALID_DATA
+ <dd>
+The supplied message buffer was not readable.
+<p>
+<dt> MACH_SEND_INVALID_HEADER
+ <dd>
+The msgh_bits value was invalid.
+<p>
+<dt> MACH_SEND_INVALID_DEST
+ <dd>
+The msgh_remote_port value was invalid.
+<p>
+<dt> MACH_SEND_INVALID_NOTIFY
+ <dd>
+When using MACH_SEND_CANCEL, the notify argument did not
+denote a valid receive right.
+<p>
+<dt> MACH_SEND_INVALID_REPLY
+ <dd>
+The msgh_local_port value was invalid.
+<p>
+<dt> MACH_SEND_INVALID_TRAILER
+ <dd>
+The trailer to be sent does not correspond to the current kernel format,
+or the sending task does not have the privilege to supply the message
+attributes.
+ </dl>
+ <p>
+These return codes imply that some or all of the message was destroyed:
+ <dl>
+<p>
+<dt> MACH_SEND_INVALID_MEMORY
+ <dd>
+The message body specified out-of-line data that was not readable.
+<p>
+<dt> MACH_SEND_INVALID_RIGHT
+ <dd>
+The message body specified a port right which the caller didn't possess.
+<p>
+<dt> MACH_SEND_INVALID_TYPE
+ <dd>
+A kernel processed descriptor was invalid.
+<p>
+<dt> MACH_SEND_MSG_TOO_SMALL
+ <dd>
+The last data item in the message ran over the end of the message.
+ </dl>
+ <p>
+These return codes imply that the message was returned to the caller with a
+pseudo-receive operation:
+ <dl>
+<p>
+<dt> MACH_SEND_TIMED_OUT
+ <dd>
+The timeout interval expired.
+<p>
+<dt> MACH_SEND_INTERRUPTED
+ <dd>
+A software interrupt occurred.
+ </dl>
+ <p>
+This return code implies that the message was queued:
+ <dl>
+<p>
+<dt> MACH_MSG_SUCCESS
+ <dd>
+The message was queued.
+ </dl>
+ <p>
+The receive operation can generate the following return codes. These return
+codes imply that the call did not de-queue a message:
+ <dl>
+<p>
+<dt> MACH_RCV_INVALID_NAME
+ <dd>
+The specified receive_name was invalid.
+<p>
+<dt> MACH_RCV_IN_SET
+ <dd>
+The specified port was a member of a port set.
+<p>
+<dt> MACH_RCV_TIMED_OUT
+ <dd>
+The timeout interval expired.
+<p>
+<dt> MACH_RCV_INTERRUPTED
+ <dd>
+A software interrupt occurred.
+<p>
+<dt> MACH_RCV_PORT_DIED
+ <dd>
+The caller lost the rights specified by receive_name.
+<p>
+<dt> MACH_RCV_PORT_CHANGED
+ <dd>
+receive_name specified a receive right which was moved into a port set
+during the call.
+<p>
+<dt> MACH_RCV_TOO_LARGE
+ <dd>
+When using MACH_RCV_LARGE, the message was larger than
+receive_limit. The message is left queued, and its actual size is
+returned in the message header/message body.
+<p>
+<dt> MACH_RCV_SCATTER_SMALL
+ <dd>
+When using MACH_RCV_LARGE with MACH_RCV_OVERWRITE, one or more scatter
+list descriptors specified an overwrite region smaller than the
+corresponding incoming region. The message is left queued, and the
+proper descriptors are returned in the message header/message body.
+<p>
+<dt> MACH_RCV_INVALID_TRAILER
+ <dd>
+The trailer type desired, or the number of trailer elements desired, is
+not supported by the kernel.
+ </dl>
+ <p>
+These return codes imply that a message was de-queued and destroyed:
+ <dl>
+<p>
+<dt> MACH_RCV_HEADER_ERROR
+ <dd>
+A resource shortage prevented the reception of the port rights in the
+message header.
+<p>
+<dt> MACH_RCV_INVALID_NOTIFY
+ <dd>
+When using MACH_RCV_NOTIFY, the notify argument did not denote a
+valid receive right.
+<p>
+<dt> MACH_RCV_INVALID_DATA
+ <dd>
+The specified message buffer was not writable.
+<p>
+<dt> MACH_RCV_TOO_LARGE
+ <dd>
+When not using MACH_RCV_LARGE, a message larger than
+receive_limit was de-queued and destroyed.
+<p>
+<dt> MACH_RCV_SCATTER_SMALL
+ <dd>
+When not using MACH_RCV_LARGE with MACH_RCV_OVERWRITE, one or more
+scatter list descriptors specified an overwrite region smaller than
+the corresponding incoming region. The message was de-queued and
+destroyed.
+<p>
+<dt> MACH_RCV_OVERWRITE_ERROR
+ <dd>
+A region specified by a receive overwrite descriptor
+(MACH_RCV_OVERWRITE) was not allocated or could not be written.
+<p>
+<dt> MACH_RCV_INVALID_TYPE
+ <dd>
+When using MACH_RCV_OVERWRITE, one or more scatter list descriptors
+did not have the type matching the corresponding incoming message
+descriptor or had an invalid copy (disposition) field.
+<p>
+<dt> MACH_RCV_LIMITS
+ <dd>
+The combined size of all out-of-line memory regions or the total num-
+ber of port rights in the message exceeds the limit set for the port.
+These return codes imply that a message was received:
+<p>
+<dt> MACH_RCV_BODY_ERROR
+ <dd>
+A resource shortage prevented the reception of a port right or out-of-
+line memory region in the message body.
+<p>
+<dt> MACH_MSG_SUCCESS
+ <dd>
+A message was received.
+ </dl>
+ <p>
+Resource shortages can occur after a message is de-queued, while
+transferring port rights and out-of-line memory regions to the
+receiving task. The <strong>mach_msg</strong> call returns MACH_RCV_HEADER_ERROR or
+MACH_RCV_BODY_ERROR in this situation. These return codes always carry
+ extra bits (bitwise-or'ed) that indicate the nature of the resource
+shortage:
+ <dl>
+<p>
+<dt> MACH_MSG_IPC_SPACE
+ <dd>
+There was no room in the task's IPC name space for another port name.
+<p>
+<dt> MACH_MSG_VM_SPACE
+ <dd>
+There was no room in the task's VM address space for an out-of-line
+memory region.
+<p>
+<dt> MACH_MSG_IPC_KERNEL
+ <dd>
+A kernel resource shortage prevented the reception of a port right.
+<p>
+<dt> MACH_MSG_VM_KERNEL
+ <dd>
+A kernel resource shortage prevented the reception of an out-of-line
+memory region.
+</dl>
+<h3>RELATED INFORMATION</h3>
+<p>
+Functions:
+<a href="vm_allocate.html"><strong>vm_allocate</strong></a>,
+<a href="vm_deallocate.html"><strong>vm_deallocate</strong></a>,
+<a href="vm_write.html"><strong>vm_write</strong></a>,
+<a href="MP_request_notification.html"><strong>mach_port_request_notification</strong></a>,
+<p>
+Data Structures:
+mach_msg_header.