]> git.lizzy.rs Git - rust.git/blob - src/libstd/sys/windows/ext/fs.rs
Add riscv64gc-unknown-none-elf target
[rust.git] / src / libstd / sys / windows / ext / fs.rs
1 //! Windows-specific extensions for the primitives in the `std::fs` module.
2
3 #![stable(feature = "rust1", since = "1.0.0")]
4
5 use fs::{self, OpenOptions, Metadata};
6 use io;
7 use path::Path;
8 use sys;
9 use sys_common::{AsInnerMut, AsInner};
10
11 /// Windows-specific extensions to [`File`].
12 ///
13 /// [`File`]: ../../../fs/struct.File.html
14 #[stable(feature = "file_offset", since = "1.15.0")]
15 pub trait FileExt {
16     /// Seeks to a given position and reads a number of bytes.
17     ///
18     /// Returns the number of bytes read.
19     ///
20     /// The offset is relative to the start of the file and thus independent
21     /// from the current cursor. The current cursor **is** affected by this
22     /// function, it is set to the end of the read.
23     ///
24     /// Reading beyond the end of the file will always return with a length of
25     /// 0\.
26     ///
27     /// Note that similar to `File::read`, it is not an error to return with a
28     /// short read. When returning from such a short read, the file pointer is
29     /// still updated.
30     ///
31     /// # Examples
32     ///
33     /// ```no_run
34     /// use std::io;
35     /// use std::fs::File;
36     /// use std::os::windows::prelude::*;
37     ///
38     /// fn main() -> io::Result<()> {
39     ///     let mut file = File::open("foo.txt")?;
40     ///     let mut buffer = [0; 10];
41     ///
42     ///     // Read 10 bytes, starting 72 bytes from the
43     ///     // start of the file.
44     ///     file.seek_read(&mut buffer[..], 72)?;
45     ///     Ok(())
46     /// }
47     /// ```
48     #[stable(feature = "file_offset", since = "1.15.0")]
49     fn seek_read(&self, buf: &mut [u8], offset: u64) -> io::Result<usize>;
50
51     /// Seeks to a given position and writes a number of bytes.
52     ///
53     /// Returns the number of bytes written.
54     ///
55     /// The offset is relative to the start of the file and thus independent
56     /// from the current cursor. The current cursor **is** affected by this
57     /// function, it is set to the end of the write.
58     ///
59     /// When writing beyond the end of the file, the file is appropriately
60     /// extended and the intermediate bytes are left uninitialized.
61     ///
62     /// Note that similar to `File::write`, it is not an error to return a
63     /// short write. When returning from such a short write, the file pointer
64     /// is still updated.
65     ///
66     /// # Examples
67     ///
68     /// ```no_run
69     /// use std::fs::File;
70     /// use std::os::windows::prelude::*;
71     ///
72     /// fn main() -> std::io::Result<()> {
73     ///     let mut buffer = File::create("foo.txt")?;
74     ///
75     ///     // Write a byte string starting 72 bytes from
76     ///     // the start of the file.
77     ///     buffer.seek_write(b"some bytes", 72)?;
78     ///     Ok(())
79     /// }
80     /// ```
81     #[stable(feature = "file_offset", since = "1.15.0")]
82     fn seek_write(&self, buf: &[u8], offset: u64) -> io::Result<usize>;
83 }
84
85 #[stable(feature = "file_offset", since = "1.15.0")]
86 impl FileExt for fs::File {
87     fn seek_read(&self, buf: &mut [u8], offset: u64) -> io::Result<usize> {
88         self.as_inner().read_at(buf, offset)
89     }
90
91     fn seek_write(&self, buf: &[u8], offset: u64) -> io::Result<usize> {
92         self.as_inner().write_at(buf, offset)
93     }
94 }
95
96 /// Windows-specific extensions to [`fs::OpenOptions`].
97 ///
98 /// [`fs::OpenOptions`]: ../../../../std/fs/struct.OpenOptions.html
99 #[stable(feature = "open_options_ext", since = "1.10.0")]
100 pub trait OpenOptionsExt {
101     /// Overrides the `dwDesiredAccess` argument to the call to [`CreateFile`]
102     /// with the specified value.
103     ///
104     /// This will override the `read`, `write`, and `append` flags on the
105     /// `OpenOptions` structure. This method provides fine-grained control over
106     /// the permissions to read, write and append data, attributes (like hidden
107     /// and system), and extended attributes.
108     ///
109     /// # Examples
110     ///
111     /// ```no_run
112     /// use std::fs::OpenOptions;
113     /// use std::os::windows::prelude::*;
114     ///
115     /// // Open without read and write permission, for example if you only need
116     /// // to call `stat` on the file
117     /// let file = OpenOptions::new().access_mode(0).open("foo.txt");
118     /// ```
119     ///
120     /// [`CreateFile`]: https://msdn.microsoft.com/en-us/library/windows/desktop/aa363858.aspx
121     #[stable(feature = "open_options_ext", since = "1.10.0")]
122     fn access_mode(&mut self, access: u32) -> &mut Self;
123
124     /// Overrides the `dwShareMode` argument to the call to [`CreateFile`] with
125     /// the specified value.
126     ///
127     /// By default `share_mode` is set to
128     /// `FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE`. This allows
129     /// other processes to read, write, and delete/rename the same file
130     /// while it is open. Removing any of the flags will prevent other
131     /// processes from performing the corresponding operation until the file
132     /// handle is closed.
133     ///
134     /// # Examples
135     ///
136     /// ```no_run
137     /// use std::fs::OpenOptions;
138     /// use std::os::windows::prelude::*;
139     ///
140     /// // Do not allow others to read or modify this file while we have it open
141     /// // for writing.
142     /// let file = OpenOptions::new()
143     ///     .write(true)
144     ///     .share_mode(0)
145     ///     .open("foo.txt");
146     /// ```
147     ///
148     /// [`CreateFile`]: https://msdn.microsoft.com/en-us/library/windows/desktop/aa363858.aspx
149     #[stable(feature = "open_options_ext", since = "1.10.0")]
150     fn share_mode(&mut self, val: u32) -> &mut Self;
151
152     /// Sets extra flags for the `dwFileFlags` argument to the call to
153     /// [`CreateFile2`] to the specified value (or combines it with
154     /// `attributes` and `security_qos_flags` to set the `dwFlagsAndAttributes`
155     /// for [`CreateFile`]).
156     ///
157     /// Custom flags can only set flags, not remove flags set by Rust's options.
158     /// This option overwrites any previously set custom flags.
159     ///
160     /// # Examples
161     ///
162     /// ```no_run
163     /// # #[cfg(for_demonstration_only)]
164     /// extern crate winapi;
165     /// # mod winapi { pub const FILE_FLAG_DELETE_ON_CLOSE: u32 = 0x04000000; }
166     ///
167     /// use std::fs::OpenOptions;
168     /// use std::os::windows::prelude::*;
169     ///
170     /// let file = OpenOptions::new()
171     ///     .create(true)
172     ///     .write(true)
173     ///     .custom_flags(winapi::FILE_FLAG_DELETE_ON_CLOSE)
174     ///     .open("foo.txt");
175     /// ```
176     ///
177     /// [`CreateFile`]: https://msdn.microsoft.com/en-us/library/windows/desktop/aa363858.aspx
178     /// [`CreateFile2`]: https://msdn.microsoft.com/en-us/library/windows/desktop/hh449422.aspx
179     #[stable(feature = "open_options_ext", since = "1.10.0")]
180     fn custom_flags(&mut self, flags: u32) -> &mut Self;
181
182     /// Sets the `dwFileAttributes` argument to the call to [`CreateFile2`] to
183     /// the specified value (or combines it with `custom_flags` and
184     /// `security_qos_flags` to set the `dwFlagsAndAttributes` for
185     /// [`CreateFile`]).
186     ///
187     /// If a _new_ file is created because it does not yet exist and
188     /// `.create(true)` or `.create_new(true)` are specified, the new file is
189     /// given the attributes declared with `.attributes()`.
190     ///
191     /// If an _existing_ file is opened with `.create(true).truncate(true)`, its
192     /// existing attributes are preserved and combined with the ones declared
193     /// with `.attributes()`.
194     ///
195     /// In all other cases the attributes get ignored.
196     ///
197     /// # Examples
198     ///
199     /// ```no_run
200     /// # #[cfg(for_demonstration_only)]
201     /// extern crate winapi;
202     /// # mod winapi { pub const FILE_ATTRIBUTE_HIDDEN: u32 = 2; }
203     ///
204     /// use std::fs::OpenOptions;
205     /// use std::os::windows::prelude::*;
206     ///
207     /// let file = OpenOptions::new()
208     ///     .write(true)
209     ///     .create(true)
210     ///     .attributes(winapi::FILE_ATTRIBUTE_HIDDEN)
211     ///     .open("foo.txt");
212     /// ```
213     ///
214     /// [`CreateFile`]: https://msdn.microsoft.com/en-us/library/windows/desktop/aa363858.aspx
215     /// [`CreateFile2`]: https://msdn.microsoft.com/en-us/library/windows/desktop/hh449422.aspx
216     #[stable(feature = "open_options_ext", since = "1.10.0")]
217     fn attributes(&mut self, val: u32) -> &mut Self;
218
219     /// Sets the `dwSecurityQosFlags` argument to the call to [`CreateFile2`] to
220     /// the specified value (or combines it with `custom_flags` and `attributes`
221     /// to set the `dwFlagsAndAttributes` for [`CreateFile`]).
222     ///
223     /// By default, `security_qos_flags` is set to `SECURITY_ANONYMOUS`. For
224     /// information about possible values, see [Impersonation Levels] on the
225     /// Windows Dev Center site.
226     ///
227     /// # Examples
228     ///
229     /// ```no_run
230     /// use std::fs::OpenOptions;
231     /// use std::os::windows::prelude::*;
232     ///
233     /// let file = OpenOptions::new()
234     ///     .write(true)
235     ///     .create(true)
236     ///
237     ///     // Sets the flag value to `SecurityIdentification`.
238     ///     .security_qos_flags(1)
239     ///
240     ///     .open("foo.txt");
241     /// ```
242     ///
243     /// [`CreateFile`]: https://msdn.microsoft.com/en-us/library/windows/desktop/aa363858.aspx
244     /// [`CreateFile2`]: https://msdn.microsoft.com/en-us/library/windows/desktop/hh449422.aspx
245     /// [Impersonation Levels]:
246     ///     https://msdn.microsoft.com/en-us/library/windows/desktop/aa379572.aspx
247     #[stable(feature = "open_options_ext", since = "1.10.0")]
248     fn security_qos_flags(&mut self, flags: u32) -> &mut OpenOptions;
249 }
250
251 #[stable(feature = "open_options_ext", since = "1.10.0")]
252 impl OpenOptionsExt for OpenOptions {
253     fn access_mode(&mut self, access: u32) -> &mut OpenOptions {
254         self.as_inner_mut().access_mode(access); self
255     }
256
257     fn share_mode(&mut self, share: u32) -> &mut OpenOptions {
258         self.as_inner_mut().share_mode(share); self
259     }
260
261     fn custom_flags(&mut self, flags: u32) -> &mut OpenOptions {
262         self.as_inner_mut().custom_flags(flags); self
263     }
264
265     fn attributes(&mut self, attributes: u32) -> &mut OpenOptions {
266         self.as_inner_mut().attributes(attributes); self
267     }
268
269     fn security_qos_flags(&mut self, flags: u32) -> &mut OpenOptions {
270         self.as_inner_mut().security_qos_flags(flags); self
271     }
272 }
273
274 /// Windows-specific extensions to [`fs::Metadata`].
275 ///
276 /// The data members that this trait exposes correspond to the members
277 /// of the [`BY_HANDLE_FILE_INFORMATION`] structure.
278 ///
279 /// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html
280 /// [`BY_HANDLE_FILE_INFORMATION`]:
281 ///     https://msdn.microsoft.com/en-us/library/windows/desktop/aa363788.aspx
282 #[stable(feature = "metadata_ext", since = "1.1.0")]
283 pub trait MetadataExt {
284     /// Returns the value of the `dwFileAttributes` field of this metadata.
285     ///
286     /// This field contains the file system attribute information for a file
287     /// or directory. For possible values and their descriptions, see
288     /// [File Attribute Constants] in the Windows Dev Center.
289     ///
290     /// # Examples
291     ///
292     /// ```no_run
293     /// use std::io;
294     /// use std::fs;
295     /// use std::os::windows::prelude::*;
296     ///
297     /// fn main() -> io::Result<()> {
298     ///     let metadata = fs::metadata("foo.txt")?;
299     ///     let attributes = metadata.file_attributes();
300     ///     Ok(())
301     /// }
302     /// ```
303     ///
304     /// [File Attribute Constants]:
305     ///     https://msdn.microsoft.com/en-us/library/windows/desktop/gg258117.aspx
306     #[stable(feature = "metadata_ext", since = "1.1.0")]
307     fn file_attributes(&self) -> u32;
308
309     /// Returns the value of the `ftCreationTime` field of this metadata.
310     ///
311     /// The returned 64-bit value is equivalent to a [`FILETIME`] struct,
312     /// which represents the number of 100-nanosecond intervals since
313     /// January 1, 1601 (UTC). The struct is automatically
314     /// converted to a `u64` value, as that is the recommended way
315     /// to use it.
316     ///
317     /// If the underlying filesystem does not support creation time, the
318     /// returned value is 0.
319     ///
320     /// # Examples
321     ///
322     /// ```no_run
323     /// use std::io;
324     /// use std::fs;
325     /// use std::os::windows::prelude::*;
326     ///
327     /// fn main() -> io::Result<()> {
328     ///     let metadata = fs::metadata("foo.txt")?;
329     ///     let creation_time = metadata.creation_time();
330     ///     Ok(())
331     /// }
332     /// ```
333     ///
334     /// [`FILETIME`]: https://msdn.microsoft.com/en-us/library/windows/desktop/ms724284.aspx
335     #[stable(feature = "metadata_ext", since = "1.1.0")]
336     fn creation_time(&self) -> u64;
337
338     /// Returns the value of the `ftLastAccessTime` field of this metadata.
339     ///
340     /// The returned 64-bit value is equivalent to a [`FILETIME`] struct,
341     /// which represents the number of 100-nanosecond intervals since
342     /// January 1, 1601 (UTC). The struct is automatically
343     /// converted to a `u64` value, as that is the recommended way
344     /// to use it.
345     ///
346     /// For a file, the value specifies the last time that a file was read
347     /// from or written to. For a directory, the value specifies when
348     /// the directory was created. For both files and directories, the
349     /// specified date is correct, but the time of day is always set to
350     /// midnight.
351     ///
352     /// If the underlying filesystem does not support last access time, the
353     /// returned value is 0.
354     ///
355     /// # Examples
356     ///
357     /// ```no_run
358     /// use std::io;
359     /// use std::fs;
360     /// use std::os::windows::prelude::*;
361     ///
362     /// fn main() -> io::Result<()> {
363     ///     let metadata = fs::metadata("foo.txt")?;
364     ///     let last_access_time = metadata.last_access_time();
365     ///     Ok(())
366     /// }
367     /// ```
368     ///
369     /// [`FILETIME`]: https://msdn.microsoft.com/en-us/library/windows/desktop/ms724284.aspx
370     #[stable(feature = "metadata_ext", since = "1.1.0")]
371     fn last_access_time(&self) -> u64;
372
373     /// Returns the value of the `ftLastWriteTime` field of this metadata.
374     ///
375     /// The returned 64-bit value is equivalent to a [`FILETIME`] struct,
376     /// which represents the number of 100-nanosecond intervals since
377     /// January 1, 1601 (UTC). The struct is automatically
378     /// converted to a `u64` value, as that is the recommended way
379     /// to use it.
380     ///
381     /// For a file, the value specifies the last time that a file was written
382     /// to. For a directory, the structure specifies when the directory was
383     /// created.
384     ///
385     /// If the underlying filesystem does not support the last write time,
386     /// the returned value is 0.
387     ///
388     /// # Examples
389     ///
390     /// ```no_run
391     /// use std::io;
392     /// use std::fs;
393     /// use std::os::windows::prelude::*;
394     ///
395     /// fn main() -> io::Result<()> {
396     ///     let metadata = fs::metadata("foo.txt")?;
397     ///     let last_write_time = metadata.last_write_time();
398     ///     Ok(())
399     /// }
400     /// ```
401     ///
402     /// [`FILETIME`]: https://msdn.microsoft.com/en-us/library/windows/desktop/ms724284.aspx
403     #[stable(feature = "metadata_ext", since = "1.1.0")]
404     fn last_write_time(&self) -> u64;
405
406     /// Returns the value of the `nFileSize{High,Low}` fields of this
407     /// metadata.
408     ///
409     /// The returned value does not have meaning for directories.
410     ///
411     /// # Examples
412     ///
413     /// ```no_run
414     /// use std::io;
415     /// use std::fs;
416     /// use std::os::windows::prelude::*;
417     ///
418     /// fn main() -> io::Result<()> {
419     ///     let metadata = fs::metadata("foo.txt")?;
420     ///     let file_size = metadata.file_size();
421     ///     Ok(())
422     /// }
423     /// ```
424     #[stable(feature = "metadata_ext", since = "1.1.0")]
425     fn file_size(&self) -> u64;
426 }
427
428 #[stable(feature = "metadata_ext", since = "1.1.0")]
429 impl MetadataExt for Metadata {
430     fn file_attributes(&self) -> u32 { self.as_inner().attrs() }
431     fn creation_time(&self) -> u64 { self.as_inner().created_u64() }
432     fn last_access_time(&self) -> u64 { self.as_inner().accessed_u64() }
433     fn last_write_time(&self) -> u64 { self.as_inner().modified_u64() }
434     fn file_size(&self) -> u64 { self.as_inner().size() }
435 }
436
437 /// Windows-specific extensions to [`FileType`].
438 ///
439 /// On Windows, a symbolic link knows whether it is a file or directory.
440 ///
441 /// [`FileType`]: ../../../../std/fs/struct.FileType.html
442 #[unstable(feature = "windows_file_type_ext", issue = "0")]
443 pub trait FileTypeExt {
444     /// Returns whether this file type is a symbolic link that is also a directory.
445     #[unstable(feature = "windows_file_type_ext", issue = "0")]
446     fn is_symlink_dir(&self) -> bool;
447     /// Returns whether this file type is a symbolic link that is also a file.
448     #[unstable(feature = "windows_file_type_ext", issue = "0")]
449     fn is_symlink_file(&self) -> bool;
450 }
451
452 #[unstable(feature = "windows_file_type_ext", issue = "0")]
453 impl FileTypeExt for fs::FileType {
454     fn is_symlink_dir(&self) -> bool { self.as_inner().is_symlink_dir() }
455     fn is_symlink_file(&self) -> bool { self.as_inner().is_symlink_file() }
456 }
457
458 /// Creates a new file symbolic link on the filesystem.
459 ///
460 /// The `dst` path will be a file symbolic link pointing to the `src`
461 /// path.
462 ///
463 /// # Examples
464 ///
465 /// ```no_run
466 /// use std::os::windows::fs;
467 ///
468 /// fn main() -> std::io::Result<()> {
469 ///     fs::symlink_file("a.txt", "b.txt")?;
470 ///     Ok(())
471 /// }
472 /// ```
473 #[stable(feature = "symlink", since = "1.1.0")]
474 pub fn symlink_file<P: AsRef<Path>, Q: AsRef<Path>>(src: P, dst: Q)
475                                                     -> io::Result<()> {
476     sys::fs::symlink_inner(src.as_ref(), dst.as_ref(), false)
477 }
478
479 /// Creates a new directory symlink on the filesystem.
480 ///
481 /// The `dst` path will be a directory symbolic link pointing to the `src`
482 /// path.
483 ///
484 /// # Examples
485 ///
486 /// ```no_run
487 /// use std::os::windows::fs;
488 ///
489 /// fn main() -> std::io::Result<()> {
490 ///     fs::symlink_dir("a", "b")?;
491 ///     Ok(())
492 /// }
493 /// ```
494 #[stable(feature = "symlink", since = "1.1.0")]
495 pub fn symlink_dir<P: AsRef<Path>, Q: AsRef<Path>>(src: P, dst: Q)
496                                                    -> io::Result<()> {
497     sys::fs::symlink_inner(src.as_ref(), dst.as_ref(), true)
498 }