xpc

package
v0.6.18 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 22, 2026 License: MIT Imports: 16 Imported by: 0

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

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 Dictionary map[string]any

type Endpoint

type Endpoint struct {
	// contains filtered or unexported fields
}

func EndpointFromHandle

func EndpointFromHandle(handle uintptr) Endpoint

EndpointFromHandle wraps a borrowed XPC endpoint handle. The caller retains ownership; the wrapper never releases it.

func (Endpoint) Handle

func (e Endpoint) Handle() uintptr

Handle returns the underlying XPC endpoint handle.

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 (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

type Listener

type Listener struct {
	// contains filtered or unexported fields
}

func ListenerFromHandle

func ListenerFromHandle(handle uintptr) *Listener

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)

func (*Listener) Activate

func (l *Listener) Activate() error

func (*Listener) Cancel

func (l *Listener) Cancel()

func (*Listener) Handle

func (l *Listener) Handle() uintptr

Handle returns the underlying XPC listener handle.

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

func RichErrorFromHandle(handle uintptr) RichError

RichErrorFromHandle wraps a borrowed XPC rich error handle. The caller retains ownership; the wrapper never releases it.

func (RichError) CanRetry

func (e RichError) CanRetry() bool

func (RichError) Error

func (e RichError) Error() string

func (RichError) Handle

func (e RichError) Handle() uintptr

Handle returns the underlying XPC rich error handle.

func (RichError) Unwrap

func (e RichError) Unwrap() error

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

func SessionFromHandle(handle uintptr) *Session

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) Activate

func (s *Session) Activate() error

func (*Session) Call

func (s *Session) Call(ctx context.Context, msg any) (ReceivedMessage, error)

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) Handle

func (s *Session) Handle() uintptr

Handle returns the underlying XPC session handle.

func (*Session) Notify

func (s *Session) Notify(msg any) error

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

func (s *Session) SetTargetQueue(queue dispatch.Queue) error

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL