1 // Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 //! Unix-specific extensions to primitives in the `std::fs` module.
13 #![stable(feature = "rust1", since = "1.0.0")]
15 use fs::{self, Permissions, OpenOptions};
20 use sys_common::{FromInner, AsInner, AsInnerMut};
21 use sys::platform::fs::MetadataExt as UnixMetadataExt;
23 /// Unix-specific extensions to `Permissions`
24 #[stable(feature = "fs_ext", since = "1.1.0")]
25 pub trait PermissionsExt {
26 /// Returns the underlying raw `mode_t` bits that are the standard Unix
27 /// permissions for this file.
32 /// use std::fs::File;
33 /// use std::os::unix::fs::PermissionsExt;
35 /// let f = try!(File::create("foo.txt"));
36 /// let metadata = try!(f.metadata());
37 /// let permissions = metadata.permissions();
39 /// println!("permissions: {}", permissions.mode());
41 #[stable(feature = "fs_ext", since = "1.1.0")]
42 fn mode(&self) -> u32;
44 /// Sets the underlying raw bits for this set of permissions.
49 /// use std::fs::File;
50 /// use std::os::unix::fs::PermissionsExt;
52 /// let f = try!(File::create("foo.txt"));
53 /// let metadata = try!(f.metadata());
54 /// let mut permissions = metadata.permissions();
56 /// permissions.set_mode(0o644); // Read/write for owner and read for others.
57 /// assert_eq!(permissions.mode(), 0o644);
59 #[stable(feature = "fs_ext", since = "1.1.0")]
60 fn set_mode(&mut self, mode: u32);
62 /// Creates a new instance of `Permissions` from the given set of Unix
68 /// use std::fs::Permissions;
69 /// use std::os::unix::fs::PermissionsExt;
71 /// // Read/write for owner and read for others.
72 /// let permissions = Permissions::from_mode(0o644);
73 /// assert_eq!(permissions.mode(), 0o644);
75 #[stable(feature = "fs_ext", since = "1.1.0")]
76 fn from_mode(mode: u32) -> Self;
79 #[stable(feature = "fs_ext", since = "1.1.0")]
80 impl PermissionsExt for Permissions {
81 fn mode(&self) -> u32 {
82 self.as_inner().mode()
85 fn set_mode(&mut self, mode: u32) {
86 *self = Permissions::from_inner(FromInner::from_inner(mode));
89 fn from_mode(mode: u32) -> Permissions {
90 Permissions::from_inner(FromInner::from_inner(mode))
94 /// Unix-specific extensions to `OpenOptions`
95 #[stable(feature = "fs_ext", since = "1.1.0")]
96 pub trait OpenOptionsExt {
97 /// Sets the mode bits that a new file will be created with.
99 /// If a new file is created as part of a `File::open_opts` call then this
100 /// specified `mode` will be used as the permission bits for the new file.
101 /// If no `mode` is set, the default of `0o666` will be used.
102 /// The operating system masks out bits with the systems `umask`, to produce
103 /// the final permissions.
108 /// extern crate libc;
109 /// use std::fs::OpenOptions;
110 /// use std::os::unix::fs::OpenOptionsExt;
112 /// let mut options = OpenOptions::new();
113 /// options.mode(0o644); // Give read/write for owner and read for others.
114 /// let file = options.open("foo.txt");
116 #[stable(feature = "fs_ext", since = "1.1.0")]
117 fn mode(&mut self, mode: u32) -> &mut Self;
119 /// Pass custom flags to the `flags` agument of `open`.
121 /// The bits that define the access mode are masked out with `O_ACCMODE`, to
122 /// ensure they do not interfere with the access mode set by Rusts options.
124 /// Custom flags can only set flags, not remove flags set by Rusts options.
125 /// This options overwrites any previously set custom flags.
130 /// extern crate libc;
131 /// use std::fs::OpenOptions;
132 /// use std::os::unix::fs::OpenOptionsExt;
134 /// let mut options = OpenOptions::new();
135 /// options.write(true);
137 /// options.custom_flags(libc::O_NOFOLLOW);
139 /// let file = options.open("foo.txt");
141 #[stable(feature = "open_options_ext", since = "1.10.0")]
142 fn custom_flags(&mut self, flags: i32) -> &mut Self;
145 #[stable(feature = "fs_ext", since = "1.1.0")]
146 impl OpenOptionsExt for OpenOptions {
147 fn mode(&mut self, mode: u32) -> &mut OpenOptions {
148 self.as_inner_mut().mode(mode); self
151 fn custom_flags(&mut self, flags: i32) -> &mut OpenOptions {
152 self.as_inner_mut().custom_flags(flags); self
156 // Hm, why are there casts here to the returned type, shouldn't the types always
157 // be the same? Right you are! Turns out, however, on android at least the types
158 // in the raw `stat` structure are not the same as the types being returned. Who
161 // As a result to make sure this compiles for all platforms we do the manual
162 // casts and rely on manual lowering to `stat` if the raw type is desired.
163 #[stable(feature = "metadata_ext", since = "1.1.0")]
164 pub trait MetadataExt {
165 #[stable(feature = "metadata_ext", since = "1.1.0")]
166 fn dev(&self) -> u64;
167 #[stable(feature = "metadata_ext", since = "1.1.0")]
168 fn ino(&self) -> u64;
169 #[stable(feature = "metadata_ext", since = "1.1.0")]
170 fn mode(&self) -> u32;
171 #[stable(feature = "metadata_ext", since = "1.1.0")]
172 fn nlink(&self) -> u64;
173 #[stable(feature = "metadata_ext", since = "1.1.0")]
174 fn uid(&self) -> u32;
175 #[stable(feature = "metadata_ext", since = "1.1.0")]
176 fn gid(&self) -> u32;
177 #[stable(feature = "metadata_ext", since = "1.1.0")]
178 fn rdev(&self) -> u64;
179 #[stable(feature = "metadata_ext", since = "1.1.0")]
180 fn size(&self) -> u64;
181 #[stable(feature = "metadata_ext", since = "1.1.0")]
182 fn atime(&self) -> i64;
183 #[stable(feature = "metadata_ext", since = "1.1.0")]
184 fn atime_nsec(&self) -> i64;
185 #[stable(feature = "metadata_ext", since = "1.1.0")]
186 fn mtime(&self) -> i64;
187 #[stable(feature = "metadata_ext", since = "1.1.0")]
188 fn mtime_nsec(&self) -> i64;
189 #[stable(feature = "metadata_ext", since = "1.1.0")]
190 fn ctime(&self) -> i64;
191 #[stable(feature = "metadata_ext", since = "1.1.0")]
192 fn ctime_nsec(&self) -> i64;
193 #[stable(feature = "metadata_ext", since = "1.1.0")]
194 fn blksize(&self) -> u64;
195 #[stable(feature = "metadata_ext", since = "1.1.0")]
196 fn blocks(&self) -> u64;
199 #[stable(feature = "metadata_ext", since = "1.1.0")]
200 impl MetadataExt for fs::Metadata {
201 fn dev(&self) -> u64 { self.st_dev() }
202 fn ino(&self) -> u64 { self.st_ino() }
203 fn mode(&self) -> u32 { self.st_mode() }
204 fn nlink(&self) -> u64 { self.st_nlink() }
205 fn uid(&self) -> u32 { self.st_uid() }
206 fn gid(&self) -> u32 { self.st_gid() }
207 fn rdev(&self) -> u64 { self.st_rdev() }
208 fn size(&self) -> u64 { self.st_size() }
209 fn atime(&self) -> i64 { self.st_atime() }
210 fn atime_nsec(&self) -> i64 { self.st_atime_nsec() }
211 fn mtime(&self) -> i64 { self.st_mtime() }
212 fn mtime_nsec(&self) -> i64 { self.st_mtime_nsec() }
213 fn ctime(&self) -> i64 { self.st_ctime() }
214 fn ctime_nsec(&self) -> i64 { self.st_ctime_nsec() }
215 fn blksize(&self) -> u64 { self.st_blksize() }
216 fn blocks(&self) -> u64 { self.st_blocks() }
219 /// Add special unix types (block/char device, fifo and socket)
220 #[stable(feature = "file_type_ext", since = "1.5.0")]
221 pub trait FileTypeExt {
222 /// Returns whether this file type is a block device.
223 #[stable(feature = "file_type_ext", since = "1.5.0")]
224 fn is_block_device(&self) -> bool;
225 /// Returns whether this file type is a char device.
226 #[stable(feature = "file_type_ext", since = "1.5.0")]
227 fn is_char_device(&self) -> bool;
228 /// Returns whether this file type is a fifo.
229 #[stable(feature = "file_type_ext", since = "1.5.0")]
230 fn is_fifo(&self) -> bool;
231 /// Returns whether this file type is a socket.
232 #[stable(feature = "file_type_ext", since = "1.5.0")]
233 fn is_socket(&self) -> bool;
236 #[stable(feature = "file_type_ext", since = "1.5.0")]
237 impl FileTypeExt for fs::FileType {
238 fn is_block_device(&self) -> bool { self.as_inner().is(libc::S_IFBLK) }
239 fn is_char_device(&self) -> bool { self.as_inner().is(libc::S_IFCHR) }
240 fn is_fifo(&self) -> bool { self.as_inner().is(libc::S_IFIFO) }
241 fn is_socket(&self) -> bool { self.as_inner().is(libc::S_IFSOCK) }
244 /// Unix-specific extension methods for `fs::DirEntry`
245 #[stable(feature = "dir_entry_ext", since = "1.1.0")]
246 pub trait DirEntryExt {
247 /// Returns the underlying `d_ino` field in the contained `dirent`
254 /// use std::os::unix::fs::DirEntryExt;
256 /// if let Ok(entries) = fs::read_dir(".") {
257 /// for entry in entries {
258 /// if let Ok(entry) = entry {
259 /// // Here, `entry` is a `DirEntry`.
260 /// println!("{:?}: {}", entry.file_name(), entry.ino());
265 #[stable(feature = "dir_entry_ext", since = "1.1.0")]
266 fn ino(&self) -> u64;
269 #[stable(feature = "dir_entry_ext", since = "1.1.0")]
270 impl DirEntryExt for fs::DirEntry {
271 fn ino(&self) -> u64 { self.as_inner().ino() }
274 /// Creates a new symbolic link on the filesystem.
276 /// The `dst` path will be a symbolic link pointing to the `src` path.
280 /// On Windows, you must specify whether a symbolic link points to a file
281 /// or directory. Use `os::windows::fs::symlink_file` to create a
282 /// symbolic link to a file, or `os::windows::fs::symlink_dir` to create a
283 /// symbolic link to a directory. Additionally, the process must have
284 /// `SeCreateSymbolicLinkPrivilege` in order to be able to create a
290 /// use std::os::unix::fs;
292 /// # fn foo() -> std::io::Result<()> {
293 /// try!(fs::symlink("a.txt", "b.txt"));
297 #[stable(feature = "symlink", since = "1.1.0")]
298 pub fn symlink<P: AsRef<Path>, Q: AsRef<Path>>(src: P, dst: Q) -> io::Result<()>
300 sys::fs::symlink(src.as_ref(), dst.as_ref())
303 #[stable(feature = "dir_builder", since = "1.6.0")]
304 /// An extension trait for `fs::DirBuilder` for unix-specific options.
305 pub trait DirBuilderExt {
306 /// Sets the mode to create new directories with. This option defaults to
312 /// use std::fs::DirBuilder;
313 /// use std::os::unix::fs::DirBuilderExt;
315 /// let mut builder = DirBuilder::new();
316 /// builder.mode(0o755);
318 #[stable(feature = "dir_builder", since = "1.6.0")]
319 fn mode(&mut self, mode: u32) -> &mut Self;
322 #[stable(feature = "dir_builder", since = "1.6.0")]
323 impl DirBuilderExt for fs::DirBuilder {
324 fn mode(&mut self, mode: u32) -> &mut fs::DirBuilder {
325 self.as_inner_mut().set_mode(mode);