[][src]Struct sunrise_libuser::ipc::Message

pub struct Message<'a, RAW, BUFF = [IPCBuffer<'a>; 0], COPY = [u32; 0], MOVE = [u32; 0]> where
    BUFF: Array<Item = IPCBuffer<'a>>,
    COPY: Array<Item = u32>,
    MOVE: Array<Item = u32>,
    RAW: Copy
{ ty: u16, pid: Option<u64>, buffers: ArrayVec<BUFF>, copy_handles: ArrayVec<COPY>, move_handles: ArrayVec<MOVE>, is_request: bool, cmdid_error: u32, token: Option<u32>, raw: Option<RAW>, }

A generic IPC message, representing either an IPC Request or an IPC Response.

In order to ensure performance, the request lives entirely on the stack, no heap allocation is done. However, if we allowed the maximum sizes for everything, this structure would be over-sized, spanning a page. In order to avoid this, we allow the user to set the size of the various parameters they need.

When sending a request that needs to send a COPY handle, the user is expected to create a message specifying the COPY count through the type argument, e.g.

use sunrise_libuser::ipc::Message;
let msg = Message::<(), [_; 0], [_; 1], [_; 0]>::new_request(None, 1);

The ugly syntax, while unfortunate, is a necessary evil until const generics happen.

Fields

ty: u16

Type of the message. This is derived from MessageTy and Message::token.

pid: Option<u64>

Optional PID included in the message. For outgoing messages, the actual value is not relevant, as the kernel will replace it with the sender's pid.

buffers: ArrayVec<BUFF>

Array of IPC Buffers included in the message.

The user may configure the size of this array in the type, allowing precise control over the size of the Message type.

copy_handles: ArrayVec<COPY>

Array of copy handles included in the message. Copy handles are copied from the sender's process into the receiver's process. The sender and receiver may both use their respective handles.

The user may configure the size of this array in the type, allowing precise control over the size of the Message type.

move_handles: ArrayVec<MOVE>

Array of move handles included in the message. Move handles are moved from the sender's process into the receiver's process. The sender loses control over the handle, as if it had been closed.

The user may configure the size of this array in the type, allowing precise control over the size of the Message type.

is_request: bool

Whether this message contains an IPC request or an IPC response.

cmdid_error: u32

Contains either the cmdid (if this message is a request) or an error number (if this message is a response).

token: Option<u32>

Optional tracking token. This is used to track the origin of each IPC call. Generally, the creating application will chose a random token when doing its request. Services will then use that token when they need to make their own requests.

raw: Option<RAW>

The raw arguments included in this message.

Implementations

impl<'a, RAW, BUFF, COPY, MOVE> Message<'a, RAW, BUFF, COPY, MOVE> where
    BUFF: Array<Item = IPCBuffer<'a>>,
    COPY: Array<Item = u32>,
    MOVE: Array<Item = u32>,
    RAW: Copy
[src]

pub fn new_request(
    token: Option<u32>,
    cmdid: u32
) -> Message<'a, RAW, BUFF, COPY, MOVE>
[src]

Create a new request for the given cmdid. If a token is passed, the new IPC version will be used. The tokens allow for tracking an IPC request chain. The raw data will contain the default value, and all arrays will be empty.

pub fn new_response(token: Option<u32>) -> Message<'a, RAW, BUFF, COPY, MOVE>[src]

Create a new empty reply. If the request this reply is created for had a token, it should be passed here. The raw data will contain the default value, and all arrays will be empty.

pub fn set_ty(&mut self, ty: MessageTy) -> &mut Self[src]

Sets the message type.

pub fn set_error(&mut self, err: u32) -> &mut Self[src]

Set the error code from a reply.

Panics

Panics if the message is a request.

pub fn error(&self) -> Result<(), Error>[src]

Get the error code from a reply.

Panics

Panics if the message is a request.

pub fn push_raw(&mut self, raw: RAW) -> &mut Self[src]

Sets the raw data of the message.

pub fn raw(&self) -> RAW[src]

Gets the raw data of the message.

pub fn token(&self) -> Option<u32>[src]

Gets the token of a message. This token is used to track IPC call chains. Only present on newer IPC request types.

pub fn push_handle_move(&mut self, handle: Handle) -> &mut Self[src]

Move a handle over IPC. Once the message is sent, the handle will not exist in the current process anymore.

Note

The handle is forgotten as soon as this function is called. If the message is never sent, then the handle will never be closed, causing a handle leak! Furthermore, IPC errors might cause similar problems.

Panics

Panics if attempting to push more handles than there is space for in this message.

pub fn push_handle_copy(&mut self, handle: HandleRef) -> &mut Self[src]

Copy a handle over IPC. The remote process will have a handle that points to the same object.

Panics

Panics if attempting to push more handles than there is space for in this message.

pub fn pop_handle_move(&mut self) -> Result<Handle, Error>[src]

Retrieve a moved handle from this IPC message. Those are popped in the order they were inserted.

Errors

Returns an InvalidMoveHandleCount if attempting to pop more handles than this message has.

pub fn pop_handle_copy(&mut self) -> Result<Handle, Error>[src]

Retrieve a copied handle from this IPC message. Those are popped in the order they were inserted.

Errors

Returns an InvalidCopyHandleCount if attempting to pop more handles than this message has.

pub fn pop_pid(&mut self) -> Result<Pid, Error>[src]

Retrieve the PID of the remote process (if sent at all). This message should only be called once.

Errors

Returns a PidMissing if attempting to pop a Pid from a message that has none, or if attempting to pop a Pid twice.

