1use rustix::fs::*;
4
5use crate::op::*;
6
7pub struct OpenFile<S: AsFd> {
9 pub(crate) dirfd: S,
10 pub(crate) path: CString,
11 pub(crate) flags: OFlags,
12 pub(crate) mode: Mode,
13 pub(crate) opened_fd: Option<OwnedFd>,
14}
15
16impl<S: AsFd> OpenFile<S> {
17 pub fn new(dirfd: S, path: CString, flags: OFlags, mode: Mode) -> Self {
19 Self {
20 dirfd,
21 path,
22 flags,
23 mode,
24 opened_fd: None,
25 }
26 }
27
28 pub(crate) fn call(&mut self, _: &mut ()) -> io::Result<usize> {
29 let fd = openat(
30 self.dirfd.as_fd(),
31 &self.path,
32 self.flags | OFlags::CLOEXEC,
33 self.mode,
34 )?;
35 let raw_fd = fd.as_raw_fd();
36 self.opened_fd = Some(fd);
37 Ok(raw_fd as _)
38 }
39}
40
41impl<S: AsFd> IntoInner for OpenFile<S> {
42 type Inner = OwnedFd;
43
44 fn into_inner(self) -> Self::Inner {
45 self.opened_fd.expect("file not opened")
46 }
47}
48
49impl CloseFile {
50 pub(crate) fn call(&mut self, _: &mut ()) -> io::Result<usize> {
51 unsafe { ManuallyDrop::drop(&mut self.fd) };
52 Ok(0)
53 }
54}
55
56#[derive(Debug)]
59pub struct TruncateFile<S: AsFd> {
60 pub(crate) fd: S,
61 pub(crate) size: u64,
62}
63
64impl<S: AsFd> TruncateFile<S> {
65 pub fn new(fd: S, size: u64) -> Self {
67 Self { fd, size }
68 }
69
70 pub(crate) fn call(&self) -> io::Result<usize> {
71 ftruncate(self.fd.as_fd(), self.size)?;
72 Ok(0)
73 }
74}
75
76#[doc(hidden)]
77#[derive(Default)]
78pub struct VectoredControl {
79 pub(crate) slices: Vec<SysSlice>,
80}
81
82pub struct ReadVectoredAt<T: IoVectoredBufMut, S> {
84 pub(crate) fd: S,
85 pub(crate) offset: u64,
86 pub(crate) buffer: T,
87}
88
89impl<T: IoVectoredBufMut, S> ReadVectoredAt<T, S> {
90 pub fn new(fd: S, offset: u64, buffer: T) -> Self {
92 Self { fd, offset, buffer }
93 }
94}
95
96impl<T: IoVectoredBufMut, S> IntoInner for ReadVectoredAt<T, S> {
97 type Inner = T;
98
99 fn into_inner(self) -> Self::Inner {
100 self.buffer
101 }
102}
103
104pub struct WriteVectoredAt<T: IoVectoredBuf, S> {
106 pub(crate) fd: S,
107 pub(crate) offset: u64,
108 pub(crate) buffer: T,
109}
110
111impl<T: IoVectoredBuf, S> WriteVectoredAt<T, S> {
112 pub fn new(fd: S, offset: u64, buffer: T) -> Self {
114 Self { fd, offset, buffer }
115 }
116}
117
118impl<T: IoVectoredBuf, S> IntoInner for WriteVectoredAt<T, S> {
119 type Inner = T;
120
121 fn into_inner(self) -> Self::Inner {
122 self.buffer
123 }
124}
125
126pub struct ReadVectored<T: IoVectoredBufMut, S> {
128 pub(crate) fd: S,
129 pub(crate) buffer: T,
130}
131
132impl<T: IoVectoredBufMut, S> ReadVectored<T, S> {
133 pub fn new(fd: S, buffer: T) -> Self {
135 Self { fd, buffer }
136 }
137}
138
139impl<T: IoVectoredBufMut, S> IntoInner for ReadVectored<T, S> {
140 type Inner = T;
141
142 fn into_inner(self) -> Self::Inner {
143 self.buffer
144 }
145}
146
147pub struct WriteVectored<T: IoVectoredBuf, S> {
149 pub(crate) fd: S,
150 pub(crate) buffer: T,
151}
152
153impl<T: IoVectoredBuf, S> WriteVectored<T, S> {
154 pub fn new(fd: S, buffer: T) -> Self {
156 Self { fd, buffer }
157 }
158}
159
160impl<T: IoVectoredBuf, S> IntoInner for WriteVectored<T, S> {
161 type Inner = T;
162
163 fn into_inner(self) -> Self::Inner {
164 self.buffer
165 }
166}
167
168pub struct Unlink<S: AsFd> {
170 pub(crate) dirfd: S,
171 pub(crate) path: CString,
172 pub(crate) dir: bool,
173}
174
175impl<S: AsFd> Unlink<S> {
176 pub fn new(dirfd: S, path: CString, dir: bool) -> Self {
178 Self { dirfd, path, dir }
179 }
180
181 pub(crate) fn call(&mut self, _: &mut ()) -> io::Result<usize> {
182 let flags = if self.dir {
183 AtFlags::REMOVEDIR
184 } else {
185 AtFlags::empty()
186 };
187
188 unlinkat(self.dirfd.as_fd(), &self.path, flags)?;
189
190 Ok(0)
191 }
192}
193
194pub struct CreateDir<S: AsFd> {
196 pub(crate) dirfd: S,
197 pub(crate) path: CString,
198 pub(crate) mode: Mode,
199}
200
201impl<S: AsFd> CreateDir<S> {
202 pub fn new(dirfd: S, path: CString, mode: Mode) -> Self {
204 Self { dirfd, path, mode }
205 }
206
207 pub(crate) fn call(&mut self, _: &mut ()) -> io::Result<usize> {
208 mkdirat(self.dirfd.as_fd(), &self.path, self.mode)?;
209
210 Ok(0)
211 }
212}
213
214pub struct Rename<S1: AsFd, S2: AsFd> {
216 pub(crate) old_dirfd: S1,
217 pub(crate) old_path: CString,
218 pub(crate) new_dirfd: S2,
219 pub(crate) new_path: CString,
220}
221
222impl<S1: AsFd, S2: AsFd> Rename<S1, S2> {
223 pub fn new(old_dirfd: S1, old_path: CString, new_dirfd: S2, new_path: CString) -> Self {
225 Self {
226 old_dirfd,
227 old_path,
228 new_dirfd,
229 new_path,
230 }
231 }
232
233 pub(crate) fn call(&mut self, _: &mut ()) -> io::Result<usize> {
234 renameat(
235 self.old_dirfd.as_fd(),
236 &self.old_path,
237 self.new_dirfd.as_fd(),
238 &self.new_path,
239 )?;
240
241 Ok(0)
242 }
243}
244
245pub struct Symlink<S: AsFd> {
247 pub(crate) source: CString,
248 pub(crate) dirfd: S,
249 pub(crate) target: CString,
250}
251
252impl<S: AsFd> Symlink<S> {
253 pub fn new(source: CString, dirfd: S, target: CString) -> Self {
255 Self {
256 source,
257 dirfd,
258 target,
259 }
260 }
261
262 pub(crate) fn call(&mut self, _: &mut ()) -> io::Result<usize> {
263 symlinkat(&self.source, self.dirfd.as_fd(), &self.target)?;
264
265 Ok(0)
266 }
267}
268
269pub struct HardLink<S1: AsFd, S2: AsFd> {
271 pub(crate) source_dirfd: S1,
272 pub(crate) source: CString,
273 pub(crate) target_dirfd: S2,
274 pub(crate) target: CString,
275}
276
277impl<S1: AsFd, S2: AsFd> HardLink<S1, S2> {
278 pub fn new(source_dirfd: S1, source: CString, target_dirfd: S2, target: CString) -> Self {
280 Self {
281 source_dirfd,
282 source,
283 target_dirfd,
284 target,
285 }
286 }
287
288 pub(crate) fn call(&mut self, _: &mut ()) -> io::Result<usize> {
289 linkat(
290 self.source_dirfd.as_fd(),
291 &self.source,
292 self.target_dirfd.as_fd(),
293 &self.target,
294 AtFlags::empty(),
295 )?;
296 Ok(0)
297 }
298}
299
300pub struct PollOnce<S> {
302 pub(crate) fd: S,
303 pub(crate) interest: Interest,
304}
305
306impl<S> PollOnce<S> {
307 pub fn new(fd: S, interest: Interest) -> Self {
309 Self { fd, interest }
310 }
311}
312
313impl<S> IntoInner for PollOnce<S> {
314 type Inner = S;
315
316 fn into_inner(self) -> Self::Inner {
317 self.fd
318 }
319}
320
321pub struct Pipe {
323 pub(crate) fds: [Option<OwnedFd>; 2],
324}
325
326const _: () = assert!(std::mem::size_of::<Option<OwnedFd>>() == std::mem::size_of::<RawFd>());
328
329impl Pipe {
330 #[allow(clippy::new_without_default)]
332 pub fn new() -> Self {
333 Self { fds: [None, None] }
334 }
335
336 pub(crate) fn call(&mut self) -> io::Result<usize> {
337 self.fds = mk_pipe()?;
338 Ok(0)
339 }
340}
341
342impl IntoInner for Pipe {
343 type Inner = (OwnedFd, OwnedFd);
344
345 fn into_inner(self) -> Self::Inner {
346 let [read_fd, write_fd] = self.fds;
347 let read_fd = read_fd.expect("pipe not created");
348 let write_fd = write_fd.expect("pipe not created");
349 (read_fd, write_fd)
350 }
351}