1use crate::marker::PhantomData;
2use crate::os::fd::{AsFd, AsRawFd};
3use crate::slice;
4
5use libc::{c_void, iovec};
6
7#[derive(Copy, Clone)]
8#[repr(transparent)]
9pub struct IoSlice<'a> {
10 vec: iovec,
11 _p: PhantomData<&'a [u8]>,
12}
13
14impl<'a> IoSlice<'a> {
15 #[inline]
16 pub fn new(buf: &'a [u8]) -> IoSlice<'a> {
17 IoSlice {
18 vec: iovec { iov_base: buf.as_ptr() as *mut u8 as *mut c_void, iov_len: buf.len() },
19 _p: PhantomData,
20 }
21 }
22
23 #[inline]
24 pub fn advance(&mut self, n: usize) {
25 if self.vec.iov_len < n {
26 panic!("advancing IoSlice beyond its length");
27 }
28
29 unsafe {
30 self.vec.iov_len -= n;
31 self.vec.iov_base = self.vec.iov_base.add(n);
32 }
33 }
34
35 #[inline]
36 pub fn as_slice(&self) -> &[u8] {
37 unsafe { slice::from_raw_parts(self.vec.iov_base as *mut u8, self.vec.iov_len) }
38 }
39}
40
41#[repr(transparent)]
42pub struct IoSliceMut<'a> {
43 vec: iovec,
44 _p: PhantomData<&'a mut [u8]>,
45}
46
47impl<'a> IoSliceMut<'a> {
48 #[inline]
49 pub fn new(buf: &'a mut [u8]) -> IoSliceMut<'a> {
50 IoSliceMut {
51 vec: iovec { iov_base: buf.as_mut_ptr() as *mut c_void, iov_len: buf.len() },
52 _p: PhantomData,
53 }
54 }
55
56 #[inline]
57 pub fn advance(&mut self, n: usize) {
58 if self.vec.iov_len < n {
59 panic!("advancing IoSliceMut beyond its length");
60 }
61
62 unsafe {
63 self.vec.iov_len -= n;
64 self.vec.iov_base = self.vec.iov_base.add(n);
65 }
66 }
67
68 #[inline]
69 pub fn as_slice(&self) -> &[u8] {
70 unsafe { slice::from_raw_parts(self.vec.iov_base as *mut u8, self.vec.iov_len) }
71 }
72
73 #[inline]
74 pub fn as_mut_slice(&mut self) -> &mut [u8] {
75 unsafe { slice::from_raw_parts_mut(self.vec.iov_base as *mut u8, self.vec.iov_len) }
76 }
77}
78
79pub fn is_terminal(fd: &impl AsFd) -> bool {
80 let fd: BorrowedFd<'_> = fd.as_fd();
81 unsafe { libc::isatty(fd.as_raw_fd()) != 0 }
82}
83