[−][src]Struct sunrise_libuser::ipc::Message
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]
BUFF: Array<Item = IPCBuffer<'a>>,
COPY: Array<Item = u32>,
MOVE: Array<Item = u32>,
RAW: Copy,
pub fn new_request(
token: Option<u32>,
cmdid: u32
) -> Message<'a, RAW, BUFF, COPY, MOVE>
[src]
token: Option<u32>,
cmdid: u32
) -> Message<'a, RAW, BUFF, COPY, MOVE>
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]
pub fn error(&self) -> Result<(), Error>
[src]
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]
&mut self
) -> Result<&'b T, Error>
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]
&mut self
) -> Result<&'b mut T, Error>
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]
&mut self,
data: &'a T
) -> &mut Self
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]
&mut self,
data: &'a mut T
) -> &mut Self
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]
&mut self,
data: &'a mut T,
has_u16_count: bool
) -> &mut Self
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]
&mut self,
data: &'a T
) -> &mut Self
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]
&mut self
) -> Result<&'b T, Error>
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]
BUFF: Array<Item = IPCBuffer<'a>>,
COPY: Array<Item = u32>,
MOVE: Array<Item = u32>,
RAW: Copy,
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,
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,
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,
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,
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,
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]
T: 'static + ?Sized,
impl<T> Borrow<T> for T where
T: ?Sized,
[src]
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
[src]
T: ?Sized,
fn borrow_mut(&mut self) -> &mut T
[src]
impl<T> From<T> for T
[src]
impl<T, U> Into<U> for T where
U: From<T>,
[src]
U: From<T>,
impl<T> SizedIPCBuffer for T
[src]
fn size(&Self) -> usize
[src]
fn is_cool(usize, usize) -> bool
[src]
unsafe fn from_raw_parts<'a>(usize, usize) -> &'a T
[src]
unsafe fn from_raw_parts_mut<'a>(usize, usize) -> &'a mut T
[src]
impl<T, U> TryFrom<U> for T where
U: Into<T>,
[src]
U: Into<T>,
type Error = Infallible
The type returned in the event of a conversion error.
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
[src]
impl<T, U> TryInto<U> for T where
U: TryFrom<T>,
[src]
U: TryFrom<T>,