]> git.lizzy.rs Git - rust.git/blob - library/std/src/sys/vxworks/ext/fs.rs
pin docs: add some forward references
[rust.git] / library / std / src / sys / vxworks / ext / fs.rs
1 #![stable(feature = "rust1", since = "1.0.0")]
2
3 use crate::fs::{self, Permissions};
4 use crate::io;
5 use crate::path::Path;
6 use crate::sys;
7 use crate::sys::platform::fs::MetadataExt as UnixMetadataExt;
8 use crate::sys_common::{AsInner, AsInnerMut, FromInner};
9
10 /// Unix-specific extensions to [`File`].
11 ///
12 /// [`File`]: ../../../../std/fs/struct.File.html
13 #[stable(feature = "file_offset", since = "1.15.0")]
14 pub trait FileExt {
15     /// Reads a number of bytes starting from a given offset.
16     ///
17     /// Returns the number of bytes read.
18     ///
19     /// The offset is relative to the start of the file and thus independent
20     /// from the current cursor.
21     ///
22     /// The current file cursor is not affected by this function.
23     ///
24     /// Note that similar to [`File::read`], it is not an error to return with a
25     /// short read.
26     ///
27     /// [`File::read`]: ../../../../std/fs/struct.File.html#method.read
28     ///
29     /// # Examples
30     ///
31     /// ```no_run
32     /// use std::io;
33     /// use std::fs::File;
34     /// use std::os::unix::prelude::FileExt;
35     ///
36     /// fn main() -> io::Result<()> {
37     ///     let mut buf = [0u8; 8];
38     ///     let file = File::open("foo.txt")?;
39     ///
40     ///     // We now read 8 bytes from the offset 10.
41     ///     let num_bytes_read = file.read_at(&mut buf, 10)?;
42     ///     println!("read {} bytes: {:?}", num_bytes_read, buf);
43     ///     Ok(())
44     /// }
45     /// ```
46     #[stable(feature = "file_offset", since = "1.15.0")]
47     fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result<usize>;
48
49     /// Reads the exact number of byte required to fill `buf` from the given offset.
50     ///
51     /// The offset is relative to the start of the file and thus independent
52     /// from the current cursor.
53     ///
54     /// The current file cursor is not affected by this function.
55     ///
56     /// Similar to [`Read::read_exact`] but uses [`read_at`] instead of `read`.
57     ///
58     /// [`Read::read_exact`]: ../../../../std/io/trait.Read.html#method.read_exact
59     /// [`read_at`]: #tymethod.read_at
60     ///
61     /// # Errors
62     ///
63     /// If this function encounters an error of the kind
64     /// [`ErrorKind::Interrupted`] then the error is ignored and the operation
65     /// will continue.
66     ///
67     /// If this function encounters an "end of file" before completely filling
68     /// the buffer, it returns an error of the kind [`ErrorKind::UnexpectedEof`].
69     /// The contents of `buf` are unspecified in this case.
70     ///
71     /// If any other read error is encountered then this function immediately
72     /// returns. The contents of `buf` are unspecified in this case.
73     ///
74     /// If this function returns an error, it is unspecified how many bytes it
75     /// has read, but it will never read more than would be necessary to
76     /// completely fill the buffer.
77     ///
78     /// [`ErrorKind::Interrupted`]: ../../../../std/io/enum.ErrorKind.html#variant.Interrupted
79     /// [`ErrorKind::UnexpectedEof`]: ../../../../std/io/enum.ErrorKind.html#variant.UnexpectedEof
80     ///
81     /// # Examples
82     ///
83     /// ```no_run
84     /// #![feature(rw_exact_all_at)]
85     /// use std::io;
86     /// use std::fs::File;
87     /// use std::os::unix::prelude::FileExt;
88     ///
89     /// fn main() -> io::Result<()> {
90     ///     let mut buf = [0u8; 8];
91     ///     let file = File::open("foo.txt")?;
92     ///
93     ///     // We now read exactly 8 bytes from the offset 10.
94     ///     file.read_exact_at(&mut buf, 10)?;
95     ///     println!("read {} bytes: {:?}", buf.len(), buf);
96     ///     Ok(())
97     /// }
98     /// ```
99     #[stable(feature = "rw_exact_all_at", since = "1.33.0")]
100     fn read_exact_at(&self, mut buf: &mut [u8], mut offset: u64) -> io::Result<()> {
101         while !buf.is_empty() {
102             match self.read_at(buf, offset) {
103                 Ok(0) => break,
104                 Ok(n) => {
105                     let tmp = buf;
106                     buf = &mut tmp[n..];
107                     offset += n as u64;
108                 }
109                 Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {}
110                 Err(e) => return Err(e),
111             }
112         }
113         if !buf.is_empty() {
114             Err(io::Error::new(io::ErrorKind::UnexpectedEof, "failed to fill whole buffer"))
115         } else {
116             Ok(())
117         }
118     }
119
120     /// Writes a number of bytes starting from a given offset.
121     ///
122     /// Returns the number of bytes written.
123     ///
124     /// The offset is relative to the start of the file and thus independent
125     /// from the current cursor.
126     ///
127     /// The current file cursor is not affected by this function.
128     ///
129     /// When writing beyond the end of the file, the file is appropriately
130     /// extended and the intermediate bytes are initialized with the value 0.
131     ///
132     /// Note that similar to [`File::write`], it is not an error to return a
133     /// short write.
134     ///
135     /// [`File::write`]: ../../../../std/fs/struct.File.html#method.write
136     ///
137     /// # Examples
138     ///
139     /// ```no_run
140     /// use std::fs::File;
141     /// use std::io;
142     /// use std::os::unix::prelude::FileExt;
143     ///
144     /// fn main() -> io::Result<()> {
145     ///     let file = File::open("foo.txt")?;
146     ///
147     ///     // We now write at the offset 10.
148     ///     file.write_at(b"sushi", 10)?;
149     ///     Ok(())
150     /// }
151     /// ```
152     #[stable(feature = "file_offset", since = "1.15.0")]
153     fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize>;
154
155     /// Attempts to write an entire buffer starting from a given offset.
156     ///
157     /// The offset is relative to the start of the file and thus independent
158     /// from the current cursor.
159     ///
160     /// The current file cursor is not affected by this function.
161     ///
162     /// This method will continuously call [`write_at`] until there is no more data
163     /// to be written or an error of non-[`ErrorKind::Interrupted`] kind is
164     /// returned. This method will not return until the entire buffer has been
165     /// successfully written or such an error occurs. The first error that is
166     /// not of [`ErrorKind::Interrupted`] kind generated from this method will be
167     /// returned.
168     ///
169     /// # Errors
170     ///
171     /// This function will return the first error of
172     /// non-[`ErrorKind::Interrupted`] kind that [`write_at`] returns.
173     ///
174     /// [`ErrorKind::Interrupted`]: ../../../../std/io/enum.ErrorKind.html#variant.Interrupted
175     /// [`write_at`]: #tymethod.write_at
176     ///
177     /// # Examples
178     ///
179     /// ```no_run
180     /// #![feature(rw_exact_all_at)]
181     /// use std::fs::File;
182     /// use std::io;
183     /// use std::os::unix::prelude::FileExt;
184     ///
185     /// fn main() -> io::Result<()> {
186     ///     let file = File::open("foo.txt")?;
187     ///
188     ///     // We now write at the offset 10.
189     ///     file.write_all_at(b"sushi", 10)?;
190     ///     Ok(())
191     /// }
192     /// ```
193     #[stable(feature = "rw_exact_all_at", since = "1.33.0")]
194     fn write_all_at(&self, mut buf: &[u8], mut offset: u64) -> io::Result<()> {
195         while !buf.is_empty() {
196             match self.write_at(buf, offset) {
197                 Ok(0) => {
198                     return Err(io::Error::new(
199                         io::ErrorKind::WriteZero,
200                         "failed to write whole buffer",
201                     ));
202                 }
203                 Ok(n) => {
204                     buf = &buf[n..];
205                     offset += n as u64
206                 }
207                 Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {}
208                 Err(e) => return Err(e),
209             }
210         }
211         Ok(())
212     }
213 }
214
215 #[stable(feature = "file_offset", since = "1.15.0")]
216 impl FileExt for fs::File {
217     fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result<usize> {
218         self.as_inner().read_at(buf, offset)
219     }
220     fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize> {
221         self.as_inner().write_at(buf, offset)
222     }
223 }
224
225 /// Unix-specific extensions to [`fs::Permissions`].
226 ///
227 /// [`fs::Permissions`]: ../../../../std/fs/struct.Permissions.html
228 #[stable(feature = "fs_ext", since = "1.1.0")]
229 pub trait PermissionsExt {
230     /// Returns the underlying raw `st_mode` bits that contain the standard
231     /// Unix permissions for this file.
232     ///
233     /// # Examples
234     ///
235     /// ```no_run
236     /// use std::fs::File;
237     /// use std::os::unix::fs::PermissionsExt;
238     ///
239     /// fn main() -> std::io::Result<()> {
240     ///     let f = File::create("foo.txt")?;
241     ///     let metadata = f.metadata()?;
242     ///     let permissions = metadata.permissions();
243     ///
244     ///     println!("permissions: {}", permissions.mode());
245     ///     Ok(()) }
246     /// ```
247     #[stable(feature = "fs_ext", since = "1.1.0")]
248     fn mode(&self) -> u32;
249
250     /// Sets the underlying raw bits for this set of permissions.
251     ///
252     /// # Examples
253     ///
254     /// ```no_run
255     /// use std::fs::File;
256     /// use std::os::unix::fs::PermissionsExt;
257     ///
258     /// fn main() -> std::io::Result<()> {
259     ///     let f = File::create("foo.txt")?;
260     ///     let metadata = f.metadata()?;
261     ///     let mut permissions = metadata.permissions();
262     ///
263     ///     permissions.set_mode(0o644); // Read/write for owner and read for others.
264     ///     assert_eq!(permissions.mode(), 0o644);
265     ///     Ok(()) }
266     /// ```
267     #[stable(feature = "fs_ext", since = "1.1.0")]
268     fn set_mode(&mut self, mode: u32);
269
270     /// Creates a new instance of `Permissions` from the given set of Unix
271     /// permission bits.
272     ///
273     /// # Examples
274     ///
275     /// ```
276     /// use std::fs::Permissions;
277     /// use std::os::unix::fs::PermissionsExt;
278     ///
279     /// // Read/write for owner and read for others.
280     /// let permissions = Permissions::from_mode(0o644);
281     /// assert_eq!(permissions.mode(), 0o644);
282     /// ```
283     #[stable(feature = "fs_ext", since = "1.1.0")]
284     fn from_mode(mode: u32) -> Self;
285 }
286
287 #[stable(feature = "fs_ext", since = "1.1.0")]
288 impl PermissionsExt for Permissions {
289     fn mode(&self) -> u32 {
290         self.as_inner().mode()
291     }
292
293     fn set_mode(&mut self, mode: u32) {
294         *self = Permissions::from_inner(FromInner::from_inner(mode));
295     }
296
297     fn from_mode(mode: u32) -> Permissions {
298         Permissions::from_inner(FromInner::from_inner(mode))
299     }
300 }
301
302 /// Unix-specific extensions to [`fs::OpenOptions`].
303 ///
304 /// [`fs::OpenOptions`]: ../../../../std/fs/struct.OpenOptions.html
305 #[stable(feature = "fs_ext", since = "1.1.0")]
306 pub trait OpenOptionsExt {
307     /// Sets the mode bits that a new file will be created with.
308     ///
309     /// If a new file is created as part of an `OpenOptions::open` call then this
310     /// specified `mode` will be used as the permission bits for the new file.
311     /// If no `mode` is set, the default of `0o666` will be used.
312     /// The operating system masks out bits with the system's `umask`, to produce
313     /// the final permissions.
314     ///
315     /// # Examples
316     ///
317     /// ```no_run
318     /// use std::fs::OpenOptions;
319     /// use std::os::unix::fs::OpenOptionsExt;
320     ///
321     /// # fn main() {
322     /// let mut options = OpenOptions::new();
323     /// options.mode(0o644); // Give read/write for owner and read for others.
324     /// let file = options.open("foo.txt");
325     /// # }
326     /// ```
327     #[stable(feature = "fs_ext", since = "1.1.0")]
328     fn mode(&mut self, mode: u32) -> &mut Self;
329
330     /// Pass custom flags to the `flags` argument of `open`.
331     ///
332     /// The bits that define the access mode are masked out with `O_ACCMODE`, to
333     /// ensure they do not interfere with the access mode set by Rusts options.
334     ///
335     /// Custom flags can only set flags, not remove flags set by Rusts options.
336     /// This options overwrites any previously set custom flags.
337     ///
338     /// # Examples
339     ///
340     /// ```no_run
341     /// # #![feature(libc)]
342     /// extern crate libc;
343     /// use std::fs::OpenOptions;
344     /// use std::os::unix::fs::OpenOptionsExt;
345     ///
346     /// # fn main() {
347     /// let mut options = OpenOptions::new();
348     /// options.write(true);
349     /// if cfg!(unix) {
350     ///     options.custom_flags(libc::O_NOFOLLOW);
351     /// }
352     /// let file = options.open("foo.txt");
353     /// # }
354     /// ```
355     #[stable(feature = "open_options_ext", since = "1.10.0")]
356     fn custom_flags(&mut self, flags: i32) -> &mut Self;
357 }
358
359 /*#[stable(feature = "fs_ext", since = "1.1.0")]
360 impl OpenOptionsExt for OpenOptions {
361     fn mode(&mut self, mode: u32) -> &mut OpenOptions {
362         self.as_inner_mut().mode(mode); self
363     }
364
365     fn custom_flags(&mut self, flags: i32) -> &mut OpenOptions {
366         self.as_inner_mut().custom_flags(flags); self
367     }
368 }
369 */
370
371 /// Unix-specific extensions to [`fs::Metadata`].
372 ///
373 /// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html
374 #[stable(feature = "metadata_ext", since = "1.1.0")]
375 pub trait MetadataExt {
376     /// Returns the ID of the device containing the file.
377     ///
378     /// # Examples
379     ///
380     /// ```no_run
381     /// use std::io;
382     /// use std::fs;
383     /// use std::os::unix::fs::MetadataExt;
384     ///
385     /// fn main() -> io::Result<()> {
386     ///     let meta = fs::metadata("some_file")?;
387     ///     let dev_id = meta.dev();
388     ///     Ok(())
389     /// }
390     /// ```
391     #[stable(feature = "metadata_ext", since = "1.1.0")]
392     fn dev(&self) -> u64;
393     /// Returns the inode number.
394     ///
395     /// # Examples
396     ///
397     /// ```no_run
398     /// use std::fs;
399     /// use std::os::unix::fs::MetadataExt;
400     /// use std::io;
401     ///
402     /// fn main() -> io::Result<()> {
403     ///     let meta = fs::metadata("some_file")?;
404     ///     let inode = meta.ino();
405     ///     Ok(())
406     /// }
407     /// ```
408     #[stable(feature = "metadata_ext", since = "1.1.0")]
409     fn ino(&self) -> u64;
410     /// Returns the rights applied to this file.
411     ///
412     /// # Examples
413     ///
414     /// ```no_run
415     /// use std::fs;
416     /// use std::os::unix::fs::MetadataExt;
417     /// use std::io;
418     ///
419     /// fn main() -> io::Result<()> {
420     ///     let meta = fs::metadata("some_file")?;
421     ///     let mode = meta.mode();
422     ///     let user_has_write_access      = mode & 0o200;
423     ///     let user_has_read_write_access = mode & 0o600;
424     ///     let group_has_read_access      = mode & 0o040;
425     ///     let others_have_exec_access    = mode & 0o001;
426     ///     Ok(())
427     /// }
428     /// ```
429     #[stable(feature = "metadata_ext", since = "1.1.0")]
430     fn mode(&self) -> u32;
431     /// Returns the number of hard links pointing to this file.
432     ///
433     /// # Examples
434     ///
435     /// ```no_run
436     /// use std::fs;
437     /// use std::os::unix::fs::MetadataExt;
438     ///  use std::io;
439     ///
440     /// fn main() -> io::Result<()> {
441     ///     let meta = fs::metadata("some_file")?;
442     ///     let nb_hard_links = meta.nlink();
443     ///     Ok(())
444     /// }
445     /// ```
446     #[stable(feature = "metadata_ext", since = "1.1.0")]
447     fn nlink(&self) -> u64;
448     /// Returns the user ID of the owner of this file.
449     ///
450     /// # Examples
451     ///
452     /// ```no_run
453     /// use std::fs;
454     /// use std::os::unix::fs::MetadataExt;
455     /// use std::io;
456     ///
457     /// fn main() -> io::Result<()> {
458     ///     let meta = fs::metadata("some_file")?;
459     ///     let user_id = meta.uid();
460     ///     Ok(())
461     /// }
462     /// ```
463     #[stable(feature = "metadata_ext", since = "1.1.0")]
464     fn uid(&self) -> u32;
465     /// Returns the group ID of the owner of this file.
466     ///
467     /// # Examples
468     ///
469     /// ```no_run
470     /// use std::fs;
471     /// use std::os::unix::fs::MetadataExt;
472     /// use std::io;
473     ///
474     /// fn main() -> io::Result<()> {
475     ///     let meta = fs::metadata("some_file")?;
476     ///     let group_id = meta.gid();
477     ///     Ok(())
478     /// }
479     /// ```
480     #[stable(feature = "metadata_ext", since = "1.1.0")]
481     fn gid(&self) -> u32;
482     /// Returns the device ID of this file (if it is a special one).
483     ///
484     /// # Examples
485     ///
486     /// ```no_run
487     /// use std::fs;
488     /// use std::os::unix::fs::MetadataExt;
489     /// use std::io;
490     ///
491     /// fn main() -> io::Result<()> {
492     ///     let meta = fs::metadata("some_file")?;
493     ///     let device_id = meta.rdev();
494     ///     Ok(())
495     /// }
496     /// ```
497     #[stable(feature = "metadata_ext", since = "1.1.0")]
498     fn rdev(&self) -> u64;
499     /// Returns the total size of this file in bytes.
500     ///
501     /// # Examples
502     ///
503     /// ```no_run
504     /// use std::fs;
505     /// use std::os::unix::fs::MetadataExt;
506     /// use std::io;
507     ///
508     /// fn main() -> io::Result<()> {
509     ///     let meta = fs::metadata("some_file")?;
510     ///     let file_size = meta.size();
511     ///     Ok(())
512     /// }
513     /// ```
514     #[stable(feature = "metadata_ext", since = "1.1.0")]
515     fn size(&self) -> u64;
516     /// Returns the time of the last access to the file.
517     ///
518     /// # Examples
519     ///
520     /// ```no_run
521     /// use std::fs;
522     /// use std::os::unix::fs::MetadataExt;
523     /// use std::io;
524     ///
525     /// fn main() -> io::Result<()> {
526     ///     let meta = fs::metadata("some_file")?;
527     ///     let last_access_time = meta.atime();
528     ///     Ok(())
529     /// }
530     /// ```
531     #[stable(feature = "metadata_ext", since = "1.1.0")]
532     fn atime(&self) -> i64;
533     /// Returns the time of the last access to the file in nanoseconds.
534     ///
535     /// # Examples
536     ///
537     /// ```no_run
538     /// use std::fs;
539     /// use std::os::unix::fs::MetadataExt;
540     /// use std::io;
541     ///
542     /// fn main() -> io::Result<()> {
543     ///     let meta = fs::metadata("some_file")?;
544     ///     let nano_last_access_time = meta.atime_nsec();
545     ///     Ok(())
546     /// }
547     /// ```
548     #[stable(feature = "metadata_ext", since = "1.1.0")]
549     fn mtime(&self) -> i64;
550     /// Returns the time of the last modification of the file in nanoseconds.
551     ///
552     /// # Examples
553     ///
554     /// ```no_run
555     /// use std::fs;
556     /// use std::os::unix::fs::MetadataExt;
557     /// use std::io;
558     ///
559     /// fn main() -> io::Result<()> {
560     ///     let meta = fs::metadata("some_file")?;
561     ///     let nano_last_modification_time = meta.mtime_nsec();
562     ///     Ok(())
563     /// }
564     /// ```
565     #[stable(feature = "metadata_ext", since = "1.1.0")]
566     fn ctime(&self) -> i64;
567     /// Returns the time of the last status change of the file in nanoseconds.
568     ///
569     /// # Examples
570     ///
571     /// ```no_run
572     /// use std::fs;
573     /// use std::os::unix::fs::MetadataExt;
574     /// use std::io;
575     ///
576     /// fn main() -> io::Result<()> {
577     ///     let meta = fs::metadata("some_file")?;
578     ///     let nano_last_status_change_time = meta.ctime_nsec();
579     ///     Ok(())
580     /// }
581     /// ```
582     #[stable(feature = "metadata_ext", since = "1.1.0")]
583     fn blksize(&self) -> u64;
584     /// Returns the number of blocks allocated to the file, in 512-byte units.
585     ///
586     /// Please note that this may be smaller than `st_size / 512` when the file has holes.
587     ///
588     /// # Examples
589     ///
590     /// ```no_run
591     /// use std::fs;
592     /// use std::os::unix::fs::MetadataExt;
593     /// use std::io;
594     ///
595     /// fn main() -> io::Result<()> {
596     ///     let meta = fs::metadata("some_file")?;
597     ///     let blocks = meta.blocks();
598     ///     Ok(())
599     /// }
600     /// ```
601     #[stable(feature = "metadata_ext", since = "1.1.0")]
602     fn blocks(&self) -> u64;
603     #[stable(feature = "metadata_ext", since = "1.1.0")]
604     fn attrib(&self) -> u8;
605 }
606
607 #[stable(feature = "metadata_ext", since = "1.1.0")]
608 impl MetadataExt for fs::Metadata {
609     fn dev(&self) -> u64 {
610         self.st_dev()
611     }
612     fn ino(&self) -> u64 {
613         self.st_ino()
614     }
615     fn mode(&self) -> u32 {
616         self.st_mode()
617     }
618     fn nlink(&self) -> u64 {
619         self.st_nlink()
620     }
621     fn uid(&self) -> u32 {
622         self.st_uid()
623     }
624     fn gid(&self) -> u32 {
625         self.st_gid()
626     }
627     fn rdev(&self) -> u64 {
628         self.st_rdev()
629     }
630     fn size(&self) -> u64 {
631         self.st_size()
632     }
633     fn atime(&self) -> i64 {
634         self.st_atime()
635     }
636     fn mtime(&self) -> i64 {
637         self.st_mtime()
638     }
639     fn ctime(&self) -> i64 {
640         self.st_ctime()
641     }
642     fn blksize(&self) -> u64 {
643         self.st_blksize()
644     }
645     fn blocks(&self) -> u64 {
646         self.st_blocks()
647     }
648     fn attrib(&self) -> u8 {
649         self.st_attrib()
650     }
651 }
652
653 /// Unix-specific extensions for [`FileType`].
654 ///
655 /// Adds support for special Unix file types such as block/character devices,
656 /// pipes, and sockets.
657 ///
658 /// [`FileType`]: ../../../../std/fs/struct.FileType.html
659 #[stable(feature = "file_type_ext", since = "1.5.0")]
660 pub trait FileTypeExt {
661     /// Returns whether this file type is a block device.
662     ///
663     /// # Examples
664     ///
665     /// ```no_run
666     /// use std::fs;
667     /// use std::os::unix::fs::FileTypeExt;
668     /// use std::io;
669     ///
670     /// fn main() -> io::Result<()> {
671     ///     let meta = fs::metadata("block_device_file")?;
672     ///     let file_type = meta.file_type();
673     ///     assert!(file_type.is_block_device());
674     ///     Ok(())
675     /// }
676     /// ```
677     #[stable(feature = "file_type_ext", since = "1.5.0")]
678     fn is_block_device(&self) -> bool;
679     /// Returns whether this file type is a char device.
680     ///
681     /// # Examples
682     ///
683     /// ```no_run
684     /// use std::fs;
685     /// use std::os::unix::fs::FileTypeExt;
686     /// use std::io;
687     ///
688     /// fn main() -> io::Result<()> {
689     ///     let meta = fs::metadata("char_device_file")?;
690     ///     let file_type = meta.file_type();
691     ///     assert!(file_type.is_char_device());
692     ///     Ok(())
693     /// }
694     /// ```
695     #[stable(feature = "file_type_ext", since = "1.5.0")]
696     fn is_char_device(&self) -> bool;
697     /// Returns whether this file type is a fifo.
698     ///
699     /// # Examples
700     ///
701     /// ```no_run
702     /// use std::fs;
703     /// use std::os::unix::fs::FileTypeExt;
704     /// use std::io;
705     ///
706     /// fn main() -> io::Result<()> {
707     ///     let meta = fs::metadata("fifo_file")?;
708     ///     let file_type = meta.file_type();
709     ///     assert!(file_type.is_fifo());
710     ///     Ok(())
711     /// }
712     /// ```
713     #[stable(feature = "file_type_ext", since = "1.5.0")]
714     fn is_fifo(&self) -> bool;
715     /// Returns whether this file type is a socket.
716     ///
717     /// # Examples
718     ///
719     /// ```no_run
720     /// use std::fs;
721     /// use std::os::unix::fs::FileTypeExt;
722     /// use std::io;
723     ///
724     /// fn main() -> io::Result<()> {
725     ///     let meta = fs::metadata("unix.socket")?;
726     ///     let file_type = meta.file_type();
727     ///     assert!(file_type.is_socket());
728     ///     Ok(())
729     /// }
730     /// ```
731     #[stable(feature = "file_type_ext", since = "1.5.0")]
732     fn is_socket(&self) -> bool;
733 }
734
735 #[stable(feature = "file_type_ext", since = "1.5.0")]
736 impl FileTypeExt for fs::FileType {
737     fn is_block_device(&self) -> bool {
738         self.as_inner().is(libc::S_IFBLK)
739     }
740     fn is_char_device(&self) -> bool {
741         self.as_inner().is(libc::S_IFCHR)
742     }
743     fn is_fifo(&self) -> bool {
744         self.as_inner().is(libc::S_IFIFO)
745     }
746     fn is_socket(&self) -> bool {
747         self.as_inner().is(libc::S_IFSOCK)
748     }
749 }
750
751 /// Unix-specific extension methods for [`fs::DirEntry`].
752 ///
753 /// [`fs::DirEntry`]: ../../../../std/fs/struct.DirEntry.html
754 #[stable(feature = "dir_entry_ext", since = "1.1.0")]
755 pub trait DirEntryExt {
756     /// Returns the underlying `d_ino` field in the contained `dirent`
757     /// structure.
758     ///
759     /// # Examples
760     ///
761     /// ```
762     /// use std::fs;
763     /// use std::os::unix::fs::DirEntryExt;
764     ///
765     /// if let Ok(entries) = fs::read_dir(".") {
766     ///     for entry in entries {
767     ///         if let Ok(entry) = entry {
768     ///             // Here, `entry` is a `DirEntry`.
769     ///             println!("{:?}: {}", entry.file_name(), entry.ino());
770     ///         }
771     ///     }
772     /// }
773     /// ```
774     #[stable(feature = "dir_entry_ext", since = "1.1.0")]
775     fn ino(&self) -> u64;
776 }
777
778 #[stable(feature = "dir_entry_ext", since = "1.1.0")]
779 impl DirEntryExt for fs::DirEntry {
780     fn ino(&self) -> u64 {
781         self.as_inner().ino()
782     }
783 }
784
785 /// Creates a new symbolic link on the filesystem.
786 ///
787 /// The `dst` path will be a symbolic link pointing to the `src` path.
788 ///
789 /// # Note
790 ///
791 /// On Windows, you must specify whether a symbolic link points to a file
792 /// or directory.  Use `os::windows::fs::symlink_file` to create a
793 /// symbolic link to a file, or `os::windows::fs::symlink_dir` to create a
794 /// symbolic link to a directory.  Additionally, the process must have
795 /// `SeCreateSymbolicLinkPrivilege` in order to be able to create a
796 /// symbolic link.
797 ///
798 /// # Examples
799 ///
800 /// ```no_run
801 /// use std::os::unix::fs;
802 ///
803 /// fn main() -> std::io::Result<()> {
804 ///     fs::symlink("a.txt", "b.txt")?;
805 ///     Ok(())
806 /// }
807 /// ```
808 #[stable(feature = "symlink", since = "1.1.0")]
809 pub fn symlink<P: AsRef<Path>, Q: AsRef<Path>>(src: P, dst: Q) -> io::Result<()> {
810     sys::fs::symlink(src.as_ref(), dst.as_ref())
811 }
812
813 /// Unix-specific extensions to [`fs::DirBuilder`].
814 ///
815 /// [`fs::DirBuilder`]: ../../../../std/fs/struct.DirBuilder.html
816 #[stable(feature = "dir_builder", since = "1.6.0")]
817 pub trait DirBuilderExt {
818     /// Sets the mode to create new directories with. This option defaults to
819     /// 0o777.
820     ///
821     /// # Examples
822     ///
823     /// ```no_run
824     /// use std::fs::DirBuilder;
825     /// use std::os::unix::fs::DirBuilderExt;
826     ///
827     /// let mut builder = DirBuilder::new();
828     /// builder.mode(0o755);
829     /// ```
830     #[stable(feature = "dir_builder", since = "1.6.0")]
831     fn mode(&mut self, mode: u32) -> &mut Self;
832 }
833
834 #[stable(feature = "dir_builder", since = "1.6.0")]
835 impl DirBuilderExt for fs::DirBuilder {
836     fn mode(&mut self, mode: u32) -> &mut fs::DirBuilder {
837         self.as_inner_mut().set_mode(mode);
838         self
839     }
840 }