• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2023 Huawei Device Co., Ltd.
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 //     http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13 
14 use std::fs::File;
15 use std::io;
16 use std::io::{IoSlice, Write};
17 use std::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, RawFd};
18 
19 use ylong_io::sys::SourceFd;
20 use ylong_io::{Interest, Selector, Source, Token};
21 
22 #[derive(Debug)]
23 pub(crate) struct Pipe {
24     pub(crate) fd: File,
25 }
26 
27 impl<T: IntoRawFd> From<T> for Pipe {
from(value: T) -> Self28     fn from(value: T) -> Self {
29         let fd = unsafe { File::from_raw_fd(value.into_raw_fd()) };
30         Self { fd }
31     }
32 }
33 
34 impl<'a> io::Read for &'a Pipe {
read(&mut self, buf: &mut [u8]) -> io::Result<usize>35     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
36         (&self.fd).read(buf)
37     }
38 }
39 
40 impl<'a> Write for &'a Pipe {
write(&mut self, buf: &[u8]) -> io::Result<usize>41     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
42         (&self.fd).write(buf)
43     }
44 
write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize>45     fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
46         (&self.fd).write_vectored(bufs)
47     }
48 
flush(&mut self) -> io::Result<()>49     fn flush(&mut self) -> io::Result<()> {
50         (&self.fd).flush()
51     }
52 }
53 
54 impl AsRawFd for Pipe {
as_raw_fd(&self) -> RawFd55     fn as_raw_fd(&self) -> RawFd {
56         self.fd.as_raw_fd()
57     }
58 }
59 
60 impl AsFd for Pipe {
as_fd(&self) -> BorrowedFd<'_>61     fn as_fd(&self) -> BorrowedFd<'_> {
62         unsafe { BorrowedFd::borrow_raw(self.fd.as_raw_fd()) }
63     }
64 }
65 
66 impl Source for Pipe {
register( &mut self, selector: &Selector, token: Token, interests: Interest, ) -> io::Result<()>67     fn register(
68         &mut self,
69         selector: &Selector,
70         token: Token,
71         interests: Interest,
72     ) -> io::Result<()> {
73         SourceFd(&self.as_raw_fd()).register(selector, token, interests)
74     }
75 
deregister(&mut self, selector: &Selector) -> io::Result<()>76     fn deregister(&mut self, selector: &Selector) -> io::Result<()> {
77         SourceFd(&self.as_raw_fd()).deregister(selector)
78     }
79 
get_fd(&self) -> ylong_io::Fd80     fn get_fd(&self) -> ylong_io::Fd {
81         self.fd.as_raw_fd()
82     }
83 }
84 
85 #[cfg(test)]
86 mod test {
87     use std::io::{Read, Seek, Write};
88     use std::os::fd::{AsFd, AsRawFd};
89 
90     use ylong_io::Source;
91 
92     use super::Pipe;
93 
94     /// UT test cases for Pipe.
95     ///
96     /// # Brief
97     /// 1. Create a `Pipe` from `std::fs::File`.
98     /// 2. Write something into `Pipe`.
99     /// 3. Read from `Pipe` and check result.
100     #[test]
ut_process_pipe_test()101     fn ut_process_pipe_test() {
102         let arg = "Hello, world!";
103         let file_path = "pipe_file0.txt";
104 
105         let mut file = std::fs::File::options()
106             .read(true)
107             .write(true)
108             .create(true)
109             .open(file_path)
110             .unwrap();
111         let seek = file.stream_position().unwrap();
112         let mut pipe = Pipe::from(file);
113 
114         assert!(pipe.get_fd().as_raw_fd() >= 0);
115         assert!(pipe.as_fd().as_raw_fd() >= 0);
116         assert!(pipe.as_raw_fd() >= 0);
117 
118         (&pipe).write_all(arg.as_bytes()).unwrap();
119         (&pipe).flush().unwrap();
120 
121         pipe.fd.seek(std::io::SeekFrom::Start(seek)).unwrap();
122 
123         let mut buf = [0; 13];
124         (&pipe).read_exact(&mut buf).unwrap();
125         assert_eq!(buf, arg.as_bytes());
126 
127         std::fs::remove_file(file_path).unwrap();
128     }
129 }
130