pub unsafe fn pop_in_buffer<'b, T: SizedIPCBuffer + ?Sized>(
    &mut self
) -> Result<&'b T, Error>
[src]

Retreive the next InBuffer (type-A buffer) in the message.

Errors

Returns an InvalidIpcBufferCount if not enough buffers are present

Returns an InvalidIpcBuffer if the next buffer was not of the appropriate size.

Safety

This method is unsafe as it allows creating references to arbitrary memory, and of arbitrary type.

pub unsafe fn pop_out_buffer<'b, T: SizedIPCBuffer + ?Sized>(
    &mut self
) -> Result<&'b mut T, Error>
[src]

Retreive the next OutBuffer (type-B buffer) in the message.

Errors

Returns an InvalidIpcBufferCount if not enough buffers are present

Returns an InvalidIpcBuffer if the next buffer was not of the appropriate size.

Safety

This method is unsafe as it allows creating references to arbitrary memory, and of arbitrary type.

pub fn push_out_buffer<T: SizedIPCBuffer + ?Sized>(
    &mut self,
    data: &'a T
) -> &mut Self
[src]

Push an OutBuffer (type-A buffer) backed by the specified data.

pub fn push_in_buffer<T: SizedIPCBuffer + ?Sized>(
    &mut self,
    data: &'a mut T
) -> &mut Self
[src]

Push an InBuffer (type-B buffer) backed by the specified data.

pub fn push_in_pointer<T: SizedIPCBuffer + ?Sized>(
    &mut self,
    data: &'a mut T,
    has_u16_count: bool
) -> &mut Self
[src]

Push an InPointer (type-C buffer) backed by the specified data.

If has_u16_count is true, the size of the X buffer will be appended to the Raw Data. See Buffer 0xA on the IPC Marshalling page of switchbrew.

pub fn push_out_pointer<T: SizedIPCBuffer + ?Sized>(
    &mut self,
    data: &'a T
) -> &mut Self
[src]

Push an OutPointer (type-X buffer) backed by the specified data.

If has_u16_count is true, the size of the X buffer will be appended to the Raw Data. See Buffer 0xA on the IPC Marshalling page of switchbrew.

pub fn send_pid(&mut self, pid: Option<Pid>) -> &mut Self[src]

Send a Pid with this IPC request.

If pid is None, sends the current process' Pid. If it's Some, then it will attempt to send that process Pid. Note however that this requires a kernel patch to work properly.

pub unsafe fn pop_in_pointer<'b, T: SizedIPCBuffer + ?Sized>(
    &mut self
) -> Result<&'b T, Error>
[src]

Retreive the next InPointer (type-X buffer) in the message.

Errors

Returns an InvalidIpcBufferCount if not enough buffers are present

Returns an InvalidIpcBuffer if the next buffer was not of the appropriate size.

Safety

This method is unsafe as it allows creating references to arbitrary memory, and of arbitrary type.

pub fn pack(self, data: &mut [u8])[src]

Packs this IPC Message to an IPC buffer.

pub fn unpack(data: &[u8]) -> Message<'a, RAW, BUFF, COPY, MOVE>[src]

Parse the passed buffer into an IPC Message.

Trait Implementations

impl<'a, RAW: Debug, BUFF: Debug, COPY: Debug, MOVE: Debug> Debug for Message<'a, RAW, BUFF, COPY, MOVE> where
    BUFF: Array<Item = IPCBuffer<'a>>,
    COPY: Array<Item = u32>,
    MOVE: Array<Item = u32>,
    RAW: Copy
[src]

Auto Trait Implementations

impl<'a, RAW, BUFF, COPY, MOVE> RefUnwindSafe for Message<'a, RAW, BUFF, COPY, MOVE> where
    BUFF: RefUnwindSafe,
    COPY: RefUnwindSafe,
    MOVE: RefUnwindSafe,
    RAW: RefUnwindSafe,
    <BUFF as Array>::Index: RefUnwindSafe,
    <COPY as Array>::Index: RefUnwindSafe,
    <MOVE as Array>::Index: RefUnwindSafe

impl<'a, RAW, BUFF, COPY, MOVE> Send for Message<'a, RAW, BUFF, COPY, MOVE> where
    BUFF: Send,
    COPY: Send,
    MOVE: Send,
    RAW: Send,
    <BUFF as Array>::Index: Send,
    <COPY as Array>::Index: Send,
    <MOVE as Array>::Index: Send

impl<'a, RAW, BUFF, COPY, MOVE> Sync for Message<'a, RAW, BUFF, COPY, MOVE> where
    BUFF: Sync,
    COPY: Sync,
    MOVE: Sync,
    RAW: Sync,
    <BUFF as Array>::Index: Sync,
    <COPY as Array>::Index: Sync,
    <MOVE as Array>::Index: Sync

impl<'a, RAW, BUFF, COPY, MOVE> Unpin for Message<'a, RAW, BUFF, COPY, MOVE> where
    BUFF: Unpin,
    COPY: Unpin,
    MOVE: Unpin,
    RAW: Unpin,
    <BUFF as Array>::Index: Unpin,
    <COPY as Array>::Index: Unpin,
    <MOVE as Array>::Index: Unpin

impl<'a, RAW, BUFF, COPY, MOVE> UnwindSafe for Message<'a, RAW, BUFF, COPY, MOVE> where
    BUFF: UnwindSafe,
    COPY: UnwindSafe,
    MOVE: UnwindSafe,
    RAW: UnwindSafe,
    <BUFF as Array>::Index: UnwindSafe,
    <COPY as Array>::Index: UnwindSafe,
    <MOVE as Array>::Index: UnwindSafe

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> SizedIPCBuffer for T[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.