1 | use crate::marker::PhantomData; |
2 | use crate::os::fd::{AsFd, AsRawFd}; |
3 | use crate::slice; |
4 | |
5 | use libc::{c_void, iovec}; |
6 | |
7 | #[derive (Copy, Clone)] |
8 | #[repr (transparent)] |
9 | pub struct IoSlice<'a> { |
10 | vec: iovec, |
11 | _p: PhantomData<&'a [u8]>, |
12 | } |
13 | |
14 | impl<'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)] |
42 | pub struct IoSliceMut<'a> { |
43 | vec: iovec, |
44 | _p: PhantomData<&'a mut [u8]>, |
45 | } |
46 | |
47 | impl<'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 | |
79 | pub 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 | |