Description
Transfers one shared-memory capability over an already connected Unix- domain socket using SCM_RIGHTS. Send and Receive use synchronous sendmsg and recvmsg calls and may block. Call them from a native task unless the application has independently established nonblocking readiness; this package does not hide socket work on an event-loop pthread.
Adopt
procedure Adopt
(Item : in out Handoff_Channel; Socket : in out Socket_Descriptor; Trust : Peer_Trust := Trusted_Peer)
Transfer a connected AF_UNIX SOCK_STREAM descriptor into Item. The descriptor receives FD_CLOEXEC and Darwin SO_NOSIGPIPE before adoption. Socket becomes invalid after success. Untrusted_Peer is rejected on Darwin because truncated SCM_RIGHTS delivery can leak descriptors that XNU installed but did not expose in the returned control buffer. Linux can request close-on-exec atomically during receive. Darwin must set it immediately afterward, so applications must also obey Flyology's rule forbidding a non-exec fork child after Ada tasking has started.
Parameters
- Item
Closed channel that receives sole endpoint ownership
- Socket
Connected socket descriptor transferred on success
- Trust
Peer trust policy for descriptor and truncation behavior
Raised exceptions
- Validation_Error
Item is already open or Socket is invalid
- Security_Error
Untrusted ancillary receipt is not supported
- Protocol_Error
Socket is not connected AF_UNIX SOCK_STREAM
- Operating_System_Error
Descriptor inspection or setup fails
Channel_Busy
Channel_Busy : exception;
Raised when another native task is already operating on the same owned handoff channel. Operations never wait for the channel guard.
Close
procedure Close (Item : in out Handoff_Channel)
Explicitly close Item. This operation is idempotent and a non-raising finalization fallback also closes an owned endpoint.
Parameters
- Item
Channel owner to close
Raised exceptions
- Channel_Busy
Another native task is using Item
- Operating_System_Error
close reports an error
Handoff_Channel
type Handoff_Channel is limited private;
Limited owner of a dedicated connected AF_UNIX SOCK_STREAM endpoint. The endpoint admits only Flyology's one-byte, one-descriptor protocol, serializes each Send or Receive attempt without waiting, and becomes permanently poisoned and closed after a protocol, validation, security, or transport failure. No other read, recv, recvmsg, send, or sendmsg may use the endpoint or any duplicate while it is owned by this object.
Is_Open
function Is_Open (Item : Handoff_Channel) return Boolean
Report whether Item owns a usable or currently busy endpoint.
Parameters
- Item
Channel to inspect
Return value
True before explicit close or poisoning
Is_Poisoned
function Is_Poisoned (Item : Handoff_Channel) return Boolean
Report whether a failed operation permanently retired Item.
Parameters
- Item
Channel to inspect
Return value
True only after fail-closed channel poisoning
Peer_Trust
type Peer_Trust is (Trusted_Peer, Untrusted_Peer);
Trust assigned to the peer that supplied a handoff socket.
Enumeration literals
- Trusted_Peer
The application authenticates and trusts the peer not to exploit platform ancillary-data, shared open-file-description, or backing-resize behavior; this setting does not authenticate it
- Untrusted_Peer
Require the platform to provide bounded ancillary descriptor cleanup; currently available only on Linux
Protocol_Error
Protocol_Error : exception;
Raised when the carrier byte, ancillary layout, descriptor count, or socket kind violates the one-descriptor handoff protocol. A raw socket must be retired after this exception. An owned Handoff_Channel poisons and closes itself before propagating it.
Receive
procedure Receive
(Channel : in out Handoff_Channel;
Expected_Length : Byte_Length;
Item : in out Backing_Object;
Require_Immutable_Size : Boolean := False)
Receive exactly one descriptor through an owned dedicated channel. Trusted channels apply the caller's immutable-size choice. Untrusted channels always require Linux immutable size seals, preventing a peer that retains a duplicate from shrinking the mapped object and causing SIGBUS. Only writable exact-size regular or POSIX-shm backing objects are accepted, so pipe, socket, and mutable-status-flag hazards do not enter the mapping API. Any failure after channel input begins poisons and closes Channel after closing every descriptor visible to user space.
Parameters
- Channel
Dedicated channel owner
- Expected_Length
Exact positive backing length selected locally
- Item
Closed owner that receives one validated descriptor
- Require_Immutable_Size
Require Linux size seals for a trusted peer
Raised exceptions
- Channel_Busy
Another native task is using Channel
- Constraint_Error
Expected_Length is zero or not native
- Validation_Error
Channel is closed, Item is open, or the received descriptor has the wrong type, access mode, or size
- Security_Error
Required seals or CLOEXEC are unavailable
- Protocol_Error
Carrier or ancillary data is invalid
- Operating_System_Error
recvmsg or inspection fails
Receive
procedure Receive
(Socket : Socket_Descriptor;
Expected_Length : Byte_Length;
Item : in out Backing_Object;
Require_Immutable_Size : Boolean := False)
Receive exactly one descriptor from a caller-owned raw socket, establish FD_CLOEXEC immediately, validate regular-file type and exact length, and optionally require immutable Linux size seals before adopting it into Item. Linux requests MSG_CMSG_CLOEXEC; Darwin applies FD_CLOEXEC before return. Malformed, missing, extra, or truncated ancillary data closes every descriptor exposed by the kernel and raises. Socket must be a dedicated externally serialized AF_UNIX SOCK_STREAM lane, and must be retired after every exception. Linux closes descriptors omitted by ancillary truncation; Darwin has a known XNU leak for omitted descriptors, so this raw operation must not accept an untrusted Darwin peer. A short read does not mean the stream is drained and no ordinary read may consume the carrier byte.
Parameters
- Socket
Connected Unix-domain socket
- Expected_Length
Required exact positive backing length
- Item
Closed owner that receives exactly one validated descriptor
- Require_Immutable_Size
Reject descriptors without Linux size seals; use False for Darwin anonymous, named, and file-backed objects
Raised exceptions
- Constraint_Error
Expected_Length is zero or not native
- Validation_Error
Item is open, Socket is invalid, or the received type or size does not match
- Security_Error
CLOEXEC or a required size seal is absent
- Protocol_Error
Carrier, ancillary data, or socket kind is invalid
- Operating_System_Error
recvmsg or descriptor inspection fails
Send
procedure Send
(Channel : in out Handoff_Channel; Item : in out Backing_Object; Ownership : Send_Ownership := Borrow)
Send exactly one backing descriptor through an owned dedicated channel. The operation fails immediately on concurrent channel use. A transport failure after channel acquisition poisons and closes the channel; Transfer consumes Item only after sendmsg accepts the carrier and descriptor locally. A later failure while closing a transferred backing object does not invalidate the accepted stream record.
Parameters
- Channel
Dedicated channel owner
- Item
Open backing object to borrow or transfer
- Ownership
Whether the sender retains descriptor ownership
Raised exceptions
- Channel_Busy
Another native task is using Channel
- Validation_Error
Channel or Item is closed
- Protocol_Error
Channel protocol validation fails
- Operating_System_Error
sendmsg or close fails
Send
procedure Send
(Socket : Socket_Descriptor; Item : in out Backing_Object; Ownership : Send_Ownership := Borrow)
Send exactly one backing descriptor over a caller-owned raw socket. The receiver obtains a new descriptor referring to the same open file description. Socket must be a dedicated connected AF_UNIX SOCK_STREAM lane used by no other reader or writer; serialize calls externally and retire the socket after any exception. The one nonzero carrier byte is what binds the SCM_RIGHTS control message to the stream. Send success means local kernel acceptance, not receiver validation or attachment.
Parameters
- Socket
Connected Unix-domain socket
- Item
Open backing object to borrow or transfer
- Ownership
Whether the sender retains descriptor ownership
Raised exceptions
- Validation_Error
Item is closed or Socket is invalid
- Protocol_Error
Socket is not connected AF_UNIX SOCK_STREAM
- Operating_System_Error
sendmsg or transfer close fails
Send_Ownership
type Send_Ownership is (Borrow, Transfer);
Local ownership behavior after a successful send.
Enumeration literals
- Borrow
Keep the sending Backing_Object open
- Transfer
Close the sending Backing_Object after sendmsg accepts the capability; any existing mappings remain live
Socket_Descriptor
type Socket_Descriptor is new Interfaces.C.int;
Connected Unix-domain socket descriptor supplied by the application.