1 //! Unix-specific extensions to primitives in the `std::fs` module.
3 #![stable(feature = "rust1", since = "1.0.0")]
5 use super::platform::fs::MetadataExt as _;
6 use crate::fs::{self, OpenOptions, Permissions};
8 use crate::os::unix::io::{AsFd, AsRawFd};
11 use crate::sys_common::{AsInner, AsInnerMut, FromInner};
12 // Used for `File::read` on intra-doc links
13 use crate::ffi::OsStr;
14 use crate::sealed::Sealed;
15 #[allow(unused_imports)]
16 use io::{Read, Write};
18 /// Unix-specific extensions to [`fs::File`].
19 #[stable(feature = "file_offset", since = "1.15.0")]
21 /// Reads a number of bytes starting from a given offset.
23 /// Returns the number of bytes read.
25 /// The offset is relative to the start of the file and thus independent
26 /// from the current cursor.
28 /// The current file cursor is not affected by this function.
30 /// Note that similar to [`File::read`], it is not an error to return with a
33 /// [`File::read`]: fs::File::read
39 /// use std::fs::File;
40 /// use std::os::unix::prelude::FileExt;
42 /// fn main() -> io::Result<()> {
43 /// let mut buf = [0u8; 8];
44 /// let file = File::open("foo.txt")?;
46 /// // We now read 8 bytes from the offset 10.
47 /// let num_bytes_read = file.read_at(&mut buf, 10)?;
48 /// println!("read {} bytes: {:?}", num_bytes_read, buf);
52 #[stable(feature = "file_offset", since = "1.15.0")]
53 fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result<usize>;
55 /// Reads the exact number of byte required to fill `buf` from the given offset.
57 /// The offset is relative to the start of the file and thus independent
58 /// from the current cursor.
60 /// The current file cursor is not affected by this function.
62 /// Similar to [`io::Read::read_exact`] but uses [`read_at`] instead of `read`.
64 /// [`read_at`]: FileExt::read_at
68 /// If this function encounters an error of the kind
69 /// [`io::ErrorKind::Interrupted`] then the error is ignored and the operation
72 /// If this function encounters an "end of file" before completely filling
73 /// the buffer, it returns an error of the kind [`io::ErrorKind::UnexpectedEof`].
74 /// The contents of `buf` are unspecified in this case.
76 /// If any other read error is encountered then this function immediately
77 /// returns. The contents of `buf` are unspecified in this case.
79 /// If this function returns an error, it is unspecified how many bytes it
80 /// has read, but it will never read more than would be necessary to
81 /// completely fill the buffer.
87 /// use std::fs::File;
88 /// use std::os::unix::prelude::FileExt;
90 /// fn main() -> io::Result<()> {
91 /// let mut buf = [0u8; 8];
92 /// let file = File::open("foo.txt")?;
94 /// // We now read exactly 8 bytes from the offset 10.
95 /// file.read_exact_at(&mut buf, 10)?;
96 /// println!("read {} bytes: {:?}", buf.len(), buf);
100 #[stable(feature = "rw_exact_all_at", since = "1.33.0")]
101 fn read_exact_at(&self, mut buf: &mut [u8], mut offset: u64) -> io::Result<()> {
102 while !buf.is_empty() {
103 match self.read_at(buf, offset) {
110 Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {}
111 Err(e) => return Err(e),
115 Err(io::Error::new_const(io::ErrorKind::UnexpectedEof, &"failed to fill whole buffer"))
121 /// Writes a number of bytes starting from a given offset.
123 /// Returns the number of bytes written.
125 /// The offset is relative to the start of the file and thus independent
126 /// from the current cursor.
128 /// The current file cursor is not affected by this function.
130 /// When writing beyond the end of the file, the file is appropriately
131 /// extended and the intermediate bytes are initialized with the value 0.
133 /// Note that similar to [`File::write`], it is not an error to return a
136 /// [`File::write`]: fs::File::write
141 /// use std::fs::File;
143 /// use std::os::unix::prelude::FileExt;
145 /// fn main() -> io::Result<()> {
146 /// let file = File::open("foo.txt")?;
148 /// // We now write at the offset 10.
149 /// file.write_at(b"sushi", 10)?;
153 #[stable(feature = "file_offset", since = "1.15.0")]
154 fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize>;
156 /// Attempts to write an entire buffer starting from a given offset.
158 /// The offset is relative to the start of the file and thus independent
159 /// from the current cursor.
161 /// The current file cursor is not affected by this function.
163 /// This method will continuously call [`write_at`] until there is no more data
164 /// to be written or an error of non-[`io::ErrorKind::Interrupted`] kind is
165 /// returned. This method will not return until the entire buffer has been
166 /// successfully written or such an error occurs. The first error that is
167 /// not of [`io::ErrorKind::Interrupted`] kind generated from this method will be
172 /// This function will return the first error of
173 /// non-[`io::ErrorKind::Interrupted`] kind that [`write_at`] returns.
175 /// [`write_at`]: FileExt::write_at
180 /// use std::fs::File;
182 /// use std::os::unix::prelude::FileExt;
184 /// fn main() -> io::Result<()> {
185 /// let file = File::open("foo.txt")?;
187 /// // We now write at the offset 10.
188 /// file.write_all_at(b"sushi", 10)?;
192 #[stable(feature = "rw_exact_all_at", since = "1.33.0")]
193 fn write_all_at(&self, mut buf: &[u8], mut offset: u64) -> io::Result<()> {
194 while !buf.is_empty() {
195 match self.write_at(buf, offset) {
197 return Err(io::Error::new_const(
198 io::ErrorKind::WriteZero,
199 &"failed to write whole buffer",
206 Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {}
207 Err(e) => return Err(e),
214 #[stable(feature = "file_offset", since = "1.15.0")]
215 impl FileExt for fs::File {
216 fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result<usize> {
217 self.as_inner().read_at(buf, offset)
219 fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize> {
220 self.as_inner().write_at(buf, offset)
224 /// Unix-specific extensions to [`fs::Permissions`].
225 #[stable(feature = "fs_ext", since = "1.1.0")]
226 pub trait PermissionsExt {
227 /// Returns the underlying raw `st_mode` bits that contain the standard
228 /// Unix permissions for this file.
233 /// use std::fs::File;
234 /// use std::os::unix::fs::PermissionsExt;
236 /// fn main() -> std::io::Result<()> {
237 /// let f = File::create("foo.txt")?;
238 /// let metadata = f.metadata()?;
239 /// let permissions = metadata.permissions();
241 /// println!("permissions: {:o}", permissions.mode());
245 #[stable(feature = "fs_ext", since = "1.1.0")]
246 fn mode(&self) -> u32;
248 /// Sets the underlying raw bits for this set of permissions.
253 /// use std::fs::File;
254 /// use std::os::unix::fs::PermissionsExt;
256 /// fn main() -> std::io::Result<()> {
257 /// let f = File::create("foo.txt")?;
258 /// let metadata = f.metadata()?;
259 /// let mut permissions = metadata.permissions();
261 /// permissions.set_mode(0o644); // Read/write for owner and read for others.
262 /// assert_eq!(permissions.mode(), 0o644);
266 #[stable(feature = "fs_ext", since = "1.1.0")]
267 fn set_mode(&mut self, mode: u32);
269 /// Creates a new instance of `Permissions` from the given set of Unix
275 /// use std::fs::Permissions;
276 /// use std::os::unix::fs::PermissionsExt;
278 /// // Read/write for owner and read for others.
279 /// let permissions = Permissions::from_mode(0o644);
280 /// assert_eq!(permissions.mode(), 0o644);
282 #[stable(feature = "fs_ext", since = "1.1.0")]
283 fn from_mode(mode: u32) -> Self;
286 #[stable(feature = "fs_ext", since = "1.1.0")]
287 impl PermissionsExt for Permissions {
288 fn mode(&self) -> u32 {
289 self.as_inner().mode()
292 fn set_mode(&mut self, mode: u32) {
293 *self = Permissions::from_inner(FromInner::from_inner(mode));
296 fn from_mode(mode: u32) -> Permissions {
297 Permissions::from_inner(FromInner::from_inner(mode))
301 /// Unix-specific extensions to [`fs::OpenOptions`].
302 #[stable(feature = "fs_ext", since = "1.1.0")]
303 pub trait OpenOptionsExt {
304 /// Sets the mode bits that a new file will be created with.
306 /// If a new file is created as part of an `OpenOptions::open` call then this
307 /// specified `mode` will be used as the permission bits for the new file.
308 /// If no `mode` is set, the default of `0o666` will be used.
309 /// The operating system masks out bits with the system's `umask`, to produce
310 /// the final permissions.
315 /// use std::fs::OpenOptions;
316 /// use std::os::unix::fs::OpenOptionsExt;
319 /// let mut options = OpenOptions::new();
320 /// options.mode(0o644); // Give read/write for owner and read for others.
321 /// let file = options.open("foo.txt");
324 #[stable(feature = "fs_ext", since = "1.1.0")]
325 fn mode(&mut self, mode: u32) -> &mut Self;
327 /// Pass custom flags to the `flags` argument of `open`.
329 /// The bits that define the access mode are masked out with `O_ACCMODE`, to
330 /// ensure they do not interfere with the access mode set by Rusts options.
332 /// Custom flags can only set flags, not remove flags set by Rusts options.
333 /// This options overwrites any previously set custom flags.
338 /// # #![feature(rustc_private)]
339 /// extern crate libc;
340 /// use std::fs::OpenOptions;
341 /// use std::os::unix::fs::OpenOptionsExt;
344 /// let mut options = OpenOptions::new();
345 /// options.write(true);
347 /// options.custom_flags(libc::O_NOFOLLOW);
349 /// let file = options.open("foo.txt");
352 #[stable(feature = "open_options_ext", since = "1.10.0")]
353 fn custom_flags(&mut self, flags: i32) -> &mut Self;
356 #[stable(feature = "fs_ext", since = "1.1.0")]
357 impl OpenOptionsExt for OpenOptions {
358 fn mode(&mut self, mode: u32) -> &mut OpenOptions {
359 self.as_inner_mut().mode(mode);
363 fn custom_flags(&mut self, flags: i32) -> &mut OpenOptions {
364 self.as_inner_mut().custom_flags(flags);
369 /// Unix-specific extensions to [`fs::Metadata`].
370 #[stable(feature = "metadata_ext", since = "1.1.0")]
371 pub trait MetadataExt {
372 /// Returns the ID of the device containing the file.
379 /// use std::os::unix::fs::MetadataExt;
381 /// fn main() -> io::Result<()> {
382 /// let meta = fs::metadata("some_file")?;
383 /// let dev_id = meta.dev();
387 #[stable(feature = "metadata_ext", since = "1.1.0")]
388 fn dev(&self) -> u64;
389 /// Returns the inode number.
395 /// use std::os::unix::fs::MetadataExt;
398 /// fn main() -> io::Result<()> {
399 /// let meta = fs::metadata("some_file")?;
400 /// let inode = meta.ino();
404 #[stable(feature = "metadata_ext", since = "1.1.0")]
405 fn ino(&self) -> u64;
406 /// Returns the rights applied to this file.
412 /// use std::os::unix::fs::MetadataExt;
415 /// fn main() -> io::Result<()> {
416 /// let meta = fs::metadata("some_file")?;
417 /// let mode = meta.mode();
418 /// let user_has_write_access = mode & 0o200;
419 /// let user_has_read_write_access = mode & 0o600;
420 /// let group_has_read_access = mode & 0o040;
421 /// let others_have_exec_access = mode & 0o001;
425 #[stable(feature = "metadata_ext", since = "1.1.0")]
426 fn mode(&self) -> u32;
427 /// Returns the number of hard links pointing to this file.
433 /// use std::os::unix::fs::MetadataExt;
436 /// fn main() -> io::Result<()> {
437 /// let meta = fs::metadata("some_file")?;
438 /// let nb_hard_links = meta.nlink();
442 #[stable(feature = "metadata_ext", since = "1.1.0")]
443 fn nlink(&self) -> u64;
444 /// Returns the user ID of the owner of this file.
450 /// use std::os::unix::fs::MetadataExt;
453 /// fn main() -> io::Result<()> {
454 /// let meta = fs::metadata("some_file")?;
455 /// let user_id = meta.uid();
459 #[stable(feature = "metadata_ext", since = "1.1.0")]
460 fn uid(&self) -> u32;
461 /// Returns the group ID of the owner of this file.
467 /// use std::os::unix::fs::MetadataExt;
470 /// fn main() -> io::Result<()> {
471 /// let meta = fs::metadata("some_file")?;
472 /// let group_id = meta.gid();
476 #[stable(feature = "metadata_ext", since = "1.1.0")]
477 fn gid(&self) -> u32;
478 /// Returns the device ID of this file (if it is a special one).
484 /// use std::os::unix::fs::MetadataExt;
487 /// fn main() -> io::Result<()> {
488 /// let meta = fs::metadata("some_file")?;
489 /// let device_id = meta.rdev();
493 #[stable(feature = "metadata_ext", since = "1.1.0")]
494 fn rdev(&self) -> u64;
495 /// Returns the total size of this file in bytes.
501 /// use std::os::unix::fs::MetadataExt;
504 /// fn main() -> io::Result<()> {
505 /// let meta = fs::metadata("some_file")?;
506 /// let file_size = meta.size();
510 #[stable(feature = "metadata_ext", since = "1.1.0")]
511 fn size(&self) -> u64;
512 /// Returns the last access time of the file, in seconds since Unix Epoch.
518 /// use std::os::unix::fs::MetadataExt;
521 /// fn main() -> io::Result<()> {
522 /// let meta = fs::metadata("some_file")?;
523 /// let last_access_time = meta.atime();
527 #[stable(feature = "metadata_ext", since = "1.1.0")]
528 fn atime(&self) -> i64;
529 /// Returns the last access time of the file, in nanoseconds since [`atime`].
531 /// [`atime`]: MetadataExt::atime
537 /// use std::os::unix::fs::MetadataExt;
540 /// fn main() -> io::Result<()> {
541 /// let meta = fs::metadata("some_file")?;
542 /// let nano_last_access_time = meta.atime_nsec();
546 #[stable(feature = "metadata_ext", since = "1.1.0")]
547 fn atime_nsec(&self) -> i64;
548 /// Returns the last modification time of the file, in seconds since Unix Epoch.
554 /// use std::os::unix::fs::MetadataExt;
557 /// fn main() -> io::Result<()> {
558 /// let meta = fs::metadata("some_file")?;
559 /// let last_modification_time = meta.mtime();
563 #[stable(feature = "metadata_ext", since = "1.1.0")]
564 fn mtime(&self) -> i64;
565 /// Returns the last modification time of the file, in nanoseconds since [`mtime`].
567 /// [`mtime`]: MetadataExt::mtime
573 /// use std::os::unix::fs::MetadataExt;
576 /// fn main() -> io::Result<()> {
577 /// let meta = fs::metadata("some_file")?;
578 /// let nano_last_modification_time = meta.mtime_nsec();
582 #[stable(feature = "metadata_ext", since = "1.1.0")]
583 fn mtime_nsec(&self) -> i64;
584 /// Returns the last status change time of the file, in seconds since Unix Epoch.
590 /// use std::os::unix::fs::MetadataExt;
593 /// fn main() -> io::Result<()> {
594 /// let meta = fs::metadata("some_file")?;
595 /// let last_status_change_time = meta.ctime();
599 #[stable(feature = "metadata_ext", since = "1.1.0")]
600 fn ctime(&self) -> i64;
601 /// Returns the last status change time of the file, in nanoseconds since [`ctime`].
603 /// [`ctime`]: MetadataExt::ctime
609 /// use std::os::unix::fs::MetadataExt;
612 /// fn main() -> io::Result<()> {
613 /// let meta = fs::metadata("some_file")?;
614 /// let nano_last_status_change_time = meta.ctime_nsec();
618 #[stable(feature = "metadata_ext", since = "1.1.0")]
619 fn ctime_nsec(&self) -> i64;
620 /// Returns the block size for filesystem I/O.
626 /// use std::os::unix::fs::MetadataExt;
629 /// fn main() -> io::Result<()> {
630 /// let meta = fs::metadata("some_file")?;
631 /// let block_size = meta.blksize();
635 #[stable(feature = "metadata_ext", since = "1.1.0")]
636 fn blksize(&self) -> u64;
637 /// Returns the number of blocks allocated to the file, in 512-byte units.
639 /// Please note that this may be smaller than `st_size / 512` when the file has holes.
645 /// use std::os::unix::fs::MetadataExt;
648 /// fn main() -> io::Result<()> {
649 /// let meta = fs::metadata("some_file")?;
650 /// let blocks = meta.blocks();
654 #[stable(feature = "metadata_ext", since = "1.1.0")]
655 fn blocks(&self) -> u64;
656 #[cfg(target_os = "vxworks")]
657 #[stable(feature = "metadata_ext", since = "1.1.0")]
658 fn attrib(&self) -> u8;
661 #[stable(feature = "metadata_ext", since = "1.1.0")]
662 impl MetadataExt for fs::Metadata {
663 fn dev(&self) -> u64 {
666 fn ino(&self) -> u64 {
669 fn mode(&self) -> u32 {
672 fn nlink(&self) -> u64 {
675 fn uid(&self) -> u32 {
678 fn gid(&self) -> u32 {
681 fn rdev(&self) -> u64 {
684 fn size(&self) -> u64 {
687 fn atime(&self) -> i64 {
690 fn atime_nsec(&self) -> i64 {
693 fn mtime(&self) -> i64 {
696 fn mtime_nsec(&self) -> i64 {
699 fn ctime(&self) -> i64 {
702 fn ctime_nsec(&self) -> i64 {
705 fn blksize(&self) -> u64 {
708 fn blocks(&self) -> u64 {
711 #[cfg(target_os = "vxworks")]
712 fn attrib(&self) -> u8 {
717 /// Unix-specific extensions for [`fs::FileType`].
719 /// Adds support for special Unix file types such as block/character devices,
720 /// pipes, and sockets.
721 #[stable(feature = "file_type_ext", since = "1.5.0")]
722 pub trait FileTypeExt {
723 /// Returns `true` if this file type is a block device.
729 /// use std::os::unix::fs::FileTypeExt;
732 /// fn main() -> io::Result<()> {
733 /// let meta = fs::metadata("block_device_file")?;
734 /// let file_type = meta.file_type();
735 /// assert!(file_type.is_block_device());
739 #[stable(feature = "file_type_ext", since = "1.5.0")]
740 fn is_block_device(&self) -> bool;
741 /// Returns `true` if this file type is a char device.
747 /// use std::os::unix::fs::FileTypeExt;
750 /// fn main() -> io::Result<()> {
751 /// let meta = fs::metadata("char_device_file")?;
752 /// let file_type = meta.file_type();
753 /// assert!(file_type.is_char_device());
757 #[stable(feature = "file_type_ext", since = "1.5.0")]
758 fn is_char_device(&self) -> bool;
759 /// Returns `true` if this file type is a fifo.
765 /// use std::os::unix::fs::FileTypeExt;
768 /// fn main() -> io::Result<()> {
769 /// let meta = fs::metadata("fifo_file")?;
770 /// let file_type = meta.file_type();
771 /// assert!(file_type.is_fifo());
775 #[stable(feature = "file_type_ext", since = "1.5.0")]
776 fn is_fifo(&self) -> bool;
777 /// Returns `true` if this file type is a socket.
783 /// use std::os::unix::fs::FileTypeExt;
786 /// fn main() -> io::Result<()> {
787 /// let meta = fs::metadata("unix.socket")?;
788 /// let file_type = meta.file_type();
789 /// assert!(file_type.is_socket());
793 #[stable(feature = "file_type_ext", since = "1.5.0")]
794 fn is_socket(&self) -> bool;
797 #[stable(feature = "file_type_ext", since = "1.5.0")]
798 impl FileTypeExt for fs::FileType {
799 fn is_block_device(&self) -> bool {
800 self.as_inner().is(libc::S_IFBLK)
802 fn is_char_device(&self) -> bool {
803 self.as_inner().is(libc::S_IFCHR)
805 fn is_fifo(&self) -> bool {
806 self.as_inner().is(libc::S_IFIFO)
808 fn is_socket(&self) -> bool {
809 self.as_inner().is(libc::S_IFSOCK)
813 /// Unix-specific extension methods for [`fs::DirEntry`].
814 #[stable(feature = "dir_entry_ext", since = "1.1.0")]
815 pub trait DirEntryExt {
816 /// Returns the underlying `d_ino` field in the contained `dirent`
823 /// use std::os::unix::fs::DirEntryExt;
825 /// if let Ok(entries) = fs::read_dir(".") {
826 /// for entry in entries {
827 /// if let Ok(entry) = entry {
828 /// // Here, `entry` is a `DirEntry`.
829 /// println!("{:?}: {}", entry.file_name(), entry.ino());
834 #[stable(feature = "dir_entry_ext", since = "1.1.0")]
835 fn ino(&self) -> u64;
838 #[stable(feature = "dir_entry_ext", since = "1.1.0")]
839 impl DirEntryExt for fs::DirEntry {
840 fn ino(&self) -> u64 {
841 self.as_inner().ino()
845 /// Sealed Unix-specific extension methods for [`fs::DirEntry`].
846 #[unstable(feature = "dir_entry_ext2", issue = "85573")]
847 pub trait DirEntryExt2: Sealed {
848 /// Returns a reference to the underlying `OsStr` of this entry's filename.
853 /// #![feature(dir_entry_ext2)]
854 /// use std::os::unix::fs::DirEntryExt2;
855 /// use std::{fs, io};
857 /// fn main() -> io::Result<()> {
858 /// let mut entries = fs::read_dir(".")?.collect::<Result<Vec<_>, io::Error>>()?;
859 /// entries.sort_unstable_by(|a, b| a.file_name_ref().cmp(b.file_name_ref()));
861 /// for p in entries {
862 /// println!("{:?}", p);
868 fn file_name_ref(&self) -> &OsStr;
871 /// Allows extension traits within `std`.
872 #[unstable(feature = "sealed", issue = "none")]
873 impl Sealed for fs::DirEntry {}
875 #[unstable(feature = "dir_entry_ext2", issue = "85573")]
876 impl DirEntryExt2 for fs::DirEntry {
877 fn file_name_ref(&self) -> &OsStr {
878 self.as_inner().file_name_os_str()
882 /// Creates a new symbolic link on the filesystem.
884 /// The `link` path will be a symbolic link pointing to the `original` path.
889 /// use std::os::unix::fs;
891 /// fn main() -> std::io::Result<()> {
892 /// fs::symlink("a.txt", "b.txt")?;
896 #[stable(feature = "symlink", since = "1.1.0")]
897 pub fn symlink<P: AsRef<Path>, Q: AsRef<Path>>(original: P, link: Q) -> io::Result<()> {
898 sys::fs::symlink(original.as_ref(), link.as_ref())
901 /// Unix-specific extensions to [`fs::DirBuilder`].
902 #[stable(feature = "dir_builder", since = "1.6.0")]
903 pub trait DirBuilderExt {
904 /// Sets the mode to create new directories with. This option defaults to
910 /// use std::fs::DirBuilder;
911 /// use std::os::unix::fs::DirBuilderExt;
913 /// let mut builder = DirBuilder::new();
914 /// builder.mode(0o755);
916 #[stable(feature = "dir_builder", since = "1.6.0")]
917 fn mode(&mut self, mode: u32) -> &mut Self;
920 #[stable(feature = "dir_builder", since = "1.6.0")]
921 impl DirBuilderExt for fs::DirBuilder {
922 fn mode(&mut self, mode: u32) -> &mut fs::DirBuilder {
923 self.as_inner_mut().set_mode(mode);
928 /// Change the owner and group of the specified path.
930 /// Specifying either the uid or gid as `None` will leave it unchanged.
932 /// Changing the owner typically requires privileges, such as root or a specific capability.
933 /// Changing the group typically requires either being the owner and a member of the group, or
934 /// having privileges.
936 /// If called on a symbolic link, this will change the owner and group of the link target. To
937 /// change the owner and group of the link itself, see [`lchown`].
942 /// #![feature(unix_chown)]
943 /// use std::os::unix::fs;
945 /// fn main() -> std::io::Result<()> {
946 /// fs::chown("/sandbox", Some(0), Some(0))?;
950 #[unstable(feature = "unix_chown", issue = "88989")]
951 pub fn chown<P: AsRef<Path>>(dir: P, uid: Option<u32>, gid: Option<u32>) -> io::Result<()> {
952 sys::fs::chown(dir.as_ref(), uid.unwrap_or(u32::MAX), gid.unwrap_or(u32::MAX))
955 /// Change the owner and group of the file referenced by the specified open file descriptor.
957 /// For semantics and required privileges, see [`chown`].
962 /// #![feature(unix_chown)]
963 /// use std::os::unix::fs;
965 /// fn main() -> std::io::Result<()> {
966 /// let f = std::fs::File::open("/file")?;
967 /// fs::fchown(f, Some(0), Some(0))?;
971 #[unstable(feature = "unix_chown", issue = "88989")]
972 pub fn fchown<F: AsFd>(fd: F, uid: Option<u32>, gid: Option<u32>) -> io::Result<()> {
973 sys::fs::fchown(fd.as_fd().as_raw_fd(), uid.unwrap_or(u32::MAX), gid.unwrap_or(u32::MAX))
976 /// Change the owner and group of the specified path, without dereferencing symbolic links.
978 /// Identical to [`chown`], except that if called on a symbolic link, this will change the owner
979 /// and group of the link itself rather than the owner and group of the link target.
984 /// #![feature(unix_chown)]
985 /// use std::os::unix::fs;
987 /// fn main() -> std::io::Result<()> {
988 /// fs::lchown("/symlink", Some(0), Some(0))?;
992 #[unstable(feature = "unix_chown", issue = "88989")]
993 pub fn lchown<P: AsRef<Path>>(dir: P, uid: Option<u32>, gid: Option<u32>) -> io::Result<()> {
994 sys::fs::lchown(dir.as_ref(), uid.unwrap_or(u32::MAX), gid.unwrap_or(u32::MAX))
997 /// Change the root directory of the current process to the specified path.
999 /// This typically requires privileges, such as root or a specific capability.
1001 /// This does not change the current working directory; you should call
1002 /// [`std::env::set_current_dir`][`crate::env::set_current_dir`] afterwards.
1007 /// use std::os::unix::fs;
1009 /// fn main() -> std::io::Result<()> {
1010 /// fs::chroot("/sandbox")?;
1011 /// std::env::set_current_dir("/")?;
1012 /// // continue working in sandbox
1016 #[stable(feature = "unix_chroot", since = "1.56.0")]
1017 #[cfg(not(any(target_os = "fuchsia", target_os = "vxworks")))]
1018 pub fn chroot<P: AsRef<Path>>(dir: P) -> io::Result<()> {
1019 sys::fs::chroot(dir.as_ref())