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