crosvm/data_model/src/sys.rs
Keiichi Watanabe 156cea0d43 sys_util: Fix all the default clippy warnings
Fix following warnings so that cargo clippy passes under sys_utils:
* new_without_default
* wrong_self_convention
* or_fun_call
* comparison_chain

Note that we still have warnings on other targets such as --tests.

BUG=chromium:1111728
TEST=cargo clippy passes under sys_util directory

Change-Id: I286c4e0386e44a9aba5e78594a6f30c1046ef7ee
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/2331885
Tested-by: Keiichi Watanabe <keiichiw@chromium.org>
Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
Commit-Queue: Keiichi Watanabe <keiichiw@chromium.org>
2020-08-06 03:28:13 +00:00

90 lines
2.8 KiB
Rust

use std::ffi::c_void;
use std::fmt::{self, Debug};
use std::marker::PhantomData;
use std::slice;
use libc::iovec;
/// This type is essentialy `std::io::IoSliceMut`, and guaranteed to be ABI-compatible with
/// `libc::iovec`; however, it does NOT automatically deref to `&mut [u8]`, which is critical
/// because it can point to guest memory. (Guest memory is implicitly mutably borrowed by the
/// guest, so another mutable borrow would violate Rust assumptions about references.)
#[derive(Copy, Clone)]
#[repr(transparent)]
pub struct IoSliceMut<'a> {
iov: iovec,
phantom: PhantomData<&'a mut [u8]>,
}
impl<'a> IoSliceMut<'a> {
pub fn new(buf: &mut [u8]) -> IoSliceMut<'a> {
// Safe because buf's memory is of the supplied length, and
// guaranteed to exist for the lifetime of the returned value.
unsafe { Self::from_raw_parts(buf.as_mut_ptr(), buf.len()) }
}
/// Creates a `IoSliceMut` from a pointer and a length.
///
/// # Safety
///
/// In order to use this method safely, `addr` must be valid for reads and writes of `len` bytes
/// and should live for the entire duration of lifetime `'a`.
pub unsafe fn from_raw_parts(addr: *mut u8, len: usize) -> IoSliceMut<'a> {
IoSliceMut {
iov: iovec {
iov_base: addr as *mut c_void,
iov_len: len,
},
phantom: PhantomData,
}
}
#[inline]
pub fn len(&self) -> usize {
self.iov.iov_len as usize
}
#[inline]
pub fn as_iobuf(&self) -> libc::iovec {
self.iov
}
/// Gets a const pointer to this slice's memory.
#[inline]
pub fn as_ptr(&self) -> *const u8 {
self.iov.iov_base as *const u8
}
/// Gets a mutable pointer to this slice's memory.
#[inline]
pub fn as_mut_ptr(&self) -> *mut u8 {
self.iov.iov_base as *mut u8
}
/// Converts a slice of `IoSliceMut`s into a slice of `iovec`s.
#[allow(clippy::wrong_self_convention)]
#[inline]
pub fn as_iobufs<'slice>(iovs: &'slice [IoSliceMut<'_>]) -> &'slice [iovec] {
// Safe because `IoSliceMut` is ABI-compatible with `iovec`.
unsafe { slice::from_raw_parts(iovs.as_ptr() as *const libc::iovec, iovs.len()) }
}
}
struct DebugIovec(iovec);
impl Debug for DebugIovec {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("iovec")
.field("iov_base", &self.0.iov_base)
.field("iov_len", &self.0.iov_len)
.finish()
}
}
impl<'a> Debug for IoSliceMut<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("IoSliceMut")
.field("iov", &DebugIovec(self.iov))
.field("phantom", &self.phantom)
.finish()
}
}