Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/completion_queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use super::{IoUring, CQE, CQEs, CQEsBlocking, resultify};
///
/// Each element is a [`CQE`](crate::cqe::CQE).
///
/// Completion does not imply success. Completed events may be [timeouts](crate::cqe::CQE::is_iou_timeout).
/// Completion does not imply success; the event may have errored.
pub struct CompletionQueue<'ring> {
pub(crate) ring: NonNull<uring_sys::io_uring>,
_marker: PhantomData<&'ring mut IoUring>,
Expand Down
4 changes: 1 addition & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,7 @@
//!
//! A timeout is submitted as an additional IO event which completes after the specified time.
//! Therefore when you create a timeout, all that happens is that a completion event will appear
//! after that specified time. This also means that when processing completion events, you need to
//! be prepared for the possibility that the completion represents a timeout and not a normal IO
//! event (`CQE` has a method to check for this).
//! after that specified time.

/// Types related to completion queue events.
pub mod cqe;
Expand Down
56 changes: 56 additions & 0 deletions src/registrar/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,62 @@ impl fmt::Debug for Registrar<'_> {
unsafe impl<'ring> Send for Registrar<'ring> { }
unsafe impl<'ring> Sync for Registrar<'ring> { }

/// An opaque struct representing a process's credentials.
///
/// You can obtain a process's `Personality` using the registrar's
/// [`register_personality`](crate::registrar::Registrar::register_personality) method
/// and then use it to issue `SQEs` with that process's credentials. This may be useful if
/// you are sharing a ring between users.
/// ```no_run
/// use std::io;
/// use std::fs::File;
/// use std::ffi::CString;
/// use std::os::unix::fs::PermissionsExt;
/// use nix::libc;
/// use nix::unistd::{geteuid, seteuid, Uid};
/// use iou::sqe::{Mode, OFlag};
///
/// fn main() -> io::Result<()> {
/// if (!geteuid().is_root()) { panic!("example requires root"); }
///
/// let mut ring = iou::IoUring::new(1)?;
/// let path = "personality-tmp.txt";
/// let c_path = CString::new(path).unwrap();
///
/// // create a file only accessible by the owner
/// {
/// let f = File::create(path)?;
/// let mut perms = f.metadata()?.permissions();
/// perms.set_mode(0o600);
/// std::fs::set_permissions(path, perms)?;
/// }
///
/// let pers = ring.registrar().register_personality()?;
///
/// // other users can't access that file normally...
/// seteuid(Uid::from_raw(2000)).unwrap();
/// unsafe {
/// let mut sqe = ring.prepare_sqe().unwrap();
/// sqe.prep_openat(libc::AT_FDCWD, &c_path, OFlag::O_RDONLY, Mode::empty());
/// }
/// ring.submit_sqes()?;
/// assert!(ring.wait_for_cqe()?.result().is_err());
///
/// // ... but they can use the process's Personality to perform IO
/// // as if they were that process.
/// unsafe {
/// let mut sqe = ring.prepare_sqe().unwrap();
/// sqe.prep_openat(libc::AT_FDCWD, &c_path, OFlag::O_RDONLY, Mode::empty());
/// sqe.set_personality(pers);
/// }
/// ring.submit_sqes()?;
/// assert!(ring.wait_for_cqe()?.result().is_ok());
///
/// seteuid(Uid::from_raw(0)).unwrap();
/// let _ = std::fs::remove_file(&path);
/// Ok(())
/// }
/// ```
#[derive(Debug, Eq, PartialEq, Hash, Ord, PartialOrd, Clone, Copy)]
pub struct Personality {
pub(crate) id: u16,
Expand Down
4 changes: 2 additions & 2 deletions src/sqe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ impl<'a> SQE<'a> {
/// Prepare a read on a file descriptor.
///
/// Both the file descriptor and the buffer can be pre-registered. See the
/// [`registrar][crate::registrar] module for more information.
/// [`registrar`][crate::registrar] module for more information.
#[inline]
pub unsafe fn prep_read(
&mut self,
Expand Down Expand Up @@ -154,7 +154,7 @@ impl<'a> SQE<'a> {
/// Prepare a write on a file descriptor.
///
/// Both the file descriptor and the buffer can be pre-registered. See the
/// [`registrar][crate::registrar] module for more information.
/// [`registrar`][crate::registrar] module for more information.
#[inline]
pub unsafe fn prep_write(
&mut self,
Expand Down