1 //! Unix-specific extensions to primitives in the [`std::fs`] module.
3 //! [`std::fs`]: crate::fs
5 #![stable(feature = "rust1", since = "1.0.0")]
7 use super::platform::fs::MetadataExt as _;
8 use crate::fs::{self, OpenOptions, Permissions};
10 use crate::os::unix::io::{AsFd, AsRawFd};
11 use crate::path::Path;
13 use crate::sys_common::{AsInner, AsInnerMut, FromInner};
14 // Used for `File::read` on intra-doc links
15 use crate::ffi::OsStr;
16 use crate::sealed::Sealed;
17 #[allow(unused_imports)]
18 use io::{Read, Write};
20 /// Unix-specific extensions to [`fs::File`].
21 #[stable(feature = "file_offset", since = "1.15.0")]
23 /// Reads a number of bytes starting from a given offset.
25 /// Returns the number of bytes read.
27 /// The offset is relative to the start of the file and thus independent
28 /// from the current cursor.
30 /// The current file cursor is not affected by this function.
32 /// Note that similar to [`File::read`], it is not an error to return with a
35 /// [`File::read`]: fs::File::read
41 /// use std::fs::File;
42 /// use std::os::unix::prelude::FileExt;
44 /// fn main() -> io::Result<()> {
45 /// let mut buf = [0u8; 8];
46 /// let file = File::open("foo.txt")?;
48 /// // We now read 8 bytes from the offset 10.
49 /// let num_bytes_read = file.read_at(&mut buf, 10)?;
50 /// println!("read {num_bytes_read} bytes: {buf:?}");
54 #[stable(feature = "file_offset", since = "1.15.0")]
55 fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result<usize>;
57 /// Reads the exact number of byte required to fill `buf` from the given offset.
59 /// The offset is relative to the start of the file and thus independent
60 /// from the current cursor.
62 /// The current file cursor is not affected by this function.
64 /// Similar to [`io::Read::read_exact`] but uses [`read_at`] instead of `read`.
66 /// [`read_at`]: FileExt::read_at
70 /// If this function encounters an error of the kind
71 /// [`io::ErrorKind::Interrupted`] then the error is ignored and the operation
74 /// If this function encounters an "end of file" before completely filling
75 /// the buffer, it returns an error of the kind [`io::ErrorKind::UnexpectedEof`].
76 /// The contents of `buf` are unspecified in this case.
78 /// If any other read error is encountered then this function immediately
79 /// returns. The contents of `buf` are unspecified in this case.
81 /// If this function returns an error, it is unspecified how many bytes it
82 /// has read, but it will never read more than would be necessary to
83 /// completely fill the buffer.
89 /// use std::fs::File;
90 /// use std::os::unix::prelude::FileExt;
92 /// fn main() -> io::Result<()> {
93 /// let mut buf = [0u8; 8];
94 /// let file = File::open("foo.txt")?;
96 /// // We now read exactly 8 bytes from the offset 10.
97 /// file.read_exact_at(&mut buf, 10)?;
98 /// println!("read {} bytes: {:?}", buf.len(), buf);
102 #[stable(feature = "rw_exact_all_at", since = "1.33.0")]
103 fn read_exact_at(&self, mut buf: &mut [u8], mut offset: u64) -> io::Result<()> {
104 while !buf.is_empty() {
105 match self.read_at(buf, offset) {
112 Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {}
113 Err(e) => return Err(e),
117 Err(io::const_io_error!(io::ErrorKind::UnexpectedEof, "failed to fill whole buffer",))
123 /// Writes a number of bytes starting from a given offset.
125 /// Returns the number of bytes written.
127 /// The offset is relative to the start of the file and thus independent
128 /// from the current cursor.
130 /// The current file cursor is not affected by this function.
132 /// When writing beyond the end of the file, the file is appropriately
133 /// extended and the intermediate bytes are initialized with the value 0.
135 /// Note that similar to [`File::write`], it is not an error to return a
138 /// [`File::write`]: fs::File::write
143 /// use std::fs::File;
145 /// use std::os::unix::prelude::FileExt;
147 /// fn main() -> io::Result<()> {
148 /// let file = File::open("foo.txt")?;
150 /// // We now write at the offset 10.
151 /// file.write_at(b"sushi", 10)?;
155 #[stable(feature = "file_offset", since = "1.15.0")]
156 fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize>;
158 /// Attempts to write an entire buffer starting from a given offset.
160 /// The offset is relative to the start of the file and thus independent
161 /// from the current cursor.
163 /// The current file cursor is not affected by this function.
165 /// This method will continuously call [`write_at`] until there is no more data
166 /// to be written or an error of non-[`io::ErrorKind::Interrupted`] kind is
167 /// returned. This method will not return until the entire buffer has been
168 /// successfully written or such an error occurs. The first error that is
169 /// not of [`io::ErrorKind::Interrupted`] kind generated from this method will be
174 /// This function will return the first error of
175 /// non-[`io::ErrorKind::Interrupted`] kind that [`write_at`] returns.
177 /// [`write_at`]: FileExt::write_at
182 /// use std::fs::File;
184 /// use std::os::unix::prelude::FileExt;
186 /// fn main() -> io::Result<()> {
187 /// let file = File::open("foo.txt")?;
189 /// // We now write at the offset 10.
190 /// file.write_all_at(b"sushi", 10)?;
194 #[stable(feature = "rw_exact_all_at", since = "1.33.0")]
195 fn write_all_at(&self, mut buf: &[u8], mut offset: u64) -> io::Result<()> {
196 while !buf.is_empty() {
197 match self.write_at(buf, offset) {
199 return Err(io::const_io_error!(
200 io::ErrorKind::WriteZero,
201 "failed to write whole buffer",
208 Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {}
209 Err(e) => return Err(e),
216 #[stable(feature = "file_offset", since = "1.15.0")]
217 impl FileExt for fs::File {
218 fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result<usize> {
219 self.as_inner().read_at(buf, offset)
221 fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize> {
222 self.as_inner().write_at(buf, offset)
226 /// Unix-specific extensions to [`fs::Permissions`].
227 #[stable(feature = "fs_ext", since = "1.1.0")]
228 pub trait PermissionsExt {
229 /// Returns the underlying raw `st_mode` bits that contain the standard
230 /// Unix permissions for this file.
235 /// use std::fs::File;
236 /// use std::os::unix::fs::PermissionsExt;
238 /// fn main() -> std::io::Result<()> {
239 /// let f = File::create("foo.txt")?;
240 /// let metadata = f.metadata()?;
241 /// let permissions = metadata.permissions();
243 /// println!("permissions: {:o}", permissions.mode());
247 #[stable(feature = "fs_ext", since = "1.1.0")]
248 fn mode(&self) -> u32;
250 /// Sets the underlying raw bits for this set of permissions.
255 /// use std::fs::File;
256 /// use std::os::unix::fs::PermissionsExt;
258 /// fn main() -> std::io::Result<()> {
259 /// let f = File::create("foo.txt")?;
260 /// let metadata = f.metadata()?;
261 /// let mut permissions = metadata.permissions();
263 /// permissions.set_mode(0o644); // Read/write for owner and read for others.
264 /// assert_eq!(permissions.mode(), 0o644);
268 #[stable(feature = "fs_ext", since = "1.1.0")]
269 fn set_mode(&mut self, mode: u32);
271 /// Creates a new instance of `Permissions` from the given set of Unix
277 /// use std::fs::Permissions;
278 /// use std::os::unix::fs::PermissionsExt;
280 /// // Read/write for owner and read for others.
281 /// let permissions = Permissions::from_mode(0o644);
282 /// assert_eq!(permissions.mode(), 0o644);
284 #[stable(feature = "fs_ext", since = "1.1.0")]
285 fn from_mode(mode: u32) -> Self;
288 #[stable(feature = "fs_ext", since = "1.1.0")]
289 impl PermissionsExt for Permissions {
290 fn mode(&self) -> u32 {
291 self.as_inner().mode()
294 fn set_mode(&mut self, mode: u32) {
295 *self = Permissions::from_inner(FromInner::from_inner(mode));
298 fn from_mode(mode: u32) -> Permissions {
299 Permissions::from_inner(FromInner::from_inner(mode))
303 /// Unix-specific extensions to [`fs::OpenOptions`].
304 #[stable(feature = "fs_ext", since = "1.1.0")]
305 pub trait OpenOptionsExt {
306 /// Sets the mode bits that a new file will be created with.
308 /// If a new file is created as part of an `OpenOptions::open` call then this
309 /// specified `mode` will be used as the permission bits for the new file.
310 /// If no `mode` is set, the default of `0o666` will be used.
311 /// The operating system masks out bits with the system's `umask`, to produce
312 /// the final permissions.
317 /// use std::fs::OpenOptions;
318 /// use std::os::unix::fs::OpenOptionsExt;
321 /// let mut options = OpenOptions::new();
322 /// options.mode(0o644); // Give read/write for owner and read for others.
323 /// let file = options.open("foo.txt");
326 #[stable(feature = "fs_ext", since = "1.1.0")]
327 fn mode(&mut self, mode: u32) -> &mut Self;
329 /// Pass custom flags to the `flags` argument of `open`.
331 /// The bits that define the access mode are masked out with `O_ACCMODE`, to
332 /// ensure they do not interfere with the access mode set by Rusts options.
334 /// Custom flags can only set flags, not remove flags set by Rusts options.
335 /// This options overwrites any previously set custom flags.
340 /// # #![feature(rustc_private)]
341 /// extern crate libc;
342 /// use std::fs::OpenOptions;
343 /// use std::os::unix::fs::OpenOptionsExt;
346 /// let mut options = OpenOptions::new();
347 /// options.write(true);
349 /// options.custom_flags(libc::O_NOFOLLOW);
351 /// let file = options.open("foo.txt");
354 #[stable(feature = "open_options_ext", since = "1.10.0")]
355 fn custom_flags(&mut self, flags: i32) -> &mut Self;
358 #[stable(feature = "fs_ext", since = "1.1.0")]
359 impl OpenOptionsExt for OpenOptions {
360 fn mode(&mut self, mode: u32) -> &mut OpenOptions {
361 self.as_inner_mut().mode(mode);
365 fn custom_flags(&mut self, flags: i32) -> &mut OpenOptions {
366 self.as_inner_mut().custom_flags(flags);
371 /// Unix-specific extensions to [`fs::Metadata`].
372 #[stable(feature = "metadata_ext", since = "1.1.0")]
373 pub trait MetadataExt {
374 /// Returns the ID of the device containing the file.
381 /// use std::os::unix::fs::MetadataExt;
383 /// fn main() -> io::Result<()> {
384 /// let meta = fs::metadata("some_file")?;
385 /// let dev_id = meta.dev();
389 #[stable(feature = "metadata_ext", since = "1.1.0")]
390 fn dev(&self) -> u64;
391 /// Returns the inode number.
397 /// use std::os::unix::fs::MetadataExt;
400 /// fn main() -> io::Result<()> {
401 /// let meta = fs::metadata("some_file")?;
402 /// let inode = meta.ino();
406 #[stable(feature = "metadata_ext", since = "1.1.0")]
407 fn ino(&self) -> u64;
408 /// Returns the rights applied to this file.
414 /// use std::os::unix::fs::MetadataExt;
417 /// fn main() -> io::Result<()> {
418 /// let meta = fs::metadata("some_file")?;
419 /// let mode = meta.mode();
420 /// let user_has_write_access = mode & 0o200;
421 /// let user_has_read_write_access = mode & 0o600;
422 /// let group_has_read_access = mode & 0o040;
423 /// let others_have_exec_access = mode & 0o001;
427 #[stable(feature = "metadata_ext", since = "1.1.0")]
428 fn mode(&self) -> u32;
429 /// Returns the number of hard links pointing to this file.
435 /// use std::os::unix::fs::MetadataExt;
438 /// fn main() -> io::Result<()> {
439 /// let meta = fs::metadata("some_file")?;
440 /// let nb_hard_links = meta.nlink();
444 #[stable(feature = "metadata_ext", since = "1.1.0")]
445 fn nlink(&self) -> u64;
446 /// Returns the user ID of the owner of this file.
452 /// use std::os::unix::fs::MetadataExt;
455 /// fn main() -> io::Result<()> {
456 /// let meta = fs::metadata("some_file")?;
457 /// let user_id = meta.uid();
461 #[stable(feature = "metadata_ext", since = "1.1.0")]
462 fn uid(&self) -> u32;
463 /// Returns the group ID of the owner of this file.
469 /// use std::os::unix::fs::MetadataExt;
472 /// fn main() -> io::Result<()> {
473 /// let meta = fs::metadata("some_file")?;
474 /// let group_id = meta.gid();
478 #[stable(feature = "metadata_ext", since = "1.1.0")]
479 fn gid(&self) -> u32;
480 /// Returns the device ID of this file (if it is a special one).
486 /// use std::os::unix::fs::MetadataExt;
489 /// fn main() -> io::Result<()> {
490 /// let meta = fs::metadata("some_file")?;
491 /// let device_id = meta.rdev();
495 #[stable(feature = "metadata_ext", since = "1.1.0")]
496 fn rdev(&self) -> u64;
497 /// Returns the total size of this file in bytes.
503 /// use std::os::unix::fs::MetadataExt;
506 /// fn main() -> io::Result<()> {
507 /// let meta = fs::metadata("some_file")?;
508 /// let file_size = meta.size();
512 #[stable(feature = "metadata_ext", since = "1.1.0")]
513 fn size(&self) -> u64;
514 /// Returns the last access time of the file, in seconds since Unix Epoch.
520 /// use std::os::unix::fs::MetadataExt;
523 /// fn main() -> io::Result<()> {
524 /// let meta = fs::metadata("some_file")?;
525 /// let last_access_time = meta.atime();
529 #[stable(feature = "metadata_ext", since = "1.1.0")]
530 fn atime(&self) -> i64;
531 /// Returns the last access time of the file, in nanoseconds since [`atime`].
533 /// [`atime`]: MetadataExt::atime
539 /// use std::os::unix::fs::MetadataExt;
542 /// fn main() -> io::Result<()> {
543 /// let meta = fs::metadata("some_file")?;
544 /// let nano_last_access_time = meta.atime_nsec();
548 #[stable(feature = "metadata_ext", since = "1.1.0")]
549 fn atime_nsec(&self) -> i64;
550 /// Returns the last modification time of the file, in seconds since Unix Epoch.
556 /// use std::os::unix::fs::MetadataExt;
559 /// fn main() -> io::Result<()> {
560 /// let meta = fs::metadata("some_file")?;
561 /// let last_modification_time = meta.mtime();
565 #[stable(feature = "metadata_ext", since = "1.1.0")]
566 fn mtime(&self) -> i64;
567 /// Returns the last modification time of the file, in nanoseconds since [`mtime`].
569 /// [`mtime`]: MetadataExt::mtime
575 /// use std::os::unix::fs::MetadataExt;
578 /// fn main() -> io::Result<()> {
579 /// let meta = fs::metadata("some_file")?;
580 /// let nano_last_modification_time = meta.mtime_nsec();
584 #[stable(feature = "metadata_ext", since = "1.1.0")]
585 fn mtime_nsec(&self) -> i64;
586 /// Returns the last status change time of the file, in seconds since Unix Epoch.
592 /// use std::os::unix::fs::MetadataExt;
595 /// fn main() -> io::Result<()> {
596 /// let meta = fs::metadata("some_file")?;
597 /// let last_status_change_time = meta.ctime();
601 #[stable(feature = "metadata_ext", since = "1.1.0")]
602 fn ctime(&self) -> i64;
603 /// Returns the last status change time of the file, in nanoseconds since [`ctime`].
605 /// [`ctime`]: MetadataExt::ctime
611 /// use std::os::unix::fs::MetadataExt;
614 /// fn main() -> io::Result<()> {
615 /// let meta = fs::metadata("some_file")?;
616 /// let nano_last_status_change_time = meta.ctime_nsec();
620 #[stable(feature = "metadata_ext", since = "1.1.0")]
621 fn ctime_nsec(&self) -> i64;
622 /// Returns the block size for filesystem I/O.
628 /// use std::os::unix::fs::MetadataExt;
631 /// fn main() -> io::Result<()> {
632 /// let meta = fs::metadata("some_file")?;
633 /// let block_size = meta.blksize();
637 #[stable(feature = "metadata_ext", since = "1.1.0")]
638 fn blksize(&self) -> u64;
639 /// Returns the number of blocks allocated to the file, in 512-byte units.
641 /// Please note that this may be smaller than `st_size / 512` when the file has holes.
647 /// use std::os::unix::fs::MetadataExt;
650 /// fn main() -> io::Result<()> {
651 /// let meta = fs::metadata("some_file")?;
652 /// let blocks = meta.blocks();
656 #[stable(feature = "metadata_ext", since = "1.1.0")]
657 fn blocks(&self) -> u64;
658 #[cfg(target_os = "vxworks")]
659 #[stable(feature = "metadata_ext", since = "1.1.0")]
660 fn attrib(&self) -> u8;
663 #[stable(feature = "metadata_ext", since = "1.1.0")]
664 impl MetadataExt for fs::Metadata {
665 fn dev(&self) -> u64 {
668 fn ino(&self) -> u64 {
671 fn mode(&self) -> u32 {
674 fn nlink(&self) -> u64 {
677 fn uid(&self) -> u32 {
680 fn gid(&self) -> u32 {
683 fn rdev(&self) -> u64 {
686 fn size(&self) -> u64 {
689 fn atime(&self) -> i64 {
692 fn atime_nsec(&self) -> i64 {
695 fn mtime(&self) -> i64 {
698 fn mtime_nsec(&self) -> i64 {
701 fn ctime(&self) -> i64 {
704 fn ctime_nsec(&self) -> i64 {
707 fn blksize(&self) -> u64 {
710 fn blocks(&self) -> u64 {
713 #[cfg(target_os = "vxworks")]
714 fn attrib(&self) -> u8 {
719 /// Unix-specific extensions for [`fs::FileType`].
721 /// Adds support for special Unix file types such as block/character devices,
722 /// pipes, and sockets.
723 #[stable(feature = "file_type_ext", since = "1.5.0")]
724 pub trait FileTypeExt {
725 /// Returns `true` if this file type is a block device.
731 /// use std::os::unix::fs::FileTypeExt;
734 /// fn main() -> io::Result<()> {
735 /// let meta = fs::metadata("block_device_file")?;
736 /// let file_type = meta.file_type();
737 /// assert!(file_type.is_block_device());
741 #[stable(feature = "file_type_ext", since = "1.5.0")]
742 fn is_block_device(&self) -> bool;
743 /// Returns `true` if this file type is a char device.
749 /// use std::os::unix::fs::FileTypeExt;
752 /// fn main() -> io::Result<()> {
753 /// let meta = fs::metadata("char_device_file")?;
754 /// let file_type = meta.file_type();
755 /// assert!(file_type.is_char_device());
759 #[stable(feature = "file_type_ext", since = "1.5.0")]
760 fn is_char_device(&self) -> bool;
761 /// Returns `true` if this file type is a fifo.
767 /// use std::os::unix::fs::FileTypeExt;
770 /// fn main() -> io::Result<()> {
771 /// let meta = fs::metadata("fifo_file")?;
772 /// let file_type = meta.file_type();
773 /// assert!(file_type.is_fifo());
777 #[stable(feature = "file_type_ext", since = "1.5.0")]
778 fn is_fifo(&self) -> bool;
779 /// Returns `true` if this file type is a socket.
785 /// use std::os::unix::fs::FileTypeExt;
788 /// fn main() -> io::Result<()> {
789 /// let meta = fs::metadata("unix.socket")?;
790 /// let file_type = meta.file_type();
791 /// assert!(file_type.is_socket());
795 #[stable(feature = "file_type_ext", since = "1.5.0")]
796 fn is_socket(&self) -> bool;
799 #[stable(feature = "file_type_ext", since = "1.5.0")]
800 impl FileTypeExt for fs::FileType {
801 fn is_block_device(&self) -> bool {
802 self.as_inner().is(libc::S_IFBLK)
804 fn is_char_device(&self) -> bool {
805 self.as_inner().is(libc::S_IFCHR)
807 fn is_fifo(&self) -> bool {
808 self.as_inner().is(libc::S_IFIFO)
810 fn is_socket(&self) -> bool {
811 self.as_inner().is(libc::S_IFSOCK)
815 /// Unix-specific extension methods for [`fs::DirEntry`].
816 #[stable(feature = "dir_entry_ext", since = "1.1.0")]
817 pub trait DirEntryExt {
818 /// Returns the underlying `d_ino` field in the contained `dirent`
825 /// use std::os::unix::fs::DirEntryExt;
827 /// if let Ok(entries) = fs::read_dir(".") {
828 /// for entry in entries {
829 /// if let Ok(entry) = entry {
830 /// // Here, `entry` is a `DirEntry`.
831 /// println!("{:?}: {}", entry.file_name(), entry.ino());
836 #[stable(feature = "dir_entry_ext", since = "1.1.0")]
837 fn ino(&self) -> u64;
840 #[stable(feature = "dir_entry_ext", since = "1.1.0")]
841 impl DirEntryExt for fs::DirEntry {
842 fn ino(&self) -> u64 {
843 self.as_inner().ino()
847 /// Sealed Unix-specific extension methods for [`fs::DirEntry`].
848 #[unstable(feature = "dir_entry_ext2", issue = "85573")]
849 pub trait DirEntryExt2: Sealed {
850 /// Returns a reference to the underlying `OsStr` of this entry's filename.
855 /// #![feature(dir_entry_ext2)]
856 /// use std::os::unix::fs::DirEntryExt2;
857 /// use std::{fs, io};
859 /// fn main() -> io::Result<()> {
860 /// let mut entries = fs::read_dir(".")?.collect::<Result<Vec<_>, io::Error>>()?;
861 /// entries.sort_unstable_by(|a, b| a.file_name_ref().cmp(b.file_name_ref()));
863 /// for p in entries {
864 /// println!("{p:?}");
870 fn file_name_ref(&self) -> &OsStr;
873 /// Allows extension traits within `std`.
874 #[unstable(feature = "sealed", issue = "none")]
875 impl Sealed for fs::DirEntry {}
877 #[unstable(feature = "dir_entry_ext2", issue = "85573")]
878 impl DirEntryExt2 for fs::DirEntry {
879 fn file_name_ref(&self) -> &OsStr {
880 self.as_inner().file_name_os_str()
884 /// Creates a new symbolic link on the filesystem.
886 /// The `link` path will be a symbolic link pointing to the `original` path.
891 /// use std::os::unix::fs;
893 /// fn main() -> std::io::Result<()> {
894 /// fs::symlink("a.txt", "b.txt")?;
898 #[stable(feature = "symlink", since = "1.1.0")]
899 pub fn symlink<P: AsRef<Path>, Q: AsRef<Path>>(original: P, link: Q) -> io::Result<()> {
900 sys::fs::symlink(original.as_ref(), link.as_ref())
903 /// Unix-specific extensions to [`fs::DirBuilder`].
904 #[stable(feature = "dir_builder", since = "1.6.0")]
905 pub trait DirBuilderExt {
906 /// Sets the mode to create new directories with. This option defaults to
912 /// use std::fs::DirBuilder;
913 /// use std::os::unix::fs::DirBuilderExt;
915 /// let mut builder = DirBuilder::new();
916 /// builder.mode(0o755);
918 #[stable(feature = "dir_builder", since = "1.6.0")]
919 fn mode(&mut self, mode: u32) -> &mut Self;
922 #[stable(feature = "dir_builder", since = "1.6.0")]
923 impl DirBuilderExt for fs::DirBuilder {
924 fn mode(&mut self, mode: u32) -> &mut fs::DirBuilder {
925 self.as_inner_mut().set_mode(mode);
930 /// Change the owner and group of the specified path.
932 /// Specifying either the uid or gid as `None` will leave it unchanged.
934 /// Changing the owner typically requires privileges, such as root or a specific capability.
935 /// Changing the group typically requires either being the owner and a member of the group, or
936 /// having privileges.
938 /// If called on a symbolic link, this will change the owner and group of the link target. To
939 /// change the owner and group of the link itself, see [`lchown`].
944 /// #![feature(unix_chown)]
945 /// use std::os::unix::fs;
947 /// fn main() -> std::io::Result<()> {
948 /// fs::chown("/sandbox", Some(0), Some(0))?;
952 #[unstable(feature = "unix_chown", issue = "88989")]
953 pub fn chown<P: AsRef<Path>>(dir: P, uid: Option<u32>, gid: Option<u32>) -> io::Result<()> {
954 sys::fs::chown(dir.as_ref(), uid.unwrap_or(u32::MAX), gid.unwrap_or(u32::MAX))
957 /// Change the owner and group of the file referenced by the specified open file descriptor.
959 /// For semantics and required privileges, see [`chown`].
964 /// #![feature(unix_chown)]
965 /// use std::os::unix::fs;
967 /// fn main() -> std::io::Result<()> {
968 /// let f = std::fs::File::open("/file")?;
969 /// fs::fchown(&f, Some(0), Some(0))?;
973 #[unstable(feature = "unix_chown", issue = "88989")]
974 pub fn fchown<F: AsFd>(fd: F, uid: Option<u32>, gid: Option<u32>) -> io::Result<()> {
975 sys::fs::fchown(fd.as_fd().as_raw_fd(), uid.unwrap_or(u32::MAX), gid.unwrap_or(u32::MAX))
978 /// Change the owner and group of the specified path, without dereferencing symbolic links.
980 /// Identical to [`chown`], except that if called on a symbolic link, this will change the owner
981 /// and group of the link itself rather than the owner and group of the link target.
986 /// #![feature(unix_chown)]
987 /// use std::os::unix::fs;
989 /// fn main() -> std::io::Result<()> {
990 /// fs::lchown("/symlink", Some(0), Some(0))?;
994 #[unstable(feature = "unix_chown", issue = "88989")]
995 pub fn lchown<P: AsRef<Path>>(dir: P, uid: Option<u32>, gid: Option<u32>) -> io::Result<()> {
996 sys::fs::lchown(dir.as_ref(), uid.unwrap_or(u32::MAX), gid.unwrap_or(u32::MAX))
999 /// Change the root directory of the current process to the specified path.
1001 /// This typically requires privileges, such as root or a specific capability.
1003 /// This does not change the current working directory; you should call
1004 /// [`std::env::set_current_dir`][`crate::env::set_current_dir`] afterwards.
1009 /// use std::os::unix::fs;
1011 /// fn main() -> std::io::Result<()> {
1012 /// fs::chroot("/sandbox")?;
1013 /// std::env::set_current_dir("/")?;
1014 /// // continue working in sandbox
1018 #[stable(feature = "unix_chroot", since = "1.56.0")]
1019 #[cfg(not(any(target_os = "fuchsia", target_os = "vxworks")))]
1020 pub fn chroot<P: AsRef<Path>>(dir: P) -> io::Result<()> {
1021 sys::fs::chroot(dir.as_ref())