/rust/registry/src/index.crates.io-1949cf8c6b5b557f/cap-primitives-3.4.5/src/fs/file.rs
Line | Count | Source |
1 | | use std::io; |
2 | | |
3 | | /// Unix-specific extensions to [`fs::File`]. |
4 | | #[cfg(unix)] |
5 | | pub trait FileExt { |
6 | | /// Reads a number of bytes starting from a given offset. |
7 | | fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result<usize>; |
8 | | |
9 | | /// Like `read_at`, except that it reads into a slice of buffers. |
10 | | #[cfg(unix_file_vectored_at)] |
11 | 0 | fn read_vectored_at(&self, bufs: &mut [io::IoSliceMut<'_>], offset: u64) -> io::Result<usize> { |
12 | 0 | default_read_vectored(|b| self.read_at(b, offset), bufs) |
13 | 0 | } |
14 | | |
15 | | /// Reads the exact number of bytes required to fill `buf` from the given offset. |
16 | 0 | fn read_exact_at(&self, mut buf: &mut [u8], mut offset: u64) -> io::Result<()> { |
17 | 0 | while !buf.is_empty() { |
18 | 0 | match self.read_at(buf, offset) { |
19 | 0 | Ok(0) => break, |
20 | 0 | Ok(n) => { |
21 | 0 | let tmp = buf; |
22 | 0 | buf = &mut tmp[n..]; |
23 | 0 | offset += n as u64; |
24 | 0 | } |
25 | 0 | Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {} |
26 | 0 | Err(e) => return Err(e), |
27 | | } |
28 | | } |
29 | 0 | if !buf.is_empty() { |
30 | 0 | Err(io::Error::new( |
31 | 0 | io::ErrorKind::UnexpectedEof, |
32 | 0 | "failed to fill whole buffer", |
33 | 0 | )) |
34 | | } else { |
35 | 0 | Ok(()) |
36 | | } |
37 | 0 | } |
38 | | |
39 | | /// Writes a number of bytes starting from a given offset. |
40 | | fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize>; |
41 | | |
42 | | /// Like `write_at`, except that it writes from a slice of buffers. |
43 | | #[cfg(unix_file_vectored_at)] |
44 | 0 | fn write_vectored_at(&self, bufs: &[io::IoSlice<'_>], offset: u64) -> io::Result<usize> { |
45 | 0 | default_write_vectored(|b| self.write_at(b, offset), bufs) |
46 | 0 | } |
47 | | |
48 | | /// Attempts to write an entire buffer starting from a given offset. |
49 | 0 | fn write_all_at(&self, mut buf: &[u8], mut offset: u64) -> io::Result<()> { |
50 | 0 | while !buf.is_empty() { |
51 | 0 | match self.write_at(buf, offset) { |
52 | | Ok(0) => { |
53 | 0 | return Err(io::Error::new( |
54 | 0 | io::ErrorKind::WriteZero, |
55 | 0 | "failed to write whole buffer", |
56 | 0 | )); |
57 | | } |
58 | 0 | Ok(n) => { |
59 | 0 | buf = &buf[n..]; |
60 | 0 | offset += n as u64 |
61 | | } |
62 | 0 | Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {} |
63 | 0 | Err(e) => return Err(e), |
64 | | } |
65 | | } |
66 | 0 | Ok(()) |
67 | 0 | } |
68 | | } |
69 | | |
70 | | #[cfg(unix_file_vectored_at)] |
71 | 0 | fn default_read_vectored<F>(read: F, bufs: &mut [io::IoSliceMut<'_>]) -> io::Result<usize> |
72 | 0 | where |
73 | 0 | F: FnOnce(&mut [u8]) -> io::Result<usize>, |
74 | | { |
75 | 0 | let buf = bufs |
76 | 0 | .iter_mut() |
77 | 0 | .find(|b| !b.is_empty()) |
78 | 0 | .map_or(&mut [][..], |b| &mut **b); |
79 | 0 | read(buf) |
80 | 0 | } |
81 | | |
82 | | #[cfg(unix_file_vectored_at)] |
83 | 0 | fn default_write_vectored<F>(write: F, bufs: &[io::IoSlice<'_>]) -> io::Result<usize> |
84 | 0 | where |
85 | 0 | F: FnOnce(&[u8]) -> io::Result<usize>, |
86 | | { |
87 | 0 | let buf = bufs |
88 | 0 | .iter() |
89 | 0 | .find(|b| !b.is_empty()) |
90 | 0 | .map_or(&[][..], |b| &**b); |
91 | 0 | write(buf) |
92 | 0 | } |
93 | | |
94 | | /// WASI-specific extensions to [`fs::File`]. |
95 | | #[cfg(target_os = "wasi")] |
96 | | pub trait FileExt { |
97 | | /// Reads a number of bytes starting from a given offset. |
98 | | fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result<usize> { |
99 | | let bufs = &mut [io::IoSliceMut::new(buf)]; |
100 | | self.read_vectored_at(bufs, offset) |
101 | | } |
102 | | |
103 | | /// Reads a number of bytes starting from a given offset. |
104 | | fn read_vectored_at(&self, bufs: &mut [io::IoSliceMut<'_>], offset: u64) -> io::Result<usize>; |
105 | | |
106 | | /// Reads the exact number of byte required to fill `buf` from the given offset. |
107 | | fn read_exact_at(&self, mut buf: &mut [u8], mut offset: u64) -> io::Result<()> { |
108 | | while !buf.is_empty() { |
109 | | match self.read_at(buf, offset) { |
110 | | Ok(0) => break, |
111 | | Ok(n) => { |
112 | | let tmp = buf; |
113 | | buf = &mut tmp[n..]; |
114 | | offset += n as u64; |
115 | | } |
116 | | Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {} |
117 | | Err(e) => return Err(e), |
118 | | } |
119 | | } |
120 | | if !buf.is_empty() { |
121 | | Err(io::Error::new( |
122 | | io::ErrorKind::UnexpectedEof, |
123 | | "failed to fill whole buffer", |
124 | | )) |
125 | | } else { |
126 | | Ok(()) |
127 | | } |
128 | | } |
129 | | |
130 | | /// Writes a number of bytes starting from a given offset. |
131 | | fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize> { |
132 | | let bufs = &[io::IoSlice::new(buf)]; |
133 | | self.write_vectored_at(bufs, offset) |
134 | | } |
135 | | |
136 | | /// Writes a number of bytes starting from a given offset. |
137 | | fn write_vectored_at(&self, bufs: &[io::IoSlice<'_>], offset: u64) -> io::Result<usize>; |
138 | | |
139 | | /// Attempts to write an entire buffer starting from a given offset. |
140 | | fn write_all_at(&self, mut buf: &[u8], mut offset: u64) -> io::Result<()> { |
141 | | while !buf.is_empty() { |
142 | | match self.write_at(buf, offset) { |
143 | | Ok(0) => { |
144 | | return Err(io::Error::new( |
145 | | io::ErrorKind::WriteZero, |
146 | | "failed to write whole buffer", |
147 | | )); |
148 | | } |
149 | | Ok(n) => { |
150 | | buf = &buf[n..]; |
151 | | offset += n as u64 |
152 | | } |
153 | | Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {} |
154 | | Err(e) => return Err(e), |
155 | | } |
156 | | } |
157 | | Ok(()) |
158 | | } |
159 | | |
160 | | /// Adjust the flags associated with this file. |
161 | | fn fdstat_set_flags(&self, flags: u16) -> io::Result<()>; |
162 | | |
163 | | /// Adjust the rights associated with this file. |
164 | | fn fdstat_set_rights(&self, rights: u64, inheriting: u64) -> io::Result<()>; |
165 | | |
166 | | /// Provide file advisory information on a file descriptor. |
167 | | fn advise(&self, offset: u64, len: u64, advice: u8) -> io::Result<()>; |
168 | | |
169 | | /// Force the allocation of space in a file. |
170 | | fn allocate(&self, offset: u64, len: u64) -> io::Result<()>; |
171 | | |
172 | | /// Create a directory. |
173 | | fn create_directory<P: AsRef<std::path::Path>>(&self, dir: P) -> io::Result<()>; |
174 | | |
175 | | /// Read the contents of a symbolic link. |
176 | | fn read_link<P: AsRef<std::path::Path>>(&self, path: P) -> io::Result<std::path::PathBuf>; |
177 | | |
178 | | /// Return the attributes of a file or directory. |
179 | | fn metadata_at<P: AsRef<std::path::Path>>( |
180 | | &self, |
181 | | lookup_flags: u32, |
182 | | path: P, |
183 | | ) -> io::Result<std::fs::Metadata>; |
184 | | |
185 | | /// Unlink a file. |
186 | | fn remove_file<P: AsRef<std::path::Path>>(&self, path: P) -> io::Result<()>; |
187 | | |
188 | | /// Remove a directory. |
189 | | fn remove_directory<P: AsRef<std::path::Path>>(&self, path: P) -> io::Result<()>; |
190 | | } |
191 | | |
192 | | /// Windows-specific extensions to [`fs::File`]. |
193 | | #[cfg(windows)] |
194 | | pub trait FileExt { |
195 | | /// Seeks to a given position and reads a number of bytes. |
196 | | fn seek_read(&self, buf: &mut [u8], offset: u64) -> io::Result<usize>; |
197 | | |
198 | | /// Seeks to a given position and writes a number of bytes. |
199 | | fn seek_write(&self, buf: &[u8], offset: u64) -> io::Result<usize>; |
200 | | } |