Documentation
¶
Overview ¶
Package xpc provides Go bindings for the XPC framework.
High-level Go bindings for the XPC framework.
The public API is centered on Listener, Session, and ReceivedMessage.
Notes ¶
- Dictionary-first messaging is always available: CallDictionary and NotifyDictionary send a Dictionary, and ReceivedMessage.Dictionary returns one.
- Typed payloads are supported through Call, Notify, Decode, Marshaler, and Unmarshaler.
- Swift members without a safe public C path are omitted and recorded in xpc.omissions.gen.go.
Code generated from Apple documentation. DO NOT EDIT.
Index ¶
- type CancellationHandler
- type Dictionary
- type Endpoint
- type IncomingDecision
- type IncomingSessionRequest
- func (r IncomingSessionRequest) Accept(handler MessageHandler, onCancel CancellationHandler) IncomingDecision
- func (r IncomingSessionRequest) AcceptSession(handler MessageHandler, onCancel CancellationHandler) (IncomingDecision, *Session)
- func (r IncomingSessionRequest) Handle() uintptr
- func (r IncomingSessionRequest) Reject(reason string) IncomingDecision
- type Listener
- type ListenerOptions
- type Marshaler
- type MessageHandler
- type PeerRequirement
- func NewEntitlementExistsRequirement(entitlement string) (*PeerRequirement, error)
- func NewEntitlementMatchesRequirement(entitlement string, value any) (*PeerRequirement, error)
- func NewLightweightCodeRequirement(lwcr Dictionary) (*PeerRequirement, error)
- func NewPlatformBinaryRequirement() (*PeerRequirement, error)
- func NewPlatformBinarySignedAsRequirement(signingIdentifier string) (*PeerRequirement, error)
- func NewSameTeamRequirement() (*PeerRequirement, error)
- func NewSameTeamSignedAsRequirement(signingIdentifier string) (*PeerRequirement, error)
- func PeerRequirementFromHandle(handle uintptr) *PeerRequirement
- type ReceivedMessage
- type RichError
- type Session
- func (s *Session) Activate() error
- func (s *Session) Call(ctx context.Context, msg any) (ReceivedMessage, error)
- func (s *Session) CallDictionary(ctx context.Context, msg Dictionary) (ReceivedMessage, error)
- func (s *Session) Cancel()
- func (s *Session) Handle() uintptr
- func (s *Session) Notify(msg any) error
- func (s *Session) NotifyDictionary(msg Dictionary) error
- func (s *Session) SetCancellationHandler(handler CancellationHandler) error
- func (s *Session) SetIncomingMessageHandler(handler MessageHandler) error
- func (s *Session) SetPeerRequirement(req *PeerRequirement) error
- func (s *Session) SetTargetQueue(queue dispatch.Queue) error
- type SessionOptions
- type UUID
- type Unmarshaler
- type Unsupported
- type Xpc_object_t
- type Xpc_type_t
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type CancellationHandler ¶
type CancellationHandler func(RichError)
type Dictionary ¶
type Endpoint ¶
type Endpoint struct {
// contains filtered or unexported fields
}
func EndpointFromHandle ¶
EndpointFromHandle wraps a borrowed XPC endpoint handle. The caller retains ownership; the wrapper never releases it.
type IncomingDecision ¶
type IncomingDecision struct {
// contains filtered or unexported fields
}
type IncomingSessionRequest ¶
type IncomingSessionRequest struct {
// contains filtered or unexported fields
}
func IncomingSessionRequestFromHandle ¶
func IncomingSessionRequestFromHandle(handle uintptr) IncomingSessionRequest
IncomingSessionRequestFromHandle wraps a borrowed XPC incoming-session peer handle. The caller retains ownership; the wrapper never releases it.
func (IncomingSessionRequest) Accept ¶
func (r IncomingSessionRequest) Accept(handler MessageHandler, onCancel CancellationHandler) IncomingDecision
func (IncomingSessionRequest) AcceptSession ¶
func (r IncomingSessionRequest) AcceptSession(handler MessageHandler, onCancel CancellationHandler) (IncomingDecision, *Session)
func (IncomingSessionRequest) Handle ¶
func (r IncomingSessionRequest) Handle() uintptr
Handle returns the underlying XPC incoming-session peer handle.
func (IncomingSessionRequest) Reject ¶
func (r IncomingSessionRequest) Reject(reason string) IncomingDecision
type Listener ¶
type Listener struct {
// contains filtered or unexported fields
}
func ListenerFromHandle ¶
ListenerFromHandle wraps a borrowed XPC listener handle. The caller retains ownership; the wrapper never releases it.
func NewAnonymousListener ¶
func NewAnonymousListener(opts ListenerOptions, incoming func(IncomingSessionRequest) IncomingDecision) *Listener
func NewServiceListener ¶
func NewServiceListener(service string, opts ListenerOptions, incoming func(IncomingSessionRequest) IncomingDecision) (*Listener, error)
type ListenerOptions ¶
type ListenerOptions struct {
Inactive bool
// ForceMach and ForceXPCService tell the runtime which kind of listener
// this is when the name alone does not determine it. A Mach service
// listener needs ForceMach and a MachServices entry in the job's
// launchd.plist.
ForceMach bool
ForceXPCService bool
Requirement *PeerRequirement
// TargetQueue is the dispatch queue session events are submitted onto.
// The zero Queue means no target queue, which libdispatch treats as its
// default target queue. Dispatch queues are process-lifetime objects
// (the dispatch package never releases one), which is what makes storing
// one here sound.
TargetQueue dispatch.Queue
}
type Marshaler ¶
type Marshaler interface {
MarshalXPC() (Dictionary, error)
}
type MessageHandler ¶
type MessageHandler func(ReceivedMessage) (any, error)
MessageHandler answers one incoming message. The returned value is encoded with the package wire format and sent as the reply. A non-nil error replies with Dictionary{"error": err.Error()}. Returning (nil, nil) declines to reply at all; to reply with an empty body, return Dictionary{}.
Exactly one reply is sent per invocation, by the runtime, after the handler returns. There is no way to reply twice, and no way to reply late.
type PeerRequirement ¶
type PeerRequirement struct {
// contains filtered or unexported fields
}
func NewEntitlementExistsRequirement ¶
func NewEntitlementExistsRequirement(entitlement string) (*PeerRequirement, error)
NewEntitlementExistsRequirement returns a requirement that the peer has the given entitlement. An empty entitlement is rejected.
func NewEntitlementMatchesRequirement ¶
func NewEntitlementMatchesRequirement(entitlement string, value any) (*PeerRequirement, error)
NewEntitlementMatchesRequirement returns a requirement that the peer has the given entitlement with a matching value. The value must be a bool, a string, or a signed integer that int64 represents exactly; Apple accepts exactly XPC_TYPE_BOOL, XPC_TYPE_STRING, and XPC_TYPE_INT64 for this call, so the general codec's wider surface is deliberately not used. Anything else is rejected with an error naming the value's type.
func NewLightweightCodeRequirement ¶
func NewLightweightCodeRequirement(lwcr Dictionary) (*PeerRequirement, error)
NewLightweightCodeRequirement returns a requirement that the peer satisfy the given lightweight code requirement dictionary. A nil lwcr is rejected. The temporary object built from the dictionary is released once the constructor returns.
func NewPlatformBinaryRequirement ¶
func NewPlatformBinaryRequirement() (*PeerRequirement, error)
NewPlatformBinaryRequirement returns a requirement that the peer be a platform binary. The signing identifier is not constrained further.
func NewPlatformBinarySignedAsRequirement ¶
func NewPlatformBinarySignedAsRequirement(signingIdentifier string) (*PeerRequirement, error)
NewPlatformBinarySignedAsRequirement returns a requirement that the peer be a platform binary signed with the given signing identifier. An empty signingIdentifier is rejected: the header's meaningful NULL case is expressed by NewPlatformBinaryRequirement, and an empty C string is not NULL.
func NewSameTeamRequirement ¶
func NewSameTeamRequirement() (*PeerRequirement, error)
NewSameTeamRequirement returns a requirement that the peer be signed with the same team identifier as the current process. The signing identifier is not constrained further.
func NewSameTeamSignedAsRequirement ¶
func NewSameTeamSignedAsRequirement(signingIdentifier string) (*PeerRequirement, error)
NewSameTeamSignedAsRequirement returns a requirement that the peer be signed with the same team identifier as the current process and with the given signing identifier. An empty signingIdentifier is rejected: the header's meaningful NULL case is expressed by NewSameTeamRequirement, and an empty C string is not NULL.
func PeerRequirementFromHandle ¶
func PeerRequirementFromHandle(handle uintptr) *PeerRequirement
PeerRequirementFromHandle is the deliberate exception to the borrowed-handle rule: it retains a nonzero handle and returns an owned reference that the caller must Close, exactly as if it had been built by one of the constructors. A zero handle returns nil. Supplying a handle the caller does not own, or one already released, is undefined behaviour at the C level.
func (*PeerRequirement) Close ¶
func (r *PeerRequirement) Close() error
Close releases the requirement's reference. It is safe to call twice: the first call releases, and a second call (or a call on an already-closed requirement) returns nil. The requirement must not be used after Close.
If xpc_release is unavailable Close cannot release the reference. It clears the handle anyway, so Close stays idempotent, and returns the availability error; the underlying reference is then leaked and there is no way to recover it. This is the only outcome that leaks, and it is reported rather than swallowed.
func (*PeerRequirement) Handle ¶
func (r *PeerRequirement) Handle() uintptr
Handle returns the underlying XPC peer requirement handle. The handle is borrowed: it is valid only until Close and reads as zero afterward.
type ReceivedMessage ¶
type ReceivedMessage struct {
// contains filtered or unexported fields
}
func ReceivedMessageFromHandle ¶
func ReceivedMessageFromHandle(handle uintptr) ReceivedMessage
ReceivedMessageFromHandle wraps a borrowed XPC message handle. The caller retains ownership; the wrapper never releases it.
func (ReceivedMessage) Decode ¶
func (m ReceivedMessage) Decode(dst any) error
func (ReceivedMessage) Dictionary ¶
func (m ReceivedMessage) Dictionary() Dictionary
Dictionary returns the message body. The returned map is a shallow copy, so the caller may modify its top-level keys.
A message delivered by this package (a reply from CallDictionary, or the argument to a MessageHandler) decodes its raw object at most once, however many times Dictionary is called: each decode costs a permanently registered callback block, so repeated calls would otherwise consume a bounded process resource. A message wrapped with ReceivedMessageFromHandle has no such cache and decodes on every call, because its handle belongs to the caller.
func (ReceivedMessage) Handle ¶
func (m ReceivedMessage) Handle() uintptr
Handle returns the underlying XPC message handle.
func (ReceivedMessage) SenderSatisfies ¶
func (m ReceivedMessage) SenderSatisfies(req *PeerRequirement) bool
type RichError ¶
type RichError struct {
// contains filtered or unexported fields
}
func RichErrorFromHandle ¶
RichErrorFromHandle wraps a borrowed XPC rich error handle. The caller retains ownership; the wrapper never releases it.
type Session ¶
type Session struct {
// contains filtered or unexported fields
}
func DialMachService ¶
func DialMachService(name string, opts SessionOptions) (*Session, error)
func DialXPCService ¶
func DialXPCService(name string, opts SessionOptions) (*Session, error)
func SessionFromHandle ¶
SessionFromHandle wraps a borrowed XPC session handle. The caller retains ownership; the wrapper never releases it. A session obtained this way has an unknowable lifecycle, so the inactive-only setters refuse it.
func (*Session) Call ¶
Call encodes msg with the package wire format, sends it, and waits for the peer's reply. See CallDictionary for what ctx does and does not do.
func (*Session) CallDictionary ¶
func (s *Session) CallDictionary(ctx context.Context, msg Dictionary) (ReceivedMessage, error)
CallDictionary sends msg and waits for the peer's reply.
libxpc has no per-message timeout and no per-message cancellation: none of the xpc_session_send_message* entry points takes a deadline, and xpc_session_cancel tears down the whole session rather than one call. ctx is therefore honoured on the caller's side only. If ctx ends first, CallDictionary returns ctx.Err(), but the peer keeps running the request and the pending reply context stays alive in libxpc until the reply arrives or the session is cancelled: a cancelled call costs one leaked reply slot.
If ctx cannot end (ctx.Done() == nil, as for context.Background), CallDictionary uses the cheaper blocking C send.
func (*Session) Cancel ¶
func (s *Session) Cancel()
Cancel cancels the session. Any in-flight message fails and the cancel handler runs. Cancel is idempotent and safe on a nil or already-cancelled session.
There is no reason string: xpc_session_cancel takes only the session, so a reason parameter would be accepted and discarded. Compare IncomingSessionRequest.Reject, which does carry a reason to the peer.
func (*Session) Notify ¶
Notify encodes msg with the package wire format and sends it without waiting for a reply. Delivery is not confirmed.
func (*Session) NotifyDictionary ¶
func (s *Session) NotifyDictionary(msg Dictionary) error
NotifyDictionary sends msg without waiting for a reply. It returns when the message has been handed to the transport; delivery is not confirmed.
func (*Session) SetCancellationHandler ¶
func (s *Session) SetCancellationHandler(handler CancellationHandler) error
func (*Session) SetIncomingMessageHandler ¶
func (s *Session) SetIncomingMessageHandler(handler MessageHandler) error
func (*Session) SetPeerRequirement ¶
func (s *Session) SetPeerRequirement(req *PeerRequirement) error
SetPeerRequirement installs a peer requirement on the session. The requirement must be installed while the session is inactive and at most once per session; installing on an active session, on a session created from a raw handle whose lifecycle is unknowable, or a second time is API misuse that traps the process in native code, so each is refused here before native code runs. The session does not retain the requirement beyond this call: XPC retains it on successful installation, so the caller may Close their reference immediately afterward.
func (*Session) SetTargetQueue ¶
SetTargetQueue replaces the session's target queue. It may be called more than once while the session is inactive; a zero queue restores libdispatch's default target queue. It refuses an active session and a handle-derived session before calling native code, both of which are API misuse.
type SessionOptions ¶
type SessionOptions struct {
Inactive bool
Privileged bool
Requirement *PeerRequirement
// TargetQueue is the dispatch queue session events are submitted onto.
// The zero Queue means no target queue, which libdispatch treats as its
// default target queue. Dispatch queues are process-lifetime objects
// (the dispatch package never releases one), which is what makes storing
// one here sound.
TargetQueue dispatch.Queue
}
type UUID ¶
type UUID [16]byte
UUID is an xpc_uuid_t, the 16 bytes exactly as they travel on the wire. It is a distinct type rather than [16]byte so that encoding can tell a UUID from a 16-element byte array, which XPC carries as data.
type Unmarshaler ¶
type Unmarshaler interface {
UnmarshalXPC(Dictionary) error
}
type Unsupported ¶
type Unsupported struct {
// Type is the XPC type name, as xpc_type_get_name reports it,
// for example "fd" or "shmem".
Type string
// Description is xpc_copy_description output. It is a debugging aid
// and nothing more; in particular a descriptor named here may already
// be closed by the time it is read.
Description string
}
Unsupported is an XPC value this package has no Go representation for.
It exists so that decoding is never silently lossy. XPC can carry file descriptors and shared memory regions, which are resources with a lifetime, and a Go value describing one is not one. Rather than return something that looks like ordinary data, decoding yields an Unsupported carrying the XPC type name and the description XPC itself prints.
Encoding an Unsupported is an error: it records what arrived, and cannot reconstitute it.
type Xpc_object_t ¶
type Xpc_object_t = objectivec.Object
Xpc_object_t is the Go spelling of the C xpc_object_t handle.
The cross-framework registry attributes xpc_object_t to this package, so every other framework resolves the C type to xpc.Xpc_object_t. Until this declaration existed that reference dangled, and each consumer silently degraded to unsafe.Pointer -- foundation.NSXPCCoder's encode and decode methods among them. The degradation left no trace to search for: the emitted output contained no occurrence of the missing name, so the only evidence was the absence of a symbol nobody knew to look for.
It is an objectivec.Object rather than an opaque pointer because XPC objects are Objective-C objects under the bridge. That keeps the handle typed for callers, and it keeps a non-Go address out of a slot the Go garbage collector would scan.
type Xpc_type_t ¶
type Xpc_type_t uintptr
Xpc_type_t is the Go spelling of the C xpc_type_t handle, which identifies an XPC object's type rather than holding one.
It is a uintptr rather than an objectivec.Object or an unsafe.Pointer because the value is an opaque descriptor and not a Go pointer: uintptr is the one spelling of the three that the Go garbage collector does not scan.