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 `File`
24 #[stable(feature = "file_offset", since = "1.15.0")]
26 /// Reads a number of bytes starting from a given offset.
28 /// Returns the number of bytes read.
30 /// The offset is relative to the start of the file and thus independent
31 /// from the current cursor.
33 /// The current file cursor is not affected by this function.
35 /// Note that similar to `File::read`, it is not an error to return with a
37 #[stable(feature = "file_offset", since = "1.15.0")]
38 fn read_at(&self, buf
: &mut [u8], offset
: u64) -> io
::Result
<usize>;
40 /// Writes a number of bytes starting from a given offset.
42 /// Returns the number of bytes written.
44 /// The offset is relative to the start of the file and thus independent
45 /// from the current cursor.
47 /// The current file cursor is not affected by this function.
49 /// When writing beyond the end of the file, the file is appropriately
50 /// extended and the intermediate bytes are initialized with the value 0.
52 /// Note that similar to `File::write`, it is not an error to return a
54 #[stable(feature = "file_offset", since = "1.15.0")]
55 fn write_at(&self, buf
: &[u8], offset
: u64) -> io
::Result
<usize>;
58 #[stable(feature = "file_offset", since = "1.15.0")]
59 impl FileExt
for fs
::File
{
60 fn read_at(&self, buf
: &mut [u8], offset
: u64) -> io
::Result
<usize> {
61 self.as_inner().read_at(buf
, offset
)
63 fn write_at(&self, buf
: &[u8], offset
: u64) -> io
::Result
<usize> {
64 self.as_inner().write_at(buf
, offset
)
68 /// Unix-specific extensions to `Permissions`
69 #[stable(feature = "fs_ext", since = "1.1.0")]
70 pub trait PermissionsExt
{
71 /// Returns the underlying raw `st_mode` bits that contain the standard
72 /// Unix permissions for this file.
77 /// use std::fs::File;
78 /// use std::os::unix::fs::PermissionsExt;
80 /// # fn run() -> std::io::Result<()> {
81 /// let f = File::create("foo.txt")?;
82 /// let metadata = f.metadata()?;
83 /// let permissions = metadata.permissions();
85 /// println!("permissions: {}", permissions.mode());
88 #[stable(feature = "fs_ext", since = "1.1.0")]
89 fn mode(&self) -> u32;
91 /// Sets the underlying raw bits for this set of permissions.
96 /// use std::fs::File;
97 /// use std::os::unix::fs::PermissionsExt;
99 /// # fn run() -> std::io::Result<()> {
100 /// let f = File::create("foo.txt")?;
101 /// let metadata = f.metadata()?;
102 /// let mut permissions = metadata.permissions();
104 /// permissions.set_mode(0o644); // Read/write for owner and read for others.
105 /// assert_eq!(permissions.mode(), 0o644);
108 #[stable(feature = "fs_ext", since = "1.1.0")]
109 fn set_mode(&mut self, mode
: u32);
111 /// Creates a new instance of `Permissions` from the given set of Unix
117 /// use std::fs::Permissions;
118 /// use std::os::unix::fs::PermissionsExt;
120 /// // Read/write for owner and read for others.
121 /// let permissions = Permissions::from_mode(0o644);
122 /// assert_eq!(permissions.mode(), 0o644);
124 #[stable(feature = "fs_ext", since = "1.1.0")]
125 fn from_mode(mode
: u32) -> Self;
128 #[stable(feature = "fs_ext", since = "1.1.0")]
129 impl PermissionsExt
for Permissions
{
130 fn mode(&self) -> u32 {
131 self.as_inner().mode()
134 fn set_mode(&mut self, mode
: u32) {
135 *self = Permissions
::from_inner(FromInner
::from_inner(mode
));
138 fn from_mode(mode
: u32) -> Permissions
{
139 Permissions
::from_inner(FromInner
::from_inner(mode
))
143 /// Unix-specific extensions to `OpenOptions`
144 #[stable(feature = "fs_ext", since = "1.1.0")]
145 pub trait OpenOptionsExt
{
146 /// Sets the mode bits that a new file will be created with.
148 /// If a new file is created as part of a `File::open_opts` call then this
149 /// specified `mode` will be used as the permission bits for the new file.
150 /// If no `mode` is set, the default of `0o666` will be used.
151 /// The operating system masks out bits with the systems `umask`, to produce
152 /// the final permissions.
157 /// use std::fs::OpenOptions;
158 /// use std::os::unix::fs::OpenOptionsExt;
161 /// let mut options = OpenOptions::new();
162 /// options.mode(0o644); // Give read/write for owner and read for others.
163 /// let file = options.open("foo.txt");
166 #[stable(feature = "fs_ext", since = "1.1.0")]
167 fn mode(&mut self, mode
: u32) -> &mut Self;
169 /// Pass custom flags to the `flags` argument of `open`.
171 /// The bits that define the access mode are masked out with `O_ACCMODE`, to
172 /// ensure they do not interfere with the access mode set by Rusts options.
174 /// Custom flags can only set flags, not remove flags set by Rusts options.
175 /// This options overwrites any previously set custom flags.
180 /// # #![feature(libc)]
181 /// extern crate libc;
182 /// use std::fs::OpenOptions;
183 /// use std::os::unix::fs::OpenOptionsExt;
186 /// let mut options = OpenOptions::new();
187 /// options.write(true);
189 /// options.custom_flags(libc::O_NOFOLLOW);
191 /// let file = options.open("foo.txt");
194 #[stable(feature = "open_options_ext", since = "1.10.0")]
195 fn custom_flags(&mut self, flags
: i32) -> &mut Self;
198 #[stable(feature = "fs_ext", since = "1.1.0")]
199 impl OpenOptionsExt
for OpenOptions
{
200 fn mode(&mut self, mode
: u32) -> &mut OpenOptions
{
201 self.as_inner_mut().mode(mode
); self
204 fn custom_flags(&mut self, flags
: i32) -> &mut OpenOptions
{
205 self.as_inner_mut().custom_flags(flags
); self
209 // Hm, why are there casts here to the returned type, shouldn't the types always
210 // be the same? Right you are! Turns out, however, on android at least the types
211 // in the raw `stat` structure are not the same as the types being returned. Who
214 // As a result to make sure this compiles for all platforms we do the manual
215 // casts and rely on manual lowering to `stat` if the raw type is desired.
216 #[stable(feature = "metadata_ext", since = "1.1.0")]
217 pub trait MetadataExt
{
218 #[stable(feature = "metadata_ext", since = "1.1.0")]
219 fn dev(&self) -> u64;
220 #[stable(feature = "metadata_ext", since = "1.1.0")]
221 fn ino(&self) -> u64;
222 #[stable(feature = "metadata_ext", since = "1.1.0")]
223 fn mode(&self) -> u32;
224 #[stable(feature = "metadata_ext", since = "1.1.0")]
225 fn nlink(&self) -> u64;
226 #[stable(feature = "metadata_ext", since = "1.1.0")]
227 fn uid(&self) -> u32;
228 #[stable(feature = "metadata_ext", since = "1.1.0")]
229 fn gid(&self) -> u32;
230 #[stable(feature = "metadata_ext", since = "1.1.0")]
231 fn rdev(&self) -> u64;
232 #[stable(feature = "metadata_ext", since = "1.1.0")]
233 fn size(&self) -> u64;
234 #[stable(feature = "metadata_ext", since = "1.1.0")]
235 fn atime(&self) -> i64;
236 #[stable(feature = "metadata_ext", since = "1.1.0")]
237 fn atime_nsec(&self) -> i64;
238 #[stable(feature = "metadata_ext", since = "1.1.0")]
239 fn mtime(&self) -> i64;
240 #[stable(feature = "metadata_ext", since = "1.1.0")]
241 fn mtime_nsec(&self) -> i64;
242 #[stable(feature = "metadata_ext", since = "1.1.0")]
243 fn ctime(&self) -> i64;
244 #[stable(feature = "metadata_ext", since = "1.1.0")]
245 fn ctime_nsec(&self) -> i64;
246 #[stable(feature = "metadata_ext", since = "1.1.0")]
247 fn blksize(&self) -> u64;
248 #[stable(feature = "metadata_ext", since = "1.1.0")]
249 fn blocks(&self) -> u64;
252 #[stable(feature = "metadata_ext", since = "1.1.0")]
253 impl MetadataExt
for fs
::Metadata
{
254 fn dev(&self) -> u64 { self.st_dev() }
255 fn ino(&self) -> u64 { self.st_ino() }
256 fn mode(&self) -> u32 { self.st_mode() }
257 fn nlink(&self) -> u64 { self.st_nlink() }
258 fn uid(&self) -> u32 { self.st_uid() }
259 fn gid(&self) -> u32 { self.st_gid() }
260 fn rdev(&self) -> u64 { self.st_rdev() }
261 fn size(&self) -> u64 { self.st_size() }
262 fn atime(&self) -> i64 { self.st_atime() }
263 fn atime_nsec(&self) -> i64 { self.st_atime_nsec() }
264 fn mtime(&self) -> i64 { self.st_mtime() }
265 fn mtime_nsec(&self) -> i64 { self.st_mtime_nsec() }
266 fn ctime(&self) -> i64 { self.st_ctime() }
267 fn ctime_nsec(&self) -> i64 { self.st_ctime_nsec() }
268 fn blksize(&self) -> u64 { self.st_blksize() }
269 fn blocks(&self) -> u64 { self.st_blocks() }
272 /// Add special unix types (block/char device, fifo and socket)
273 #[stable(feature = "file_type_ext", since = "1.5.0")]
274 pub trait FileTypeExt
{
275 /// Returns whether this file type is a block device.
276 #[stable(feature = "file_type_ext", since = "1.5.0")]
277 fn is_block_device(&self) -> bool
;
278 /// Returns whether this file type is a char device.
279 #[stable(feature = "file_type_ext", since = "1.5.0")]
280 fn is_char_device(&self) -> bool
;
281 /// Returns whether this file type is a fifo.
282 #[stable(feature = "file_type_ext", since = "1.5.0")]
283 fn is_fifo(&self) -> bool
;
284 /// Returns whether this file type is a socket.
285 #[stable(feature = "file_type_ext", since = "1.5.0")]
286 fn is_socket(&self) -> bool
;
289 #[stable(feature = "file_type_ext", since = "1.5.0")]
290 impl FileTypeExt
for fs
::FileType
{
291 fn is_block_device(&self) -> bool { self.as_inner().is(libc::S_IFBLK) }
292 fn is_char_device(&self) -> bool { self.as_inner().is(libc::S_IFCHR) }
293 fn is_fifo(&self) -> bool { self.as_inner().is(libc::S_IFIFO) }
294 fn is_socket(&self) -> bool { self.as_inner().is(libc::S_IFSOCK) }
297 /// Unix-specific extension methods for `fs::DirEntry`
298 #[stable(feature = "dir_entry_ext", since = "1.1.0")]
299 pub trait DirEntryExt
{
300 /// Returns the underlying `d_ino` field in the contained `dirent`
307 /// use std::os::unix::fs::DirEntryExt;
309 /// if let Ok(entries) = fs::read_dir(".") {
310 /// for entry in entries {
311 /// if let Ok(entry) = entry {
312 /// // Here, `entry` is a `DirEntry`.
313 /// println!("{:?}: {}", entry.file_name(), entry.ino());
318 #[stable(feature = "dir_entry_ext", since = "1.1.0")]
319 fn ino(&self) -> u64;
322 #[stable(feature = "dir_entry_ext", since = "1.1.0")]
323 impl DirEntryExt
for fs
::DirEntry
{
324 fn ino(&self) -> u64 { self.as_inner().ino() }
327 /// Creates a new symbolic link on the filesystem.
329 /// The `dst` path will be a symbolic link pointing to the `src` path.
333 /// On Windows, you must specify whether a symbolic link points to a file
334 /// or directory. Use `os::windows::fs::symlink_file` to create a
335 /// symbolic link to a file, or `os::windows::fs::symlink_dir` to create a
336 /// symbolic link to a directory. Additionally, the process must have
337 /// `SeCreateSymbolicLinkPrivilege` in order to be able to create a
343 /// use std::os::unix::fs;
345 /// # fn foo() -> std::io::Result<()> {
346 /// fs::symlink("a.txt", "b.txt")?;
350 #[stable(feature = "symlink", since = "1.1.0")]
351 pub fn symlink
<P
: AsRef
<Path
>, Q
: AsRef
<Path
>>(src
: P
, dst
: Q
) -> io
::Result
<()>
353 sys
::fs
::symlink(src
.as_ref(), dst
.as_ref())
356 #[stable(feature = "dir_builder", since = "1.6.0")]
357 /// An extension trait for `fs::DirBuilder` for unix-specific options.
358 pub trait DirBuilderExt
{
359 /// Sets the mode to create new directories with. This option defaults to
365 /// use std::fs::DirBuilder;
366 /// use std::os::unix::fs::DirBuilderExt;
368 /// let mut builder = DirBuilder::new();
369 /// builder.mode(0o755);
371 #[stable(feature = "dir_builder", since = "1.6.0")]
372 fn mode(&mut self, mode
: u32) -> &mut Self;
375 #[stable(feature = "dir_builder", since = "1.6.0")]
376 impl DirBuilderExt
for fs
::DirBuilder
{
377 fn mode(&mut self, mode
: u32) -> &mut fs
::DirBuilder
{
378 self.as_inner_mut().set_mode(mode
);