]> git.lizzy.rs Git - rust.git/blob - src/libstd/sys/redox/ext/fs.rs
Rollup merge of #58802 - nnethercote:inline-record_layout, r=oli-obk
[rust.git] / src / libstd / sys / redox / ext / fs.rs
1 //! Redox-specific extensions to primitives in the `std::fs` module.
2
3 #![stable(feature = "rust1", since = "1.0.0")]
4
5 use crate::fs::{self, Permissions, OpenOptions};
6 use crate::io;
7 use crate::path::Path;
8 use crate::sys;
9 use crate::sys_common::{FromInner, AsInner, AsInnerMut};
10
11 /// Redox-specific extensions to [`fs::Permissions`].
12 ///
13 /// [`fs::Permissions`]: ../../../../std/fs/struct.Permissions.html
14 #[stable(feature = "fs_ext", since = "1.1.0")]
15 pub trait PermissionsExt {
16     /// Returns the underlying raw `mode_t` bits that are the standard Redox
17     /// permissions for this file.
18     ///
19     /// # Examples
20     ///
21     /// ```no_run
22     /// use std::fs::File;
23     /// use std::os::redox::fs::PermissionsExt;
24     ///
25     /// fn main() -> std::io::Result<()> {
26     ///     let f = File::create("foo.txt")?;
27     ///     let metadata = f.metadata()?;
28     ///     let permissions = metadata.permissions();
29     ///
30     ///     println!("permissions: {}", permissions.mode());
31     ///     Ok(())
32     /// }
33     /// ```
34     #[stable(feature = "fs_ext", since = "1.1.0")]
35     fn mode(&self) -> u32;
36
37     /// Sets the underlying raw bits for this set of permissions.
38     ///
39     /// # Examples
40     ///
41     /// ```no_run
42     /// use std::fs::File;
43     /// use std::os::redox::fs::PermissionsExt;
44     ///
45     /// fn main() -> std::io::Result<()> {
46     ///     let f = File::create("foo.txt")?;
47     ///     let metadata = f.metadata()?;
48     ///     let mut permissions = metadata.permissions();
49     ///
50     ///     permissions.set_mode(0o644); // Read/write for owner and read for others.
51     ///     assert_eq!(permissions.mode(), 0o644);
52     ///     Ok(())
53     /// }
54     /// ```
55     #[stable(feature = "fs_ext", since = "1.1.0")]
56     fn set_mode(&mut self, mode: u32);
57
58     /// Creates a new instance of `Permissions` from the given set of Redox
59     /// permission bits.
60     ///
61     /// # Examples
62     ///
63     /// ```
64     /// use std::fs::Permissions;
65     /// use std::os::redox::fs::PermissionsExt;
66     ///
67     /// // Read/write for owner and read for others.
68     /// let permissions = Permissions::from_mode(0o644);
69     /// assert_eq!(permissions.mode(), 0o644);
70     /// ```
71     #[stable(feature = "fs_ext", since = "1.1.0")]
72     fn from_mode(mode: u32) -> Self;
73 }
74
75 #[stable(feature = "fs_ext", since = "1.1.0")]
76 impl PermissionsExt for Permissions {
77     fn mode(&self) -> u32 {
78         self.as_inner().mode()
79     }
80
81     fn set_mode(&mut self, mode: u32) {
82         *self = Permissions::from_inner(FromInner::from_inner(mode));
83     }
84
85     fn from_mode(mode: u32) -> Permissions {
86         Permissions::from_inner(FromInner::from_inner(mode))
87     }
88 }
89
90 /// Redox-specific extensions to [`fs::OpenOptions`].
91 ///
92 /// [`fs::OpenOptions`]: ../../../../std/fs/struct.OpenOptions.html
93 #[stable(feature = "fs_ext", since = "1.1.0")]
94 pub trait OpenOptionsExt {
95     /// Sets the mode bits that a new file will be created with.
96     ///
97     /// If a new file is created as part of a `File::open_opts` call then this
98     /// specified `mode` will be used as the permission bits for the new file.
99     /// If no `mode` is set, the default of `0o666` will be used.
100     /// The operating system masks out bits with the systems `umask`, to produce
101     /// the final permissions.
102     ///
103     /// # Examples
104     ///
105     /// ```no_run
106     /// # #![feature(libc)]
107     /// extern crate libc;
108     /// use std::fs::OpenOptions;
109     /// use std::os::redox::fs::OpenOptionsExt;
110     ///
111     /// # fn main() {
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");
115     /// # }
116     /// ```
117     #[stable(feature = "fs_ext", since = "1.1.0")]
118     fn mode(&mut self, mode: u32) -> &mut Self;
119
120     /// Passes custom flags to the `flags` argument of `open`.
121     ///
122     /// The bits that define the access mode are masked out with `O_ACCMODE`, to
123     /// ensure they do not interfere with the access mode set by Rusts options.
124     ///
125     /// Custom flags can only set flags, not remove flags set by Rusts options.
126     /// This options overwrites any previously set custom flags.
127     ///
128     /// # Examples
129     ///
130     /// ```no_run
131     /// # #![feature(libc)]
132     /// extern crate libc;
133     /// use std::fs::OpenOptions;
134     /// use std::os::redox::fs::OpenOptionsExt;
135     ///
136     /// # fn main() {
137     /// let mut options = OpenOptions::new();
138     /// options.write(true);
139     /// if cfg!(target_os = "redox") {
140     ///     options.custom_flags(libc::O_NOFOLLOW);
141     /// }
142     /// let file = options.open("foo.txt");
143     /// # }
144     /// ```
145     #[stable(feature = "open_options_ext", since = "1.10.0")]
146     fn custom_flags(&mut self, flags: i32) -> &mut Self;
147 }
148
149 #[stable(feature = "fs_ext", since = "1.1.0")]
150 impl OpenOptionsExt for OpenOptions {
151     fn mode(&mut self, mode: u32) -> &mut OpenOptions {
152         self.as_inner_mut().mode(mode); self
153     }
154
155     fn custom_flags(&mut self, flags: i32) -> &mut OpenOptions {
156         self.as_inner_mut().custom_flags(flags); self
157     }
158 }
159
160 /// Redox-specific extensions to [`fs::Metadata`].
161 ///
162 /// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html
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 size(&self) -> u64;
179     #[stable(feature = "metadata_ext", since = "1.1.0")]
180     fn atime(&self) -> i64;
181     #[stable(feature = "metadata_ext", since = "1.1.0")]
182     fn atime_nsec(&self) -> i64;
183     #[stable(feature = "metadata_ext", since = "1.1.0")]
184     fn mtime(&self) -> i64;
185     #[stable(feature = "metadata_ext", since = "1.1.0")]
186     fn mtime_nsec(&self) -> i64;
187     #[stable(feature = "metadata_ext", since = "1.1.0")]
188     fn ctime(&self) -> i64;
189     #[stable(feature = "metadata_ext", since = "1.1.0")]
190     fn ctime_nsec(&self) -> i64;
191     #[stable(feature = "metadata_ext", since = "1.1.0")]
192     fn blksize(&self) -> u64;
193     #[stable(feature = "metadata_ext", since = "1.1.0")]
194     fn blocks(&self) -> u64;
195 }
196
197 // Hm, why are there casts here to the returned type, shouldn't the types always
198 // be the same? Right you are! Turns out, however, on android at least the types
199 // in the raw `stat` structure are not the same as the types being returned. Who
200 // knew!
201 //
202 // As a result to make sure this compiles for all platforms we do the manual
203 // casts and rely on manual lowering to `stat` if the raw type is desired.
204 #[stable(feature = "metadata_ext", since = "1.1.0")]
205 impl MetadataExt for fs::Metadata {
206     fn dev(&self) -> u64 {
207         self.as_inner().as_inner().st_dev as u64
208     }
209     fn ino(&self) -> u64 {
210         self.as_inner().as_inner().st_ino as u64
211     }
212     fn mode(&self) -> u32 {
213         self.as_inner().as_inner().st_mode as u32
214     }
215     fn nlink(&self) -> u64 {
216         self.as_inner().as_inner().st_nlink as u64
217     }
218     fn uid(&self) -> u32 {
219         self.as_inner().as_inner().st_uid as u32
220     }
221     fn gid(&self) -> u32 {
222         self.as_inner().as_inner().st_gid as u32
223     }
224     fn size(&self) -> u64 {
225         self.as_inner().as_inner().st_size as u64
226     }
227     fn atime(&self) -> i64 {
228         self.as_inner().as_inner().st_atime as i64
229     }
230     fn atime_nsec(&self) -> i64 {
231         self.as_inner().as_inner().st_atime_nsec as i64
232     }
233     fn mtime(&self) -> i64 {
234         self.as_inner().as_inner().st_mtime as i64
235     }
236     fn mtime_nsec(&self) -> i64 {
237         self.as_inner().as_inner().st_mtime_nsec as i64
238     }
239     fn ctime(&self) -> i64 {
240         self.as_inner().as_inner().st_ctime as i64
241     }
242     fn ctime_nsec(&self) -> i64 {
243         self.as_inner().as_inner().st_ctime_nsec as i64
244     }
245     fn blksize(&self) -> u64 {
246         self.as_inner().as_inner().st_blksize as u64
247     }
248     fn blocks(&self) -> u64 {
249         self.as_inner().as_inner().st_blocks as u64
250     }
251 }
252
253 /// Redox-specific extensions for [`FileType`].
254 ///
255 /// Adds support for special Unix file types such as block/character devices,
256 /// pipes, and sockets.
257 ///
258 /// [`FileType`]: ../../../../std/fs/struct.FileType.html
259 #[stable(feature = "file_type_ext", since = "1.5.0")]
260 pub trait FileTypeExt {
261     /// Returns whether this file type is a block device.
262     #[stable(feature = "file_type_ext", since = "1.5.0")]
263     fn is_block_device(&self) -> bool;
264     /// Returns whether this file type is a char device.
265     #[stable(feature = "file_type_ext", since = "1.5.0")]
266     fn is_char_device(&self) -> bool;
267     /// Returns whether this file type is a fifo.
268     #[stable(feature = "file_type_ext", since = "1.5.0")]
269     fn is_fifo(&self) -> bool;
270     /// Returns whether this file type is a socket.
271     #[stable(feature = "file_type_ext", since = "1.5.0")]
272     fn is_socket(&self) -> bool;
273 }
274
275 #[stable(feature = "file_type_ext", since = "1.5.0")]
276 impl FileTypeExt for fs::FileType {
277     fn is_block_device(&self) -> bool { false /*FIXME: Implement block device mode*/ }
278     fn is_char_device(&self) -> bool { false /*FIXME: Implement char device mode*/ }
279     fn is_fifo(&self) -> bool { false /*FIXME: Implement fifo mode*/ }
280     fn is_socket(&self) -> bool { false /*FIXME: Implement socket mode*/ }
281 }
282
283 /// Creates a new symbolic link on the filesystem.
284 ///
285 /// The `dst` path will be a symbolic link pointing to the `src` path.
286 ///
287 /// # Note
288 ///
289 /// On Windows, you must specify whether a symbolic link points to a file
290 /// or directory. Use `os::windows::fs::symlink_file` to create a
291 /// symbolic link to a file, or `os::windows::fs::symlink_dir` to create a
292 /// symbolic link to a directory. Additionally, the process must have
293 /// `SeCreateSymbolicLinkPrivilege` in order to be able to create a
294 /// symbolic link.
295 ///
296 /// # Examples
297 ///
298 /// ```no_run
299 /// use std::os::redox::fs;
300 ///
301 /// fn main() -> std::io::Result<()> {
302 ///     fs::symlink("a.txt", "b.txt")?;
303 ///     Ok(())
304 /// }
305 /// ```
306 #[stable(feature = "symlink", since = "1.1.0")]
307 pub fn symlink<P: AsRef<Path>, Q: AsRef<Path>>(src: P, dst: Q) -> io::Result<()>
308 {
309     sys::fs::symlink(src.as_ref(), dst.as_ref())
310 }
311
312 /// Redox-specific extensions to [`fs::DirBuilder`].
313 ///
314 /// [`fs::DirBuilder`]: ../../../../std/fs/struct.DirBuilder.html
315 #[stable(feature = "dir_builder", since = "1.6.0")]
316 pub trait DirBuilderExt {
317     /// Sets the mode to create new directories with. This option defaults to
318     /// 0o777.
319     ///
320     /// # Examples
321     ///
322     /// ```no_run
323     /// use std::fs::DirBuilder;
324     /// use std::os::redox::fs::DirBuilderExt;
325     ///
326     /// let mut builder = DirBuilder::new();
327     /// builder.mode(0o755);
328     /// ```
329     #[stable(feature = "dir_builder", since = "1.6.0")]
330     fn mode(&mut self, mode: u32) -> &mut Self;
331 }
332
333 #[stable(feature = "dir_builder", since = "1.6.0")]
334 impl DirBuilderExt for fs::DirBuilder {
335     fn mode(&mut self, mode: u32) -> &mut fs::DirBuilder {
336         self.as_inner_mut().set_mode(mode);
337         self
338     }
339 }