Skip to main content

file/
file.rs

1// Copyright (c) 2020 Xu Shaohua <shaohua@biofan.org>. All rights reserved.
2// Use of this source is governed by Apache-2.0 License that can be found
3// in the LICENSE file.
4
5use 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}