1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
use crate::vfs::*;
#[cfg(windows)]
use filetime::FileTime;
use std::io::Error;
#[cfg(unix)]
use std::os::unix::fs::MetadataExt;
#[cfg(windows)]
use std::os::windows::fs::MetadataExt;
#[cfg(windows)]
use winapi::shared::minwindef::DWORD;
#[cfg(windows)]
use winapi::um::winnt;
impl std::error::Error for FsError {}
impl From<std::io::Error> for FsError {
fn from(e: Error) -> Self {
use std::io::ErrorKind;
match e.kind() {
ErrorKind::NotFound => FsError::EntryNotFound,
ErrorKind::PermissionDenied => FsError::EntryNotFound,
ErrorKind::AlreadyExists => FsError::EntryExist,
ErrorKind::WouldBlock => FsError::Again,
ErrorKind::InvalidInput => FsError::InvalidParam,
ErrorKind::InvalidData => FsError::InvalidParam,
_ => FsError::DeviceError,
}
}
}
#[cfg(unix)]
impl From<std::fs::Metadata> for Metadata {
fn from(m: std::fs::Metadata) -> Self {
Metadata {
dev: m.dev() as usize,
inode: m.ino() as usize,
size: m.size() as usize,
blk_size: m.blksize() as usize,
blocks: m.blocks() as usize,
atime: Timespec {
sec: m.atime(),
nsec: m.atime_nsec() as i32,
},
mtime: Timespec {
sec: m.mtime(),
nsec: m.mtime_nsec() as i32,
},
ctime: Timespec {
sec: m.ctime(),
nsec: m.ctime_nsec() as i32,
},
type_: match (m.mode() & 0xf000) as _ {
libc::S_IFCHR => FileType::CharDevice,
libc::S_IFBLK => FileType::BlockDevice,
libc::S_IFDIR => FileType::Dir,
libc::S_IFREG => FileType::File,
libc::S_IFLNK => FileType::SymLink,
libc::S_IFSOCK => FileType::Socket,
_ => unimplemented!("unknown file type"),
},
mode: m.mode() as u16 & 0o777,
nlinks: m.nlink() as usize,
uid: m.uid() as usize,
gid: m.gid() as usize,
rdev: m.rdev() as usize,
}
}
}
#[cfg(windows)]
impl From<std::fs::Metadata> for Metadata {
fn from(m: std::fs::Metadata) -> Self {
Metadata {
dev: 0,
inode: 0,
size: m.file_size() as usize,
blk_size: 0,
blocks: 0,
atime: {
let atime = FileTime::from_last_access_time(&m);
Timespec {
sec: atime.unix_seconds(),
nsec: atime.nanoseconds() as i32,
}
},
mtime: {
let mtime = FileTime::from_last_modification_time(&m);
Timespec {
sec: mtime.unix_seconds(),
nsec: mtime.nanoseconds() as i32,
}
},
ctime: {
let mtime = FileTime::from_last_modification_time(&m);
Timespec {
sec: mtime.unix_seconds(),
nsec: mtime.nanoseconds() as i32,
}
},
type_: {
let attr = m.file_attributes() as DWORD;
if (attr & winnt::FILE_ATTRIBUTE_NORMAL) != 0 {
FileType::File
} else if (attr & winnt::FILE_ATTRIBUTE_DIRECTORY) != 0 {
FileType::Dir
} else if (attr & winnt::FILE_ATTRIBUTE_REPARSE_POINT) != 0 {
FileType::SymLink
} else {
unimplemented!("unknown file type")
}
},
mode: 0,
nlinks: 0,
uid: 0,
gid: 0,
rdev: 0,
}
}
}