1use crate::errno::Errno;
2use libc::{self, c_char, c_int, c_uint, size_t, ssize_t};
3use std::ffi::OsString;
4#[cfg(not(target_os = "redox"))]
5use std::os::raw;
6use std::os::unix::ffi::OsStringExt;
7use std::os::unix::io::RawFd;
8
9#[cfg(any(target_os = "android", target_os = "linux"))]
10use std::ptr; #[cfg(feature = "fs")]
12use crate::{
13 NixPath,
14 Result,
15 sys::stat::Mode
16};
17
18#[cfg(any(
19 target_os = "linux",
20 target_os = "android",
21 target_os = "emscripten",
22 target_os = "fuchsia",
23 any(target_os = "wasi", target_env = "wasi"),
24 target_env = "uclibc",
25 target_os = "freebsd"
26))]
27#[cfg(feature = "fs")]
28pub use self::posix_fadvise::{PosixFadviseAdvice, posix_fadvise};
29
30#[cfg(not(target_os = "redox"))]
31#[cfg(any(feature = "fs", feature = "process"))]
32libc_bitflags! {
33 #[cfg_attr(docsrs, doc(cfg(any(feature = "fs", feature = "process"))))]
34 pub struct AtFlags: c_int {
35 AT_REMOVEDIR;
36 AT_SYMLINK_FOLLOW;
37 AT_SYMLINK_NOFOLLOW;
38 #[cfg(any(target_os = "android", target_os = "linux"))]
39 AT_NO_AUTOMOUNT;
40 #[cfg(any(target_os = "android", target_os = "linux"))]
41 AT_EMPTY_PATH;
42 #[cfg(any(target_os = "illumos", target_os = "solaris"))]
43 AT_EACCESS;
44 }
45}
46
47#[cfg(any(feature = "fs", feature = "term"))]
48libc_bitflags!(
49 #[cfg_attr(docsrs, doc(cfg(any(feature = "fs", feature = "term"))))]
51 pub struct OFlag: c_int {
52 O_ACCMODE;
54 #[cfg(target_os = "netbsd")]
56 #[cfg_attr(docsrs, doc(cfg(all())))]
57 O_ALT_IO;
58 O_APPEND;
60 #[cfg(not(any(target_os = "illumos", target_os = "solaris")))]
62 #[cfg_attr(docsrs, doc(cfg(all())))]
63 O_ASYNC;
64 O_CLOEXEC;
68 O_CREAT;
70 #[cfg(any(target_os = "android",
72 target_os = "dragonfly",
73 target_os = "freebsd",
74 target_os = "linux",
75 target_os = "netbsd"))]
76 #[cfg_attr(docsrs, doc(cfg(all())))]
77 O_DIRECT;
78 #[cfg(not(any(target_os = "illumos", target_os = "solaris")))]
80 #[cfg_attr(docsrs, doc(cfg(all())))]
81 O_DIRECTORY;
82 #[cfg(any(target_os = "android",
84 target_os = "ios",
85 target_os = "linux",
86 target_os = "macos",
87 target_os = "netbsd",
88 target_os = "openbsd"))]
89 #[cfg_attr(docsrs, doc(cfg(all())))]
90 O_DSYNC;
91 O_EXCL;
93 #[cfg(target_os = "freebsd")]
95 #[cfg_attr(docsrs, doc(cfg(all())))]
96 O_EXEC;
97 #[cfg(any(target_os = "dragonfly",
99 target_os = "freebsd",
100 target_os = "ios",
101 target_os = "macos",
102 target_os = "netbsd",
103 target_os = "openbsd",
104 target_os = "redox"))]
105 #[cfg_attr(docsrs, doc(cfg(all())))]
106 O_EXLOCK;
107 #[cfg(any(target_os = "dragonfly",
109 target_os = "freebsd",
110 target_os = "ios",
111 all(target_os = "linux", not(target_env = "musl")),
112 target_os = "macos",
113 target_os = "netbsd",
114 target_os = "openbsd",
115 target_os = "redox"))]
116 #[cfg_attr(docsrs, doc(cfg(all())))]
117 O_FSYNC;
118 #[cfg(any(target_os = "android", target_os = "linux"))]
120 #[cfg_attr(docsrs, doc(cfg(all())))]
121 O_LARGEFILE;
122 #[cfg(any(target_os = "android", target_os = "linux"))]
124 #[cfg_attr(docsrs, doc(cfg(all())))]
125 O_NOATIME;
126 #[cfg(not(target_os = "redox"))]
128 #[cfg_attr(docsrs, doc(cfg(all())))]
129 O_NOCTTY;
130 #[cfg(not(target_os = "redox"))]
132 #[cfg_attr(docsrs, doc(cfg(all())))]
133 O_NDELAY;
134 O_NOFOLLOW;
136 O_NONBLOCK;
138 #[cfg(target_os = "netbsd")]
140 #[cfg_attr(docsrs, doc(cfg(all())))]
141 O_NOSIGPIPE;
142 #[cfg(any(target_os = "android", target_os = "linux", target_os = "redox"))]
146 #[cfg_attr(docsrs, doc(cfg(all())))]
147 O_PATH;
148 O_RDONLY;
152 O_RDWR;
156 #[cfg(any(target_os = "linux", target_os = "netbsd", target_os = "openbsd"))]
158 #[cfg_attr(docsrs, doc(cfg(all())))]
159 O_RSYNC;
160 #[cfg(target_os = "netbsd")]
162 #[cfg_attr(docsrs, doc(cfg(all())))]
163 O_SEARCH;
164 #[cfg(any(target_os = "dragonfly",
166 target_os = "freebsd",
167 target_os = "ios",
168 target_os = "macos",
169 target_os = "netbsd",
170 target_os = "openbsd",
171 target_os = "redox"))]
172 #[cfg_attr(docsrs, doc(cfg(all())))]
173 O_SHLOCK;
174 #[cfg(not(target_os = "redox"))]
176 #[cfg_attr(docsrs, doc(cfg(all())))]
177 O_SYNC;
178 #[cfg(any(target_os = "android", target_os = "linux"))]
180 #[cfg_attr(docsrs, doc(cfg(all())))]
181 O_TMPFILE;
182 O_TRUNC;
184 #[cfg(target_os = "freebsd")]
186 #[cfg_attr(docsrs, doc(cfg(all())))]
187 O_TTY_INIT;
188 O_WRONLY;
192 }
193);
194
195feature! {
196#![feature = "fs"]
197
198#[allow(clippy::useless_conversion)]
200pub fn open<P: ?Sized + NixPath>(path: &P, oflag: OFlag, mode: Mode) -> Result<RawFd> {
201 let fd = path.with_nix_path(|cstr| {
202 unsafe { libc::open(cstr.as_ptr(), oflag.bits(), mode.bits() as c_uint) }
203 })?;
204
205 Errno::result(fd)
206}
207
208#[allow(clippy::useless_conversion)]
210#[cfg(not(target_os = "redox"))]
211pub fn openat<P: ?Sized + NixPath>(
212 dirfd: RawFd,
213 path: &P,
214 oflag: OFlag,
215 mode: Mode,
216) -> Result<RawFd> {
217 let fd = path.with_nix_path(|cstr| {
218 unsafe { libc::openat(dirfd, cstr.as_ptr(), oflag.bits(), mode.bits() as c_uint) }
219 })?;
220 Errno::result(fd)
221}
222
223#[cfg(not(target_os = "redox"))]
224pub fn renameat<P1: ?Sized + NixPath, P2: ?Sized + NixPath>(
225 old_dirfd: Option<RawFd>,
226 old_path: &P1,
227 new_dirfd: Option<RawFd>,
228 new_path: &P2,
229) -> Result<()> {
230 let res = old_path.with_nix_path(|old_cstr| {
231 new_path.with_nix_path(|new_cstr| unsafe {
232 libc::renameat(
233 at_rawfd(old_dirfd),
234 old_cstr.as_ptr(),
235 at_rawfd(new_dirfd),
236 new_cstr.as_ptr(),
237 )
238 })
239 })??;
240 Errno::result(res).map(drop)
241}
242}
243
244#[cfg(all(
245 target_os = "linux",
246 target_env = "gnu",
247))]
248#[cfg(feature = "fs")]
249libc_bitflags! {
250 #[cfg_attr(docsrs, doc(cfg(feature = "fs")))]
251 pub struct RenameFlags: u32 {
252 RENAME_EXCHANGE;
253 RENAME_NOREPLACE;
254 RENAME_WHITEOUT;
255 }
256}
257
258feature! {
259#![feature = "fs"]
260#[cfg(all(
261 target_os = "linux",
262 target_env = "gnu",
263))]
264pub fn renameat2<P1: ?Sized + NixPath, P2: ?Sized + NixPath>(
265 old_dirfd: Option<RawFd>,
266 old_path: &P1,
267 new_dirfd: Option<RawFd>,
268 new_path: &P2,
269 flags: RenameFlags,
270) -> Result<()> {
271 let res = old_path.with_nix_path(|old_cstr| {
272 new_path.with_nix_path(|new_cstr| unsafe {
273 libc::renameat2(
274 at_rawfd(old_dirfd),
275 old_cstr.as_ptr(),
276 at_rawfd(new_dirfd),
277 new_cstr.as_ptr(),
278 flags.bits(),
279 )
280 })
281 })??;
282 Errno::result(res).map(drop)
283}
284
285fn wrap_readlink_result(mut v: Vec<u8>, len: ssize_t) -> Result<OsString> {
286 unsafe { v.set_len(len as usize) }
287 v.shrink_to_fit();
288 Ok(OsString::from_vec(v.to_vec()))
289}
290
291fn readlink_maybe_at<P: ?Sized + NixPath>(
292 dirfd: Option<RawFd>,
293 path: &P,
294 v: &mut Vec<u8>,
295) -> Result<libc::ssize_t> {
296 path.with_nix_path(|cstr| unsafe {
297 match dirfd {
298 #[cfg(target_os = "redox")]
299 Some(_) => unreachable!(),
300 #[cfg(not(target_os = "redox"))]
301 Some(dirfd) => libc::readlinkat(
302 dirfd,
303 cstr.as_ptr(),
304 v.as_mut_ptr() as *mut c_char,
305 v.capacity() as size_t,
306 ),
307 None => libc::readlink(
308 cstr.as_ptr(),
309 v.as_mut_ptr() as *mut c_char,
310 v.capacity() as size_t,
311 ),
312 }
313 })
314}
315
316fn inner_readlink<P: ?Sized + NixPath>(dirfd: Option<RawFd>, path: &P) -> Result<OsString> {
317 let mut v = Vec::with_capacity(libc::PATH_MAX as usize);
318 let res = readlink_maybe_at(dirfd, path, &mut v)?;
320 let len = Errno::result(res)?;
321 debug_assert!(len >= 0);
322 if (len as usize) < v.capacity() {
323 return wrap_readlink_result(v, res);
324 }
325 let reported_size = match dirfd {
328 #[cfg(target_os = "redox")]
329 Some(_) => unreachable!(),
330 #[cfg(any(target_os = "android", target_os = "linux"))]
331 Some(dirfd) => {
332 let flags = if path.is_empty() { AtFlags::AT_EMPTY_PATH } else { AtFlags::empty() };
333 super::sys::stat::fstatat(dirfd, path, flags | AtFlags::AT_SYMLINK_NOFOLLOW)
334 },
335 #[cfg(not(any(target_os = "android", target_os = "linux", target_os = "redox")))]
336 Some(dirfd) => super::sys::stat::fstatat(dirfd, path, AtFlags::AT_SYMLINK_NOFOLLOW),
337 None => super::sys::stat::lstat(path)
338 }
339 .map(|x| x.st_size)
340 .unwrap_or(0);
341 let mut try_size = if reported_size > 0 {
342 reported_size as usize + 1
345 } else {
346 (libc::PATH_MAX as usize).max(128) << 1
349 };
350 loop {
351 v.reserve_exact(try_size);
352 let res = readlink_maybe_at(dirfd, path, &mut v)?;
353 let len = Errno::result(res)?;
354 debug_assert!(len >= 0);
355 if (len as usize) < v.capacity() {
356 break wrap_readlink_result(v, res);
357 } else {
358 match try_size.checked_shl(1) {
360 Some(next_size) => try_size = next_size,
361 None => break Err(Errno::ENAMETOOLONG),
364 }
365 }
366 }
367}
368
369pub fn readlink<P: ?Sized + NixPath>(path: &P) -> Result<OsString> {
370 inner_readlink(None, path)
371}
372
373#[cfg(not(target_os = "redox"))]
374pub fn readlinkat<P: ?Sized + NixPath>(dirfd: RawFd, path: &P) -> Result<OsString> {
375 inner_readlink(Some(dirfd), path)
376}
377
378#[cfg(not(target_os = "redox"))]
380pub(crate) fn at_rawfd(fd: Option<RawFd>) -> raw::c_int {
381 match fd {
382 None => libc::AT_FDCWD,
383 Some(fd) => fd,
384 }
385}
386}
387
388#[cfg(any(target_os = "android", target_os = "linux"))]
389#[cfg(feature = "fs")]
390libc_bitflags!(
391 #[cfg_attr(docsrs, doc(cfg(feature = "fs")))]
393 pub struct SealFlag: c_int {
394 F_SEAL_SEAL;
396 F_SEAL_SHRINK;
398 F_SEAL_GROW;
400 F_SEAL_WRITE;
402 }
403);
404
405#[cfg(feature = "fs")]
406libc_bitflags!(
407 #[cfg_attr(docsrs, doc(cfg(feature = "fs")))]
409 pub struct FdFlag: c_int {
410 FD_CLOEXEC;
412 }
413);
414
415feature! {
416#![feature = "fs"]
417
418#[cfg(not(target_os = "redox"))]
419#[derive(Debug, Eq, Hash, PartialEq)]
420#[non_exhaustive]
421pub enum FcntlArg<'a> {
422 F_DUPFD(RawFd),
423 F_DUPFD_CLOEXEC(RawFd),
424 F_GETFD,
425 F_SETFD(FdFlag), F_GETFL,
427 F_SETFL(OFlag), F_SETLK(&'a libc::flock),
429 F_SETLKW(&'a libc::flock),
430 F_GETLK(&'a mut libc::flock),
431 #[cfg(any(target_os = "linux", target_os = "android"))]
432 F_OFD_SETLK(&'a libc::flock),
433 #[cfg(any(target_os = "linux", target_os = "android"))]
434 F_OFD_SETLKW(&'a libc::flock),
435 #[cfg(any(target_os = "linux", target_os = "android"))]
436 F_OFD_GETLK(&'a mut libc::flock),
437 #[cfg(any(target_os = "android", target_os = "linux"))]
438 F_ADD_SEALS(SealFlag),
439 #[cfg(any(target_os = "android", target_os = "linux"))]
440 F_GET_SEALS,
441 #[cfg(any(target_os = "macos", target_os = "ios"))]
442 F_FULLFSYNC,
443 #[cfg(any(target_os = "linux", target_os = "android"))]
444 F_GETPIPE_SZ,
445 #[cfg(any(target_os = "linux", target_os = "android"))]
446 F_SETPIPE_SZ(c_int),
447 }
449
450#[cfg(target_os = "redox")]
451#[derive(Debug, Clone, Copy, Eq, Hash, PartialEq)]
452#[non_exhaustive]
453pub enum FcntlArg {
454 F_DUPFD(RawFd),
455 F_DUPFD_CLOEXEC(RawFd),
456 F_GETFD,
457 F_SETFD(FdFlag), F_GETFL,
459 F_SETFL(OFlag), }
461pub use self::FcntlArg::*;
462
463pub fn fcntl(fd: RawFd, arg: FcntlArg) -> Result<c_int> {
465 let res = unsafe {
466 match arg {
467 F_DUPFD(rawfd) => libc::fcntl(fd, libc::F_DUPFD, rawfd),
468 F_DUPFD_CLOEXEC(rawfd) => libc::fcntl(fd, libc::F_DUPFD_CLOEXEC, rawfd),
469 F_GETFD => libc::fcntl(fd, libc::F_GETFD),
470 F_SETFD(flag) => libc::fcntl(fd, libc::F_SETFD, flag.bits()),
471 F_GETFL => libc::fcntl(fd, libc::F_GETFL),
472 F_SETFL(flag) => libc::fcntl(fd, libc::F_SETFL, flag.bits()),
473 #[cfg(not(target_os = "redox"))]
474 F_SETLK(flock) => libc::fcntl(fd, libc::F_SETLK, flock),
475 #[cfg(not(target_os = "redox"))]
476 F_SETLKW(flock) => libc::fcntl(fd, libc::F_SETLKW, flock),
477 #[cfg(not(target_os = "redox"))]
478 F_GETLK(flock) => libc::fcntl(fd, libc::F_GETLK, flock),
479 #[cfg(any(target_os = "android", target_os = "linux"))]
480 F_OFD_SETLK(flock) => libc::fcntl(fd, libc::F_OFD_SETLK, flock),
481 #[cfg(any(target_os = "android", target_os = "linux"))]
482 F_OFD_SETLKW(flock) => libc::fcntl(fd, libc::F_OFD_SETLKW, flock),
483 #[cfg(any(target_os = "android", target_os = "linux"))]
484 F_OFD_GETLK(flock) => libc::fcntl(fd, libc::F_OFD_GETLK, flock),
485 #[cfg(any(target_os = "android", target_os = "linux"))]
486 F_ADD_SEALS(flag) => libc::fcntl(fd, libc::F_ADD_SEALS, flag.bits()),
487 #[cfg(any(target_os = "android", target_os = "linux"))]
488 F_GET_SEALS => libc::fcntl(fd, libc::F_GET_SEALS),
489 #[cfg(any(target_os = "macos", target_os = "ios"))]
490 F_FULLFSYNC => libc::fcntl(fd, libc::F_FULLFSYNC),
491 #[cfg(any(target_os = "linux", target_os = "android"))]
492 F_GETPIPE_SZ => libc::fcntl(fd, libc::F_GETPIPE_SZ),
493 #[cfg(any(target_os = "linux", target_os = "android"))]
494 F_SETPIPE_SZ(size) => libc::fcntl(fd, libc::F_SETPIPE_SZ, size),
495 }
496 };
497
498 Errno::result(res)
499}
500
501#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
503#[non_exhaustive]
504pub enum FlockArg {
505 LockShared,
506 LockExclusive,
507 Unlock,
508 LockSharedNonblock,
509 LockExclusiveNonblock,
510 UnlockNonblock,
511}
512
513#[cfg(not(target_os = "redox"))]
514pub fn flock(fd: RawFd, arg: FlockArg) -> Result<()> {
515 use self::FlockArg::*;
516
517 let res = unsafe {
518 match arg {
519 LockShared => libc::flock(fd, libc::LOCK_SH),
520 LockExclusive => libc::flock(fd, libc::LOCK_EX),
521 Unlock => libc::flock(fd, libc::LOCK_UN),
522 LockSharedNonblock => libc::flock(fd, libc::LOCK_SH | libc::LOCK_NB),
523 LockExclusiveNonblock => libc::flock(fd, libc::LOCK_EX | libc::LOCK_NB),
524 UnlockNonblock => libc::flock(fd, libc::LOCK_UN | libc::LOCK_NB),
525 }
526 };
527
528 Errno::result(res).map(drop)
529}
530}
531
532#[cfg(any(target_os = "android", target_os = "linux"))]
533#[cfg(feature = "zerocopy")]
534libc_bitflags! {
535 #[cfg_attr(docsrs, doc(cfg(feature = "zerocopy")))]
537 pub struct SpliceFFlags: c_uint {
538 SPLICE_F_MOVE;
542 SPLICE_F_NONBLOCK;
544 SPLICE_F_MORE;
548 SPLICE_F_GIFT;
552 }
553}
554
555feature! {
556#![feature = "zerocopy"]
557
558#[cfg(any(target_os = "android", target_os = "linux"))]
575pub fn copy_file_range(
576 fd_in: RawFd,
577 off_in: Option<&mut libc::loff_t>,
578 fd_out: RawFd,
579 off_out: Option<&mut libc::loff_t>,
580 len: usize,
581) -> Result<usize> {
582 let off_in = off_in
583 .map(|offset| offset as *mut libc::loff_t)
584 .unwrap_or(ptr::null_mut());
585 let off_out = off_out
586 .map(|offset| offset as *mut libc::loff_t)
587 .unwrap_or(ptr::null_mut());
588
589 let ret = unsafe {
590 libc::syscall(
591 libc::SYS_copy_file_range,
592 fd_in,
593 off_in,
594 fd_out,
595 off_out,
596 len,
597 0,
598 )
599 };
600 Errno::result(ret).map(|r| r as usize)
601}
602
603#[cfg(any(target_os = "linux", target_os = "android"))]
604pub fn splice(
605 fd_in: RawFd,
606 off_in: Option<&mut libc::loff_t>,
607 fd_out: RawFd,
608 off_out: Option<&mut libc::loff_t>,
609 len: usize,
610 flags: SpliceFFlags,
611) -> Result<usize> {
612 let off_in = off_in
613 .map(|offset| offset as *mut libc::loff_t)
614 .unwrap_or(ptr::null_mut());
615 let off_out = off_out
616 .map(|offset| offset as *mut libc::loff_t)
617 .unwrap_or(ptr::null_mut());
618
619 let ret = unsafe { libc::splice(fd_in, off_in, fd_out, off_out, len, flags.bits()) };
620 Errno::result(ret).map(|r| r as usize)
621}
622
623#[cfg(any(target_os = "linux", target_os = "android"))]
624pub fn tee(fd_in: RawFd, fd_out: RawFd, len: usize, flags: SpliceFFlags) -> Result<usize> {
625 let ret = unsafe { libc::tee(fd_in, fd_out, len, flags.bits()) };
626 Errno::result(ret).map(|r| r as usize)
627}
628
629#[cfg(any(target_os = "linux", target_os = "android"))]
630pub fn vmsplice(
631 fd: RawFd,
632 iov: &[std::io::IoSlice<'_>],
633 flags: SpliceFFlags
634 ) -> Result<usize>
635{
636 let ret = unsafe {
637 libc::vmsplice(
638 fd,
639 iov.as_ptr() as *const libc::iovec,
640 iov.len(),
641 flags.bits(),
642 )
643 };
644 Errno::result(ret).map(|r| r as usize)
645}
646}
647
648#[cfg(any(target_os = "linux"))]
649#[cfg(feature = "fs")]
650libc_bitflags!(
651 #[cfg_attr(docsrs, doc(cfg(feature = "fs")))]
653 pub struct FallocateFlags: c_int {
654 FALLOC_FL_KEEP_SIZE;
658 FALLOC_FL_PUNCH_HOLE;
662 FALLOC_FL_COLLAPSE_RANGE;
666 FALLOC_FL_ZERO_RANGE;
670 FALLOC_FL_INSERT_RANGE;
674 FALLOC_FL_UNSHARE_RANGE;
678 }
679);
680
681feature! {
682#![feature = "fs"]
683
684#[cfg(any(target_os = "linux"))]
689#[cfg(feature = "fs")]
690pub fn fallocate(
691 fd: RawFd,
692 mode: FallocateFlags,
693 offset: libc::off_t,
694 len: libc::off_t,
695) -> Result<()> {
696 let res = unsafe { libc::fallocate(fd, mode.bits(), offset, len) };
697 Errno::result(res).map(drop)
698}
699
700#[cfg(any(target_os = "freebsd"))]
703#[derive(Clone, Copy, Debug, Eq, PartialEq)]
704pub struct SpacectlRange(pub libc::off_t, pub libc::off_t);
705
706#[cfg(any(target_os = "freebsd"))]
707impl SpacectlRange {
708 #[inline]
709 pub fn is_empty(&self) -> bool {
710 self.1 == 0
711 }
712
713 #[inline]
714 pub fn len(&self) -> libc::off_t {
715 self.1
716 }
717
718 #[inline]
719 pub fn offset(&self) -> libc::off_t {
720 self.0
721 }
722}
723
724#[cfg(target_os = "freebsd")]
764pub fn fspacectl(fd: RawFd, range: SpacectlRange) -> Result<SpacectlRange> {
765 let mut rqsr = libc::spacectl_range{r_offset: range.0, r_len: range.1};
766 let res = unsafe { libc::fspacectl(
767 fd,
768 libc::SPACECTL_DEALLOC, &rqsr,
770 0, &mut rqsr
772 )};
773 Errno::result(res).map(|_| SpacectlRange(rqsr.r_offset, rqsr.r_len))
774}
775
776#[cfg(target_os = "freebsd")]
807pub fn fspacectl_all(fd: RawFd, offset: libc::off_t, len: libc::off_t)
808 -> Result<()>
809{
810 let mut rqsr = libc::spacectl_range{r_offset: offset, r_len: len};
811 while rqsr.r_len > 0 {
812 let res = unsafe { libc::fspacectl(
813 fd,
814 libc::SPACECTL_DEALLOC, &rqsr,
816 0, &mut rqsr
818 )};
819 Errno::result(res)?;
820 }
821 Ok(())
822}
823
824#[cfg(any(
825 target_os = "linux",
826 target_os = "android",
827 target_os = "emscripten",
828 target_os = "fuchsia",
829 any(target_os = "wasi", target_env = "wasi"),
830 target_env = "uclibc",
831 target_os = "freebsd"
832))]
833mod posix_fadvise {
834 use crate::errno::Errno;
835 use std::os::unix::io::RawFd;
836 use crate::Result;
837
838 #[cfg(feature = "fs")]
839 libc_enum! {
840 #[repr(i32)]
841 #[non_exhaustive]
842 #[cfg_attr(docsrs, doc(cfg(feature = "fs")))]
843 pub enum PosixFadviseAdvice {
844 POSIX_FADV_NORMAL,
845 POSIX_FADV_SEQUENTIAL,
846 POSIX_FADV_RANDOM,
847 POSIX_FADV_NOREUSE,
848 POSIX_FADV_WILLNEED,
849 POSIX_FADV_DONTNEED,
850 }
851 }
852
853 feature! {
854 #![feature = "fs"]
855 pub fn posix_fadvise(
856 fd: RawFd,
857 offset: libc::off_t,
858 len: libc::off_t,
859 advice: PosixFadviseAdvice,
860 ) -> Result<()> {
861 let res = unsafe { libc::posix_fadvise(fd, offset, len, advice as libc::c_int) };
862
863 if res == 0 {
864 Ok(())
865 } else {
866 Err(Errno::from_i32(res))
867 }
868 }
869 }
870}
871
872#[cfg(any(
873 target_os = "linux",
874 target_os = "android",
875 target_os = "dragonfly",
876 target_os = "emscripten",
877 target_os = "fuchsia",
878 any(target_os = "wasi", target_env = "wasi"),
879 target_os = "freebsd"
880))]
881pub fn posix_fallocate(fd: RawFd, offset: libc::off_t, len: libc::off_t) -> Result<()> {
882 let res = unsafe { libc::posix_fallocate(fd, offset, len) };
883 match Errno::result(res) {
884 Err(err) => Err(err),
885 Ok(0) => Ok(()),
886 Ok(errno) => Err(Errno::from_i32(errno)),
887 }
888}
889}