1 use crate::backend::c; 2 use bitflags::bitflags; 3 4 #[cfg(not(any(target_os = "espidf", target_os = "vita")))] 5 bitflags! { 6 /// `*_OK` constants for use with [`accessat`]. 7 /// 8 /// [`accessat`]: fn.accessat.html 9 #[repr(transparent)] 10 #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] 11 pub struct Access: c::c_int { 12 /// `R_OK` 13 const READ_OK = c::R_OK; 14 15 /// `W_OK` 16 const WRITE_OK = c::W_OK; 17 18 /// `X_OK` 19 const EXEC_OK = c::X_OK; 20 21 /// `F_OK` 22 const EXISTS = c::F_OK; 23 24 /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> 25 const _ = !0; 26 } 27 } 28 29 #[cfg(not(any(target_os = "espidf", target_os = "redox")))] 30 bitflags! { 31 /// `AT_*` constants for use with [`openat`], [`statat`], and other `*at` 32 /// functions. 33 /// 34 /// [`openat`]: crate::fs::openat 35 /// [`statat`]: crate::fs::statat 36 #[repr(transparent)] 37 #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] 38 pub struct AtFlags: u32 { 39 /// `AT_SYMLINK_NOFOLLOW` 40 const SYMLINK_NOFOLLOW = bitcast!(c::AT_SYMLINK_NOFOLLOW); 41 42 /// `AT_EACCESS` 43 #[cfg(not(any(target_os = "emscripten", target_os = "android")))] 44 const EACCESS = bitcast!(c::AT_EACCESS); 45 46 /// `AT_REMOVEDIR` 47 const REMOVEDIR = bitcast!(c::AT_REMOVEDIR); 48 49 /// `AT_SYMLINK_FOLLOW` 50 const SYMLINK_FOLLOW = bitcast!(c::AT_SYMLINK_FOLLOW); 51 52 /// `AT_NO_AUTOMOUNT` 53 #[cfg(any(linux_like, target_os = "fuchsia"))] 54 const NO_AUTOMOUNT = bitcast!(c::AT_NO_AUTOMOUNT); 55 56 /// `AT_EMPTY_PATH` 57 #[cfg(any( 58 linux_kernel, 59 target_os = "freebsd", 60 target_os = "fuchsia", 61 ))] 62 const EMPTY_PATH = bitcast!(c::AT_EMPTY_PATH); 63 64 /// `AT_RESOLVE_BENEATH` 65 #[cfg(target_os = "freebsd")] 66 const RESOLVE_BENEATH = bitcast!(c::AT_RESOLVE_BENEATH); 67 68 /// `AT_STATX_SYNC_AS_STAT` 69 #[cfg(all(target_os = "linux", target_env = "gnu"))] 70 const STATX_SYNC_AS_STAT = bitcast!(c::AT_STATX_SYNC_AS_STAT); 71 72 /// `AT_STATX_FORCE_SYNC` 73 #[cfg(all(target_os = "linux", target_env = "gnu"))] 74 const STATX_FORCE_SYNC = bitcast!(c::AT_STATX_FORCE_SYNC); 75 76 /// `AT_STATX_DONT_SYNC` 77 #[cfg(all(target_os = "linux", target_env = "gnu"))] 78 const STATX_DONT_SYNC = bitcast!(c::AT_STATX_DONT_SYNC); 79 80 /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> 81 const _ = !0; 82 } 83 } 84 85 bitflags! { 86 /// `S_I*` constants for use with [`openat`], [`chmodat`], and [`fchmod`]. 87 /// 88 /// [`openat`]: crate::fs::openat 89 /// [`chmodat`]: crate::fs::chmodat 90 /// [`fchmod`]: crate::fs::fchmod 91 #[repr(transparent)] 92 #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] 93 pub struct Mode: RawMode { 94 /// `S_IRWXU` 95 #[cfg(not(any(target_os = "espidf", target_os = "vita")))] 96 const RWXU = c::S_IRWXU as RawMode; 97 98 /// `S_IRUSR` 99 #[cfg(not(any(target_os = "espidf", target_os = "vita")))] 100 const RUSR = c::S_IRUSR as RawMode; 101 102 /// `S_IWUSR` 103 #[cfg(not(any(target_os = "espidf", target_os = "vita")))] 104 const WUSR = c::S_IWUSR as RawMode; 105 106 /// `S_IXUSR` 107 #[cfg(not(any(target_os = "espidf", target_os = "vita")))] 108 const XUSR = c::S_IXUSR as RawMode; 109 110 /// `S_IRWXG` 111 #[cfg(not(any(target_os = "espidf", target_os = "vita")))] 112 const RWXG = c::S_IRWXG as RawMode; 113 114 /// `S_IRGRP` 115 #[cfg(not(any(target_os = "espidf", target_os = "vita")))] 116 const RGRP = c::S_IRGRP as RawMode; 117 118 /// `S_IWGRP` 119 #[cfg(not(any(target_os = "espidf", target_os = "vita")))] 120 const WGRP = c::S_IWGRP as RawMode; 121 122 /// `S_IXGRP` 123 #[cfg(not(any(target_os = "espidf", target_os = "vita")))] 124 const XGRP = c::S_IXGRP as RawMode; 125 126 /// `S_IRWXO` 127 #[cfg(not(any(target_os = "espidf", target_os = "vita")))] 128 const RWXO = c::S_IRWXO as RawMode; 129 130 /// `S_IROTH` 131 #[cfg(not(any(target_os = "espidf", target_os = "vita")))] 132 const ROTH = c::S_IROTH as RawMode; 133 134 /// `S_IWOTH` 135 #[cfg(not(any(target_os = "espidf", target_os = "vita")))] 136 const WOTH = c::S_IWOTH as RawMode; 137 138 /// `S_IXOTH` 139 #[cfg(not(any(target_os = "espidf", target_os = "vita")))] 140 const XOTH = c::S_IXOTH as RawMode; 141 142 /// `S_ISUID` 143 #[cfg(not(any(target_os = "espidf", target_os = "vita")))] 144 const SUID = c::S_ISUID as RawMode; 145 146 /// `S_ISGID` 147 #[cfg(not(any(target_os = "espidf", target_os = "vita")))] 148 const SGID = c::S_ISGID as RawMode; 149 150 /// `S_ISVTX` 151 #[cfg(not(any(target_os = "espidf", target_os = "vita")))] 152 const SVTX = c::S_ISVTX as RawMode; 153 154 /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> 155 const _ = !0; 156 } 157 } 158 159 #[cfg(not(target_os = "espidf"))] 160 impl Mode { 161 /// Construct a `Mode` from the mode bits of the `st_mode` field of a 162 /// `Mode`. 163 #[inline] from_raw_mode(st_mode: RawMode) -> Self164 pub const fn from_raw_mode(st_mode: RawMode) -> Self { 165 Self::from_bits_truncate(st_mode) 166 } 167 168 /// Construct an `st_mode` value from a `Mode`. 169 #[inline] as_raw_mode(self) -> RawMode170 pub const fn as_raw_mode(self) -> RawMode { 171 self.bits() 172 } 173 } 174 175 #[cfg(not(target_os = "espidf"))] 176 impl From<RawMode> for Mode { 177 /// Support conversions from raw mode values to `Mode`. 178 /// 179 /// ``` 180 /// use rustix::fs::{Mode, RawMode}; 181 /// assert_eq!(Mode::from(0o700), Mode::RWXU); 182 /// ``` 183 #[inline] from(st_mode: RawMode) -> Self184 fn from(st_mode: RawMode) -> Self { 185 Self::from_raw_mode(st_mode) 186 } 187 } 188 189 #[cfg(not(target_os = "espidf"))] 190 impl From<Mode> for RawMode { 191 /// Support conversions from `Mode` to raw mode values. 192 /// 193 /// ``` 194 /// use rustix::fs::{Mode, RawMode}; 195 /// assert_eq!(RawMode::from(Mode::RWXU), 0o700); 196 /// ``` 197 #[inline] from(mode: Mode) -> Self198 fn from(mode: Mode) -> Self { 199 mode.as_raw_mode() 200 } 201 } 202 203 bitflags! { 204 /// `O_*` constants for use with [`openat`]. 205 /// 206 /// [`openat`]: crate::fs::openat 207 #[repr(transparent)] 208 #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] 209 pub struct OFlags: u32 { 210 /// `O_ACCMODE` 211 const ACCMODE = bitcast!(c::O_ACCMODE); 212 213 /// Similar to `ACCMODE`, but just includes the read/write flags, and 214 /// no other flags. 215 /// 216 /// On some platforms, `PATH` may be included in `ACCMODE`, when 217 /// sometimes we really just want the read/write bits. Caution is 218 /// indicated, as the presence of `PATH` may mean that the read/write 219 /// bits don't have their usual meaning. 220 const RWMODE = bitcast!(c::O_RDONLY | c::O_WRONLY | c::O_RDWR); 221 222 /// `O_APPEND` 223 const APPEND = bitcast!(c::O_APPEND); 224 225 /// `O_CREAT` 226 #[doc(alias = "CREAT")] 227 const CREATE = bitcast!(c::O_CREAT); 228 229 /// `O_DIRECTORY` 230 #[cfg(not(target_os = "espidf"))] 231 const DIRECTORY = bitcast!(c::O_DIRECTORY); 232 233 /// `O_DSYNC` 234 #[cfg(not(any(target_os = "dragonfly", target_os = "espidf", target_os = "l4re", target_os = "redox", target_os = "vita")))] 235 const DSYNC = bitcast!(c::O_DSYNC); 236 237 /// `O_EXCL` 238 const EXCL = bitcast!(c::O_EXCL); 239 240 /// `O_FSYNC` 241 #[cfg(any( 242 bsd, 243 all(target_os = "linux", not(target_env = "musl")), 244 ))] 245 const FSYNC = bitcast!(c::O_FSYNC); 246 247 /// `O_NOFOLLOW` 248 #[cfg(not(target_os = "espidf"))] 249 const NOFOLLOW = bitcast!(c::O_NOFOLLOW); 250 251 /// `O_NONBLOCK` 252 const NONBLOCK = bitcast!(c::O_NONBLOCK); 253 254 /// `O_RDONLY` 255 const RDONLY = bitcast!(c::O_RDONLY); 256 257 /// `O_WRONLY` 258 const WRONLY = bitcast!(c::O_WRONLY); 259 260 /// `O_RDWR` 261 /// 262 /// This is not equal to `RDONLY | WRONLY`. It's a distinct flag. 263 const RDWR = bitcast!(c::O_RDWR); 264 265 /// `O_NOCTTY` 266 #[cfg(not(any(target_os = "espidf", target_os = "l4re", target_os = "redox", target_os = "vita")))] 267 const NOCTTY = bitcast!(c::O_NOCTTY); 268 269 /// `O_RSYNC` 270 #[cfg(any( 271 linux_kernel, 272 netbsdlike, 273 target_os = "emscripten", 274 target_os = "wasi", 275 ))] 276 const RSYNC = bitcast!(c::O_RSYNC); 277 278 /// `O_SYNC` 279 #[cfg(not(any(target_os = "l4re", target_os = "redox")))] 280 const SYNC = bitcast!(c::O_SYNC); 281 282 /// `O_TRUNC` 283 const TRUNC = bitcast!(c::O_TRUNC); 284 285 /// `O_PATH` 286 #[cfg(any( 287 linux_kernel, 288 target_os = "emscripten", 289 target_os = "freebsd", 290 target_os = "fuchsia", 291 target_os = "redox", 292 ))] 293 const PATH = bitcast!(c::O_PATH); 294 295 /// `O_CLOEXEC` 296 const CLOEXEC = bitcast!(c::O_CLOEXEC); 297 298 /// `O_TMPFILE` 299 #[cfg(any( 300 linux_kernel, 301 target_os = "emscripten", 302 target_os = "fuchsia", 303 ))] 304 const TMPFILE = bitcast!(c::O_TMPFILE); 305 306 /// `O_NOATIME` 307 #[cfg(any( 308 linux_kernel, 309 target_os = "fuchsia", 310 ))] 311 const NOATIME = bitcast!(c::O_NOATIME); 312 313 /// `O_DIRECT` 314 #[cfg(any( 315 linux_kernel, 316 target_os = "emscripten", 317 target_os = "freebsd", 318 target_os = "fuchsia", 319 target_os = "netbsd", 320 ))] 321 const DIRECT = bitcast!(c::O_DIRECT); 322 323 /// `O_RESOLVE_BENEATH` 324 #[cfg(target_os = "freebsd")] 325 const RESOLVE_BENEATH = bitcast!(c::O_RESOLVE_BENEATH); 326 327 /// `O_EMPTY_PATH` 328 #[cfg(target_os = "freebsd")] 329 const EMPTY_PATH = bitcast!(c::O_EMPTY_PATH); 330 331 /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> 332 const _ = !0; 333 } 334 } 335 336 #[cfg(apple)] 337 bitflags! { 338 /// `CLONE_*` constants for use with [`fclonefileat`]. 339 /// 340 /// [`fclonefileat`]: crate::fs::fclonefileat 341 #[repr(transparent)] 342 #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] 343 pub struct CloneFlags: u32 { 344 /// `CLONE_NOFOLLOW` 345 const NOFOLLOW = 1; 346 347 /// `CLONE_NOOWNERCOPY` 348 const NOOWNERCOPY = 2; 349 350 /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> 351 const _ = !0; 352 } 353 } 354 355 #[cfg(apple)] 356 mod copyfile { 357 pub(super) const ACL: u32 = 1 << 0; 358 pub(super) const STAT: u32 = 1 << 1; 359 pub(super) const XATTR: u32 = 1 << 2; 360 pub(super) const DATA: u32 = 1 << 3; 361 pub(super) const SECURITY: u32 = STAT | ACL; 362 pub(super) const METADATA: u32 = SECURITY | XATTR; 363 pub(super) const ALL: u32 = METADATA | DATA; 364 } 365 366 #[cfg(apple)] 367 bitflags! { 368 /// `COPYFILE_*` constants for use with [`fcopyfile`]. 369 /// 370 /// [`fcopyfile`]: crate::fs::fcopyfile 371 #[repr(transparent)] 372 #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] 373 pub struct CopyfileFlags: c::c_uint { 374 /// `COPYFILE_ACL` 375 const ACL = copyfile::ACL; 376 377 /// `COPYFILE_STAT` 378 const STAT = copyfile::STAT; 379 380 /// `COPYFILE_XATTR` 381 const XATTR = copyfile::XATTR; 382 383 /// `COPYFILE_DATA` 384 const DATA = copyfile::DATA; 385 386 /// `COPYFILE_SECURITY` 387 const SECURITY = copyfile::SECURITY; 388 389 /// `COPYFILE_METADATA` 390 const METADATA = copyfile::METADATA; 391 392 /// `COPYFILE_ALL` 393 const ALL = copyfile::ALL; 394 395 /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> 396 const _ = !0; 397 } 398 } 399 400 #[cfg(linux_kernel)] 401 bitflags! { 402 /// `RESOLVE_*` constants for use with [`openat2`]. 403 /// 404 /// [`openat2`]: crate::fs::openat2 405 #[repr(transparent)] 406 #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)] 407 pub struct ResolveFlags: u64 { 408 /// `RESOLVE_NO_XDEV` 409 const NO_XDEV = 0x01; 410 411 /// `RESOLVE_NO_MAGICLINKS` 412 const NO_MAGICLINKS = 0x02; 413 414 /// `RESOLVE_NO_SYMLINKS` 415 const NO_SYMLINKS = 0x04; 416 417 /// `RESOLVE_BENEATH` 418 const BENEATH = 0x08; 419 420 /// `RESOLVE_IN_ROOT` 421 const IN_ROOT = 0x10; 422 423 /// `RESOLVE_CACHED` (since Linux 5.12) 424 const CACHED = 0x20; 425 426 /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> 427 const _ = !0; 428 } 429 } 430 431 #[cfg(linux_kernel)] 432 bitflags! { 433 /// `RENAME_*` constants for use with [`renameat_with`]. 434 /// 435 /// [`renameat_with`]: crate::fs::renameat_with 436 #[repr(transparent)] 437 #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] 438 pub struct RenameFlags: c::c_uint { 439 /// `RENAME_EXCHANGE` 440 const EXCHANGE = bitcast!(c::RENAME_EXCHANGE); 441 442 /// `RENAME_NOREPLACE` 443 const NOREPLACE = bitcast!(c::RENAME_NOREPLACE); 444 445 /// `RENAME_WHITEOUT` 446 const WHITEOUT = bitcast!(c::RENAME_WHITEOUT); 447 448 /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> 449 const _ = !0; 450 } 451 } 452 453 /// `S_IF*` constants for use with [`mknodat`] and [`Stat`]'s `st_mode` field. 454 /// 455 /// [`mknodat`]: crate::fs::mknodat 456 /// [`Stat`]: crate::fs::Stat 457 #[derive(Clone, Copy, Debug, PartialEq, Eq)] 458 pub enum FileType { 459 /// `S_IFREG` 460 RegularFile = c::S_IFREG as isize, 461 462 /// `S_IFDIR` 463 Directory = c::S_IFDIR as isize, 464 465 /// `S_IFLNK` 466 Symlink = c::S_IFLNK as isize, 467 468 /// `S_IFIFO` 469 #[cfg(not(target_os = "wasi"))] // TODO: Use WASI's `S_IFIFO`. 470 #[doc(alias = "IFO")] 471 Fifo = c::S_IFIFO as isize, 472 473 /// `S_IFSOCK` 474 #[cfg(not(target_os = "wasi"))] // TODO: Use WASI's `S_IFSOCK`. 475 Socket = c::S_IFSOCK as isize, 476 477 /// `S_IFCHR` 478 CharacterDevice = c::S_IFCHR as isize, 479 480 /// `S_IFBLK` 481 BlockDevice = c::S_IFBLK as isize, 482 483 /// An unknown filesystem object. 484 Unknown, 485 } 486 487 impl FileType { 488 /// Construct a `FileType` from the `S_IFMT` bits of the `st_mode` field of 489 /// a `Stat`. 490 #[inline] from_raw_mode(st_mode: RawMode) -> Self491 pub const fn from_raw_mode(st_mode: RawMode) -> Self { 492 match (st_mode as c::mode_t) & c::S_IFMT { 493 c::S_IFREG => Self::RegularFile, 494 c::S_IFDIR => Self::Directory, 495 c::S_IFLNK => Self::Symlink, 496 #[cfg(not(target_os = "wasi"))] // TODO: Use WASI's `S_IFIFO`. 497 c::S_IFIFO => Self::Fifo, 498 #[cfg(not(target_os = "wasi"))] // TODO: Use WASI's `S_IFSOCK`. 499 c::S_IFSOCK => Self::Socket, 500 c::S_IFCHR => Self::CharacterDevice, 501 c::S_IFBLK => Self::BlockDevice, 502 _ => Self::Unknown, 503 } 504 } 505 506 /// Construct an `st_mode` value from a `FileType`. 507 #[inline] as_raw_mode(self) -> RawMode508 pub const fn as_raw_mode(self) -> RawMode { 509 match self { 510 Self::RegularFile => c::S_IFREG as RawMode, 511 Self::Directory => c::S_IFDIR as RawMode, 512 Self::Symlink => c::S_IFLNK as RawMode, 513 #[cfg(not(target_os = "wasi"))] // TODO: Use WASI's `S_IFIFO`. 514 Self::Fifo => c::S_IFIFO as RawMode, 515 #[cfg(not(target_os = "wasi"))] // TODO: Use WASI's `S_IFSOCK`. 516 Self::Socket => c::S_IFSOCK as RawMode, 517 Self::CharacterDevice => c::S_IFCHR as RawMode, 518 Self::BlockDevice => c::S_IFBLK as RawMode, 519 Self::Unknown => c::S_IFMT as RawMode, 520 } 521 } 522 523 /// Construct a `FileType` from the `d_type` field of a `c::dirent`. 524 #[cfg(not(any( 525 solarish, 526 target_os = "aix", 527 target_os = "espidf", 528 target_os = "haiku", 529 target_os = "nto", 530 target_os = "redox", 531 target_os = "vita" 532 )))] 533 #[inline] from_dirent_d_type(d_type: u8) -> Self534 pub(crate) const fn from_dirent_d_type(d_type: u8) -> Self { 535 match d_type { 536 c::DT_REG => Self::RegularFile, 537 c::DT_DIR => Self::Directory, 538 c::DT_LNK => Self::Symlink, 539 #[cfg(not(target_os = "wasi"))] // TODO: Use WASI's `DT_SOCK`. 540 c::DT_SOCK => Self::Socket, 541 #[cfg(not(target_os = "wasi"))] // TODO: Use WASI's `DT_FIFO`. 542 c::DT_FIFO => Self::Fifo, 543 c::DT_CHR => Self::CharacterDevice, 544 c::DT_BLK => Self::BlockDevice, 545 // c::DT_UNKNOWN | 546 _ => Self::Unknown, 547 } 548 } 549 } 550 551 /// `POSIX_FADV_*` constants for use with [`fadvise`]. 552 /// 553 /// [`fadvise`]: crate::fs::fadvise 554 #[cfg(not(any( 555 apple, 556 netbsdlike, 557 solarish, 558 target_os = "dragonfly", 559 target_os = "espidf", 560 target_os = "haiku", 561 target_os = "redox", 562 target_os = "vita", 563 )))] 564 #[derive(Debug, Copy, Clone, Eq, PartialEq)] 565 #[repr(u32)] 566 pub enum Advice { 567 /// `POSIX_FADV_NORMAL` 568 Normal = c::POSIX_FADV_NORMAL as c::c_uint, 569 570 /// `POSIX_FADV_SEQUENTIAL` 571 Sequential = c::POSIX_FADV_SEQUENTIAL as c::c_uint, 572 573 /// `POSIX_FADV_RANDOM` 574 Random = c::POSIX_FADV_RANDOM as c::c_uint, 575 576 /// `POSIX_FADV_NOREUSE` 577 NoReuse = c::POSIX_FADV_NOREUSE as c::c_uint, 578 579 /// `POSIX_FADV_WILLNEED` 580 WillNeed = c::POSIX_FADV_WILLNEED as c::c_uint, 581 582 /// `POSIX_FADV_DONTNEED` 583 DontNeed = c::POSIX_FADV_DONTNEED as c::c_uint, 584 } 585 586 #[cfg(any(linux_kernel, target_os = "freebsd"))] 587 bitflags! { 588 /// `MFD_*` constants for use with [`memfd_create`]. 589 /// 590 /// [`memfd_create`]: crate::fs::memfd_create 591 #[repr(transparent)] 592 #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] 593 pub struct MemfdFlags: c::c_uint { 594 /// `MFD_CLOEXEC` 595 const CLOEXEC = c::MFD_CLOEXEC; 596 597 /// `MFD_ALLOW_SEALING` 598 const ALLOW_SEALING = c::MFD_ALLOW_SEALING; 599 600 /// `MFD_HUGETLB` (since Linux 4.14) 601 const HUGETLB = c::MFD_HUGETLB; 602 603 /// `MFD_HUGE_64KB` 604 const HUGE_64KB = c::MFD_HUGE_64KB; 605 /// `MFD_HUGE_512JB` 606 const HUGE_512KB = c::MFD_HUGE_512KB; 607 /// `MFD_HUGE_1MB` 608 const HUGE_1MB = c::MFD_HUGE_1MB; 609 /// `MFD_HUGE_2MB` 610 const HUGE_2MB = c::MFD_HUGE_2MB; 611 /// `MFD_HUGE_8MB` 612 const HUGE_8MB = c::MFD_HUGE_8MB; 613 /// `MFD_HUGE_16MB` 614 const HUGE_16MB = c::MFD_HUGE_16MB; 615 /// `MFD_HUGE_32MB` 616 const HUGE_32MB = c::MFD_HUGE_32MB; 617 /// `MFD_HUGE_256MB` 618 const HUGE_256MB = c::MFD_HUGE_256MB; 619 /// `MFD_HUGE_512MB` 620 const HUGE_512MB = c::MFD_HUGE_512MB; 621 /// `MFD_HUGE_1GB` 622 const HUGE_1GB = c::MFD_HUGE_1GB; 623 /// `MFD_HUGE_2GB` 624 const HUGE_2GB = c::MFD_HUGE_2GB; 625 /// `MFD_HUGE_16GB` 626 const HUGE_16GB = c::MFD_HUGE_16GB; 627 628 /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> 629 const _ = !0; 630 } 631 } 632 633 #[cfg(any(linux_kernel, target_os = "freebsd", target_os = "fuchsia"))] 634 bitflags! { 635 /// `F_SEAL_*` constants for use with [`fcntl_add_seals`] and 636 /// [`fcntl_get_seals`]. 637 /// 638 /// [`fcntl_add_seals`]: crate::fs::fcntl_add_seals 639 /// [`fcntl_get_seals`]: crate::fs::fcntl_get_seals 640 #[repr(transparent)] 641 #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] 642 pub struct SealFlags: u32 { 643 /// `F_SEAL_SEAL` 644 const SEAL = bitcast!(c::F_SEAL_SEAL); 645 /// `F_SEAL_SHRINK` 646 const SHRINK = bitcast!(c::F_SEAL_SHRINK); 647 /// `F_SEAL_GROW` 648 const GROW = bitcast!(c::F_SEAL_GROW); 649 /// `F_SEAL_WRITE` 650 const WRITE = bitcast!(c::F_SEAL_WRITE); 651 /// `F_SEAL_FUTURE_WRITE` (since Linux 5.1) 652 #[cfg(linux_kernel)] 653 const FUTURE_WRITE = bitcast!(c::F_SEAL_FUTURE_WRITE); 654 655 /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> 656 const _ = !0; 657 } 658 } 659 660 #[cfg(all(target_os = "linux", target_env = "gnu"))] 661 bitflags! { 662 /// `STATX_*` constants for use with [`statx`]. 663 /// 664 /// [`statx`]: crate::fs::statx 665 #[repr(transparent)] 666 #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] 667 pub struct StatxFlags: u32 { 668 /// `STATX_TYPE` 669 const TYPE = c::STATX_TYPE; 670 671 /// `STATX_MODE` 672 const MODE = c::STATX_MODE; 673 674 /// `STATX_NLINK` 675 const NLINK = c::STATX_NLINK; 676 677 /// `STATX_UID` 678 const UID = c::STATX_UID; 679 680 /// `STATX_GID` 681 const GID = c::STATX_GID; 682 683 /// `STATX_ATIME` 684 const ATIME = c::STATX_ATIME; 685 686 /// `STATX_MTIME` 687 const MTIME = c::STATX_MTIME; 688 689 /// `STATX_CTIME` 690 const CTIME = c::STATX_CTIME; 691 692 /// `STATX_INO` 693 const INO = c::STATX_INO; 694 695 /// `STATX_SIZE` 696 const SIZE = c::STATX_SIZE; 697 698 /// `STATX_BLOCKS` 699 const BLOCKS = c::STATX_BLOCKS; 700 701 /// `STATX_BASIC_STATS` 702 const BASIC_STATS = c::STATX_BASIC_STATS; 703 704 /// `STATX_BTIME` 705 const BTIME = c::STATX_BTIME; 706 707 /// `STATX_MNT_ID` (since Linux 5.8) 708 const MNT_ID = c::STATX_MNT_ID; 709 710 /// `STATX_DIOALIGN` (since Linux 6.1) 711 const DIOALIGN = c::STATX_DIOALIGN; 712 713 /// `STATX_ALL` 714 const ALL = c::STATX_ALL; 715 716 /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> 717 const _ = !0; 718 } 719 } 720 721 #[cfg(any( 722 target_os = "android", 723 all(target_os = "linux", not(target_env = "gnu")), 724 ))] 725 bitflags! { 726 /// `STATX_*` constants for use with [`statx`]. 727 /// 728 /// [`statx`]: crate::fs::statx 729 #[repr(transparent)] 730 #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] 731 pub struct StatxFlags: u32 { 732 /// `STATX_TYPE` 733 const TYPE = 0x0001; 734 735 /// `STATX_MODE` 736 const MODE = 0x0002; 737 738 /// `STATX_NLINK` 739 const NLINK = 0x0004; 740 741 /// `STATX_UID` 742 const UID = 0x0008; 743 744 /// `STATX_GID` 745 const GID = 0x0010; 746 747 /// `STATX_ATIME` 748 const ATIME = 0x0020; 749 750 /// `STATX_MTIME` 751 const MTIME = 0x0040; 752 753 /// `STATX_CTIME` 754 const CTIME = 0x0080; 755 756 /// `STATX_INO` 757 const INO = 0x0100; 758 759 /// `STATX_SIZE` 760 const SIZE = 0x0200; 761 762 /// `STATX_BLOCKS` 763 const BLOCKS = 0x0400; 764 765 /// `STATX_BASIC_STATS` 766 const BASIC_STATS = 0x07ff; 767 768 /// `STATX_BTIME` 769 const BTIME = 0x800; 770 771 /// `STATX_MNT_ID` (since Linux 5.8) 772 const MNT_ID = 0x1000; 773 774 /// `STATX_ALL` 775 const ALL = 0xfff; 776 777 /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> 778 const _ = !0; 779 } 780 } 781 782 #[cfg(not(any( 783 netbsdlike, 784 solarish, 785 target_os = "aix", 786 target_os = "espidf", 787 target_os = "nto", 788 target_os = "redox", 789 target_os = "vita" 790 )))] 791 bitflags! { 792 /// `FALLOC_FL_*` constants for use with [`fallocate`]. 793 /// 794 /// [`fallocate`]: crate::fs::fallocate 795 #[repr(transparent)] 796 #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] 797 pub struct FallocateFlags: u32 { 798 /// `FALLOC_FL_KEEP_SIZE` 799 #[cfg(not(any( 800 bsd, 801 target_os = "aix", 802 target_os = "haiku", 803 target_os = "hurd", 804 target_os = "wasi", 805 )))] 806 const KEEP_SIZE = bitcast!(c::FALLOC_FL_KEEP_SIZE); 807 /// `FALLOC_FL_PUNCH_HOLE` 808 #[cfg(not(any( 809 bsd, 810 target_os = "aix", 811 target_os = "haiku", 812 target_os = "hurd", 813 target_os = "wasi", 814 )))] 815 const PUNCH_HOLE = bitcast!(c::FALLOC_FL_PUNCH_HOLE); 816 /// `FALLOC_FL_NO_HIDE_STALE` 817 #[cfg(not(any( 818 bsd, 819 target_os = "aix", 820 target_os = "emscripten", 821 target_os = "fuchsia", 822 target_os = "haiku", 823 target_os = "hurd", 824 target_os = "l4re", 825 target_os = "linux", 826 target_os = "wasi", 827 )))] 828 const NO_HIDE_STALE = bitcast!(c::FALLOC_FL_NO_HIDE_STALE); 829 /// `FALLOC_FL_COLLAPSE_RANGE` 830 #[cfg(not(any( 831 bsd, 832 target_os = "aix", 833 target_os = "haiku", 834 target_os = "hurd", 835 target_os = "emscripten", 836 target_os = "wasi", 837 )))] 838 const COLLAPSE_RANGE = bitcast!(c::FALLOC_FL_COLLAPSE_RANGE); 839 /// `FALLOC_FL_ZERO_RANGE` 840 #[cfg(not(any( 841 bsd, 842 target_os = "aix", 843 target_os = "haiku", 844 target_os = "hurd", 845 target_os = "emscripten", 846 target_os = "wasi", 847 )))] 848 const ZERO_RANGE = bitcast!(c::FALLOC_FL_ZERO_RANGE); 849 /// `FALLOC_FL_INSERT_RANGE` 850 #[cfg(not(any( 851 bsd, 852 target_os = "aix", 853 target_os = "haiku", 854 target_os = "hurd", 855 target_os = "emscripten", 856 target_os = "wasi", 857 )))] 858 const INSERT_RANGE = bitcast!(c::FALLOC_FL_INSERT_RANGE); 859 /// `FALLOC_FL_UNSHARE_RANGE` 860 #[cfg(not(any( 861 bsd, 862 target_os = "aix", 863 target_os = "haiku", 864 target_os = "hurd", 865 target_os = "emscripten", 866 target_os = "wasi", 867 )))] 868 const UNSHARE_RANGE = bitcast!(c::FALLOC_FL_UNSHARE_RANGE); 869 870 /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> 871 const _ = !0; 872 } 873 } 874 875 #[cfg(not(any(target_os = "haiku", target_os = "redox", target_os = "wasi")))] 876 bitflags! { 877 /// `ST_*` constants for use with [`StatVfs`]. 878 #[repr(transparent)] 879 #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] 880 pub struct StatVfsMountFlags: u64 { 881 /// `ST_MANDLOCK` 882 #[cfg(any(linux_kernel, target_os = "emscripten", target_os = "fuchsia"))] 883 const MANDLOCK = c::ST_MANDLOCK as u64; 884 885 /// `ST_NOATIME` 886 #[cfg(any(linux_kernel, target_os = "emscripten", target_os = "fuchsia"))] 887 const NOATIME = c::ST_NOATIME as u64; 888 889 /// `ST_NODEV` 890 #[cfg(any( 891 linux_kernel, 892 target_os = "aix", 893 target_os = "emscripten", 894 target_os = "fuchsia" 895 ))] 896 const NODEV = c::ST_NODEV as u64; 897 898 /// `ST_NODIRATIME` 899 #[cfg(any(linux_kernel, target_os = "emscripten", target_os = "fuchsia"))] 900 const NODIRATIME = c::ST_NODIRATIME as u64; 901 902 /// `ST_NOEXEC` 903 #[cfg(any(linux_kernel, target_os = "emscripten", target_os = "fuchsia"))] 904 const NOEXEC = c::ST_NOEXEC as u64; 905 906 /// `ST_NOSUID` 907 #[cfg(not(any(target_os = "espidf", target_os = "vita")))] 908 const NOSUID = c::ST_NOSUID as u64; 909 910 /// `ST_RDONLY` 911 #[cfg(not(any(target_os = "espidf", target_os = "vita")))] 912 const RDONLY = c::ST_RDONLY as u64; 913 914 /// `ST_RELATIME` 915 #[cfg(any(target_os = "android", all(target_os = "linux", target_env = "gnu")))] 916 const RELATIME = c::ST_RELATIME as u64; 917 918 /// `ST_SYNCHRONOUS` 919 #[cfg(any(linux_kernel, target_os = "emscripten", target_os = "fuchsia"))] 920 const SYNCHRONOUS = c::ST_SYNCHRONOUS as u64; 921 922 /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> 923 const _ = !0; 924 } 925 } 926 927 /// `LOCK_*` constants for use with [`flock`] and [`fcntl_lock`]. 928 /// 929 /// [`flock`]: crate::fs::flock 930 /// [`fcntl_lock`]: crate::fs::fcntl_lock 931 #[cfg(not(any(target_os = "espidf", target_os = "vita", target_os = "wasi")))] 932 #[derive(Clone, Copy, Debug, PartialEq, Eq)] 933 #[repr(u32)] 934 pub enum FlockOperation { 935 /// `LOCK_SH` 936 LockShared = bitcast!(c::LOCK_SH), 937 /// `LOCK_EX` 938 LockExclusive = bitcast!(c::LOCK_EX), 939 /// `LOCK_UN` 940 Unlock = bitcast!(c::LOCK_UN), 941 /// `LOCK_SH | LOCK_NB` 942 NonBlockingLockShared = bitcast!(c::LOCK_SH | c::LOCK_NB), 943 /// `LOCK_EX | LOCK_NB` 944 NonBlockingLockExclusive = bitcast!(c::LOCK_EX | c::LOCK_NB), 945 /// `LOCK_UN | LOCK_NB` 946 NonBlockingUnlock = bitcast!(c::LOCK_UN | c::LOCK_NB), 947 } 948 949 /// `struct stat` for use with [`statat`] and [`fstat`]. 950 /// 951 /// [`statat`]: crate::fs::statat 952 /// [`fstat`]: crate::fs::fstat 953 #[cfg(not(any(linux_like, target_os = "hurd")))] 954 pub type Stat = c::stat; 955 956 /// `struct stat` for use with [`statat`] and [`fstat`]. 957 /// 958 /// [`statat`]: crate::fs::statat 959 /// [`fstat`]: crate::fs::fstat 960 #[cfg(any( 961 all(linux_kernel, target_pointer_width = "64"), 962 target_os = "hurd", 963 target_os = "emscripten", 964 target_os = "l4re", 965 ))] 966 pub type Stat = c::stat64; 967 968 /// `struct stat` for use with [`statat`] and [`fstat`]. 969 /// 970 /// [`statat`]: crate::fs::statat 971 /// [`fstat`]: crate::fs::fstat 972 // On 32-bit, Linux's `struct stat64` has a 32-bit `st_mtime` and friends, so 973 // we use our own struct, populated from `statx` where possible, to avoid the 974 // y2038 bug. 975 #[cfg(all(linux_kernel, target_pointer_width = "32"))] 976 #[repr(C)] 977 #[derive(Debug, Copy, Clone)] 978 #[allow(missing_docs)] 979 pub struct Stat { 980 pub st_dev: u64, 981 pub st_mode: u32, 982 pub st_nlink: u32, 983 pub st_uid: u32, 984 pub st_gid: u32, 985 pub st_rdev: u64, 986 pub st_size: i64, 987 pub st_blksize: u32, 988 pub st_blocks: u64, 989 #[deprecated(note = "Use `rustix::fs::StatExt::atime` instead.")] 990 pub st_atime: u64, 991 pub st_atime_nsec: u32, 992 #[deprecated(note = "Use `rustix::fs::StatExt::mtime` instead.")] 993 pub st_mtime: u64, 994 pub st_mtime_nsec: u32, 995 #[deprecated(note = "Use `rustix::fs::StatExt::ctime` instead.")] 996 pub st_ctime: u64, 997 pub st_ctime_nsec: u32, 998 pub st_ino: u64, 999 } 1000 1001 /// `struct statfs` for use with [`statfs`] and [`fstatfs`]. 1002 /// 1003 /// [`statfs`]: crate::fs::statfs 1004 /// [`fstatfs`]: crate::fs::fstatfs 1005 #[cfg(not(any( 1006 linux_like, 1007 solarish, 1008 target_os = "espidf", 1009 target_os = "haiku", 1010 target_os = "netbsd", 1011 target_os = "nto", 1012 target_os = "redox", 1013 target_os = "vita", 1014 target_os = "wasi", 1015 )))] 1016 #[allow(clippy::module_name_repetitions)] 1017 pub type StatFs = c::statfs; 1018 1019 /// `struct statfs` for use with [`statfs`] and [`fstatfs`]. 1020 /// 1021 /// [`statfs`]: crate::fs::statfs 1022 /// [`fstatfs`]: crate::fs::fstatfs 1023 #[cfg(linux_like)] 1024 pub type StatFs = c::statfs64; 1025 1026 /// `struct statvfs` for use with [`statvfs`] and [`fstatvfs`]. 1027 /// 1028 /// [`statvfs`]: crate::fs::statvfs 1029 /// [`fstatvfs`]: crate::fs::fstatvfs 1030 #[cfg(not(any(target_os = "haiku", target_os = "redox", target_os = "wasi")))] 1031 #[allow(missing_docs)] 1032 pub struct StatVfs { 1033 pub f_bsize: u64, 1034 pub f_frsize: u64, 1035 pub f_blocks: u64, 1036 pub f_bfree: u64, 1037 pub f_bavail: u64, 1038 pub f_files: u64, 1039 pub f_ffree: u64, 1040 pub f_favail: u64, 1041 pub f_fsid: u64, 1042 pub f_flag: StatVfsMountFlags, 1043 pub f_namemax: u64, 1044 } 1045 1046 /// `struct statx` for use with [`statx`]. 1047 /// 1048 /// [`statx`]: crate::fs::statx 1049 #[cfg(all(target_os = "linux", target_env = "gnu"))] 1050 // Use the glibc `struct statx`. 1051 pub type Statx = c::statx; 1052 1053 /// `struct statx_timestamp` for use with [`Statx`]. 1054 #[cfg(all(target_os = "linux", target_env = "gnu"))] 1055 // Use the glibc `struct statx_timestamp`. 1056 pub type StatxTimestamp = c::statx; 1057 1058 /// `struct statx` for use with [`statx`]. 1059 /// 1060 /// [`statx`]: crate::fs::statx 1061 // Non-glibc ABIs don't currently declare a `struct statx`, so we declare it 1062 // ourselves. 1063 #[cfg(any( 1064 target_os = "android", 1065 all(target_os = "linux", not(target_env = "gnu")), 1066 ))] 1067 #[repr(C)] 1068 #[allow(missing_docs)] 1069 pub struct Statx { 1070 pub stx_mask: u32, 1071 pub stx_blksize: u32, 1072 pub stx_attributes: u64, 1073 pub stx_nlink: u32, 1074 pub stx_uid: u32, 1075 pub stx_gid: u32, 1076 pub stx_mode: u16, 1077 __statx_pad1: [u16; 1], 1078 pub stx_ino: u64, 1079 pub stx_size: u64, 1080 pub stx_blocks: u64, 1081 pub stx_attributes_mask: u64, 1082 pub stx_atime: StatxTimestamp, 1083 pub stx_btime: StatxTimestamp, 1084 pub stx_ctime: StatxTimestamp, 1085 pub stx_mtime: StatxTimestamp, 1086 pub stx_rdev_major: u32, 1087 pub stx_rdev_minor: u32, 1088 pub stx_dev_major: u32, 1089 pub stx_dev_minor: u32, 1090 pub stx_mnt_id: u64, 1091 __statx_pad2: u64, 1092 __statx_pad3: [u64; 12], 1093 } 1094 1095 /// `struct statx_timestamp` for use with [`Statx`]. 1096 // Non-glibc ABIs don't currently declare a `struct statx_timestamp`, so we 1097 // declare it ourselves. 1098 #[cfg(any( 1099 target_os = "android", 1100 all(target_os = "linux", not(target_env = "gnu")), 1101 ))] 1102 #[repr(C)] 1103 #[allow(missing_docs)] 1104 pub struct StatxTimestamp { 1105 pub tv_sec: i64, 1106 pub tv_nsec: u32, 1107 pub __statx_timestamp_pad1: [i32; 1], 1108 } 1109 1110 /// `mode_t` 1111 #[cfg(not(all(target_os = "android", target_pointer_width = "32")))] 1112 pub type RawMode = c::mode_t; 1113 1114 /// `mode_t` 1115 #[cfg(all(target_os = "android", target_pointer_width = "32"))] 1116 pub type RawMode = c::c_uint; 1117 1118 /// `dev_t` 1119 #[cfg(not(all(target_os = "android", target_pointer_width = "32")))] 1120 pub type Dev = c::dev_t; 1121 1122 /// `dev_t` 1123 #[cfg(all(target_os = "android", target_pointer_width = "32"))] 1124 pub type Dev = c::c_ulonglong; 1125 1126 /// `__fsword_t` 1127 #[cfg(all( 1128 target_os = "linux", 1129 not(target_env = "musl"), 1130 not(target_arch = "s390x"), 1131 ))] 1132 pub type FsWord = c::__fsword_t; 1133 1134 /// `__fsword_t` 1135 #[cfg(all( 1136 any(target_os = "android", all(target_os = "linux", target_env = "musl")), 1137 target_pointer_width = "32", 1138 ))] 1139 pub type FsWord = u32; 1140 1141 /// `__fsword_t` 1142 #[cfg(all( 1143 any(target_os = "android", all(target_os = "linux", target_env = "musl")), 1144 not(target_arch = "s390x"), 1145 target_pointer_width = "64", 1146 ))] 1147 pub type FsWord = u64; 1148 1149 /// `__fsword_t` 1150 // s390x uses `u32` for `statfs` entries on glibc, even though `__fsword_t` is 1151 // `u64`. 1152 #[cfg(all(target_os = "linux", target_arch = "s390x", target_env = "gnu"))] 1153 pub type FsWord = u32; 1154 1155 /// `__fsword_t` 1156 // s390x uses `u64` for `statfs` entries on musl. 1157 #[cfg(all(target_os = "linux", target_arch = "s390x", target_env = "musl"))] 1158 pub type FsWord = u64; 1159 1160 /// `copyfile_state_t`—State for use with [`fcopyfile`]. 1161 /// 1162 /// [`fcopyfile`]: crate::fs::fcopyfile 1163 #[cfg(apple)] 1164 #[allow(non_camel_case_types)] 1165 #[repr(transparent)] 1166 #[derive(Copy, Clone)] 1167 pub struct copyfile_state_t(pub(crate) *mut c::c_void); 1168