1use std::io::{self, BufRead, BufReader, Read};
6use std::path::{Path, PathBuf};
7
8#[derive(Debug)]
9pub struct File {
10 fd: i32,
11 path: PathBuf,
12}
13
14impl File {
15 pub fn new(path: &Path) -> Self {
16 Self {
17 fd: -1,
18 path: path.to_path_buf(),
19 }
20 }
21
22 pub fn open(&mut self) -> Result<(), nc::Errno> {
23 let ret = unsafe { nc::openat(nc::AT_FDCWD, self.path.to_str().unwrap(), nc::O_RDONLY, 0) };
24 match ret {
25 Ok(fd) => {
26 self.fd = fd;
27 Ok(())
28 }
29 Err(errno) => Err(errno),
30 }
31 }
32}
33
34impl Read for File {
35 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
36 let n_read = unsafe { nc::read(self.fd, buf) };
37 match n_read {
38 Ok(n_read) => Ok(n_read as usize),
39 Err(_errno) => Err(io::Error::new(io::ErrorKind::Other, "errno")),
40 }
41 }
42}
43
44impl Drop for File {
45 fn drop(&mut self) {
46 if self.fd > -1 {
47 println!("closing fd: {}", self.fd);
48 let _ = unsafe { nc::close(self.fd) };
49 self.fd = -1;
50 }
51 }
52}
53
54fn test_fd() {
55 let path = Path::new("/etc/issue");
56 let mut fd = File::new(path);
57 let _ = fd.open();
58 println!("fd: {:?}", fd);
59 let buf = BufReader::new(fd);
60 let lines = buf.lines().collect::<io::Result<Vec<String>>>().unwrap();
61 print!("lines: {:?}", lines);
62}
63
64fn main() {
65 test_fd();
66}