Skip to content

Commit

Permalink
Auto merge of #25844 - alexcrichton:stabilize-fs-features, r=aturon
Browse files Browse the repository at this point in the history
This commit stabilizes the following APIs, slating them all to be cherry-picked
into the 1.1 release.

* fs::FileType (and transitively the derived trait implementations)
* fs::Metadata::file_type
* fs::FileType::is_dir
* fs::FileType::is_file
* fs::FileType::is_symlink
* fs::DirEntry::metadata
* fs::DirEntry::file_type
* fs::DirEntry::file_name
* fs::set_permissions
* fs::symlink_metadata
* os::raw::{self, *}
* os::{android, bitrig, linux, ...}::raw::{self, *}
* os::{android, bitrig, linux, ...}::fs::MetadataExt
* os::{android, bitrig, linux, ...}::fs::MetadataExt::as_raw_stat
* os::unix::fs::PermissionsExt
* os::unix::fs::PermissionsExt::mode
* os::unix::fs::PermissionsExt::set_mode
* os::unix::fs::PermissionsExt::from_mode
* os::unix::fs::OpenOptionsExt
* os::unix::fs::OpenOptionsExt::mode
* os::unix::fs::DirEntryExt
* os::unix::fs::DirEntryExt::ino
* os::windows::fs::MetadataExt
* os::windows::fs::MetadataExt::file_attributes
* os::windows::fs::MetadataExt::creation_time
* os::windows::fs::MetadataExt::last_access_time
* os::windows::fs::MetadataExt::last_write_time
* os::windows::fs::MetadataExt::file_size

The `os::unix::fs::Metadata` structure was also removed entirely, moving all of
its associated methods into the `os::unix::fs::MetadataExt` trait instead. The
methods are all marked as `#[stable]` still.

As some minor cleanup, some deprecated and unstable fs apis were also removed:

* File::path
* Metadata::accessed
* Metadata::modified

Features that were explicitly left unstable include:

* fs::WalkDir - the semantics of this were not considered in the recent fs
  expansion RFC.
* fs::DirBuilder - it's still not 100% clear if the naming is right here and if
  the set of functionality exposed is appropriate.
* fs::canonicalize - the implementation on Windows here is specifically in
  question as it always returns a verbatim path. Additionally the Unix
  implementation is susceptible to buffer overflows on long paths unfortunately.
* fs::PathExt - as this is just a convenience trait, it is not stabilized at
  this time.
* fs::set_file_times - this funciton is still waiting on a time abstraction.
  • Loading branch information
bors committed Jun 12, 2015
2 parents 85b5338 + ec68c4a commit 50ab23d
Show file tree
Hide file tree
Showing 27 changed files with 672 additions and 257 deletions.
18 changes: 18 additions & 0 deletions RELEASES.md
@@ -1,3 +1,21 @@
Version 1.1.0 (July 2015)
========================

* NNNN changes, numerous bugfixes

Libraries
---------

* The [`std::fs` module has been expanded][fs-expand] to expand the set of
functionality exposed:
* `DirEntry` now supports optimizations like `file_type` and `metadata` which
don't incur a syscall on some platforms.
* A `symlink_metadata` function has been added.
* The `fs::Metadata` structure now lowers to its OS counterpart, providing
access to all underlying information.

[fs-expand]: https://github.com/rust-lang/rust/pull/25844

Version 1.0.0 (May 2015)
========================

Expand Down
1 change: 0 additions & 1 deletion src/librustc_trans/lib.rs
Expand Up @@ -38,7 +38,6 @@
#![feature(staged_api)]
#![feature(unicode)]
#![feature(path_ext)]
#![feature(fs)]
#![feature(path_relative_from)]
#![feature(std_misc)]

Expand Down
88 changes: 31 additions & 57 deletions src/libstd/fs.rs
Expand Up @@ -148,7 +148,7 @@ pub struct OpenOptions(fs_imp::OpenOptions);
pub struct Permissions(fs_imp::FilePermissions);

/// An structure representing a type of file with accessors for each file type.
#[unstable(feature = "file_type", reason = "recently added API")]
#[stable(feature = "file_type", since = "1.1.0")]
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
pub struct FileType(fs_imp::FileType);

Expand Down Expand Up @@ -208,14 +208,6 @@ impl File {
OpenOptions::new().write(true).create(true).truncate(true).open(path)
}

/// Returns `None`.
#[unstable(feature = "file_path",
reason = "this abstraction was imposed by this library and was removed")]
#[deprecated(since = "1.0.0", reason = "abstraction was removed")]
pub fn path(&self) -> Option<&Path> {
None
}

/// Attempts to sync all OS-internal metadata to disk.
///
/// This function will attempt to ensure that all in-core data reaches the
Expand Down Expand Up @@ -501,7 +493,7 @@ impl AsInnerMut<fs_imp::OpenOptions> for OpenOptions {

impl Metadata {
/// Returns the file type for this metadata.
#[unstable(feature = "file_type", reason = "recently added API")]
#[stable(feature = "file_type", since = "1.1.0")]
pub fn file_type(&self) -> FileType {
FileType(self.0.file_type())
}
Expand Down Expand Up @@ -575,38 +567,6 @@ impl Metadata {
pub fn permissions(&self) -> Permissions {
Permissions(self.0.perm())
}

/// Returns the most recent access time for a file.
///
/// The return value is in milliseconds since the epoch.
#[unstable(feature = "fs_time",
reason = "the return type of u64 is not quite appropriate for \
this method and may change if the standard library \
gains a type to represent a moment in time")]
#[deprecated(since = "1.1.0",
reason = "use os::platform::fs::MetadataExt extension traits")]
pub fn accessed(&self) -> u64 {
self.adjust_time(self.0.accessed())
}

/// Returns the most recent modification time for a file.
///
/// The return value is in milliseconds since the epoch.
#[unstable(feature = "fs_time",
reason = "the return type of u64 is not quite appropriate for \
this method and may change if the standard library \
gains a type to represent a moment in time")]
#[deprecated(since = "1.1.0",
reason = "use os::platform::fs::MetadataExt extension traits")]
pub fn modified(&self) -> u64 {
self.adjust_time(self.0.modified())
}

fn adjust_time(&self, val: u64) -> u64 {
// FILETIME (what `val` represents) is in 100ns intervals and there are
// 10000 intervals in a millisecond.
if cfg!(windows) {val / 10000} else {val}
}
}

impl AsInner<fs_imp::FileAttr> for Metadata {
Expand Down Expand Up @@ -663,15 +623,17 @@ impl Permissions {
}
}

#[unstable(feature = "file_type", reason = "recently added API")]
impl FileType {
/// Test whether this file type represents a directory.
#[stable(feature = "file_type", since = "1.1.0")]
pub fn is_dir(&self) -> bool { self.0.is_dir() }

/// Test whether this file type represents a regular file.
#[stable(feature = "file_type", since = "1.1.0")]
pub fn is_file(&self) -> bool { self.0.is_file() }

/// Test whether this file type represents a symbolic link.
#[stable(feature = "file_type", since = "1.1.0")]
pub fn is_symlink(&self) -> bool { self.0.is_symlink() }
}

Expand Down Expand Up @@ -736,7 +698,7 @@ impl DirEntry {
/// On Windows this function is cheap to call (no extra system calls
/// needed), but on Unix platforms this function is the equivalent of
/// calling `symlink_metadata` on the path.
#[unstable(feature = "dir_entry_ext", reason = "recently added API")]
#[stable(feature = "dir_entry_ext", since = "1.1.0")]
pub fn metadata(&self) -> io::Result<Metadata> {
self.0.metadata().map(Metadata)
}
Expand All @@ -751,14 +713,14 @@ impl DirEntry {
/// On Windows and most Unix platforms this function is free (no extra
/// system calls needed), but some Unix platforms may require the equivalent
/// call to `symlink_metadata` to learn about the target file type.
#[unstable(feature = "dir_entry_ext", reason = "recently added API")]
#[stable(feature = "dir_entry_ext", since = "1.1.0")]
pub fn file_type(&self) -> io::Result<FileType> {
self.0.file_type().map(FileType)
}

/// Returns the bare file name of this directory entry without any other
/// leading path component.
#[unstable(feature = "dir_entry_ext", reason = "recently added API")]
#[stable(feature = "dir_entry_ext", since = "1.1.0")]
pub fn file_name(&self) -> OsString {
self.0.file_name()
}
Expand Down Expand Up @@ -828,7 +790,6 @@ pub fn metadata<P: AsRef<Path>>(path: P) -> io::Result<Metadata> {
/// # Examples
///
/// ```rust
/// #![feature(symlink_metadata)]
/// # fn foo() -> std::io::Result<()> {
/// use std::fs;
///
Expand All @@ -837,7 +798,7 @@ pub fn metadata<P: AsRef<Path>>(path: P) -> io::Result<Metadata> {
/// # Ok(())
/// # }
/// ```
#[unstable(feature = "symlink_metadata", reason = "recently added API")]
#[stable(feature = "symlink_metadata", since = "1.1.0")]
pub fn symlink_metadata<P: AsRef<Path>>(path: P) -> io::Result<Metadata> {
fs_imp::lstat(path.as_ref()).map(Metadata)
}
Expand Down Expand Up @@ -1270,7 +1231,6 @@ pub fn set_file_times<P: AsRef<Path>>(path: P, accessed: u64,
/// # Examples
///
/// ```
/// # #![feature(fs)]
/// # fn foo() -> std::io::Result<()> {
/// use std::fs;
///
Expand All @@ -1286,14 +1246,13 @@ pub fn set_file_times<P: AsRef<Path>>(path: P, accessed: u64,
/// This function will return an error if the provided `path` doesn't exist, if
/// the process lacks permissions to change the attributes of the file, or if
/// some other I/O error is encountered.
#[unstable(feature = "fs",
reason = "a more granual ability to set specific permissions may \
be exposed on the Permissions structure itself and this \
method may not always exist")]
pub fn set_permissions<P: AsRef<Path>>(path: P, perm: Permissions) -> io::Result<()> {
#[stable(feature = "set_permissions", since = "1.1.0")]
pub fn set_permissions<P: AsRef<Path>>(path: P, perm: Permissions)
-> io::Result<()> {
fs_imp::set_perm(path.as_ref(), perm.0)
}

#[unstable(feature = "dir_builder", reason = "recently added API")]
impl DirBuilder {
/// Creates a new set of options with default mode/security settings for all
/// platforms and also non-recursive.
Expand Down Expand Up @@ -2066,9 +2025,24 @@ mod tests {
// These numbers have to be bigger than the time in the day to account
// for timezones Windows in particular will fail in certain timezones
// with small enough values
check!(fs::set_file_times(&path, 100000, 200000));
assert_eq!(check!(path.metadata()).accessed(), 100000);
assert_eq!(check!(path.metadata()).modified(), 200000);
check!(fs::set_file_times(&path, 100_000, 200_000));

check(&check!(path.metadata()));

#[cfg(unix)]
fn check(metadata: &fs::Metadata) {
use os::unix::prelude::*;
assert_eq!(metadata.atime(), 100);
assert_eq!(metadata.atime_nsec(), 0);
assert_eq!(metadata.mtime(), 200);
assert_eq!(metadata.mtime_nsec(), 0);
}
#[cfg(windows)]
fn check(metadata: &fs::Metadata) {
use os::windows::prelude::*;
assert_eq!(metadata.last_access_time(), 100_000 * 10_000);
assert_eq!(metadata.last_write_time(), 200_000 * 10_000);
}
}

#[test]
Expand Down
3 changes: 2 additions & 1 deletion src/libstd/os/android/mod.rs
Expand Up @@ -10,10 +10,11 @@

//! Android-specific definitions

#![unstable(feature = "raw_ext", reason = "recently added API")]
#![stable(feature = "raw_ext", since = "1.1.0")]

pub mod raw;

pub mod fs {
#![stable(feature = "raw_ext", since = "1.1.0")]
pub use sys::fs::MetadataExt;
}
59 changes: 58 additions & 1 deletion src/libstd/os/android/raw.rs
Expand Up @@ -10,6 +10,8 @@

//! Android-specific raw type definitions

#![stable(feature = "raw_ext", since = "1.1.0")]

#[doc(inline)]
pub use self::arch::{dev_t, mode_t, blkcnt_t, blksize_t, ino_t, nlink_t, off_t, stat, time_t};

Expand All @@ -18,36 +20,64 @@ mod arch {
use os::raw::{c_uint, c_uchar, c_ulonglong, c_longlong, c_ulong};
use os::unix::raw::{uid_t, gid_t};

#[stable(feature = "raw_ext", since = "1.1.0")]
pub type dev_t = u32;
#[stable(feature = "raw_ext", since = "1.1.0")]
pub type mode_t = u16;

#[stable(feature = "raw_ext", since = "1.1.0")]
pub type blkcnt_t = u32;
#[stable(feature = "raw_ext", since = "1.1.0")]
pub type blksize_t = u32;
#[stable(feature = "raw_ext", since = "1.1.0")]
pub type ino_t = u32;
#[stable(feature = "raw_ext", since = "1.1.0")]
pub type nlink_t = u16;
#[stable(feature = "raw_ext", since = "1.1.0")]
pub type off_t = i32;
#[stable(feature = "raw_ext", since = "1.1.0")]
pub type time_t = i32;

#[repr(C)]
#[stable(feature = "raw_ext", since = "1.1.0")]
pub struct stat {
#[stable(feature = "raw_ext", since = "1.1.0")]
pub st_dev: c_ulonglong,
#[stable(feature = "raw_ext", since = "1.1.0")]
pub __pad0: [c_uchar; 4],
#[stable(feature = "raw_ext", since = "1.1.0")]
pub __st_ino: ino_t,
#[stable(feature = "raw_ext", since = "1.1.0")]
pub st_mode: c_uint,
#[stable(feature = "raw_ext", since = "1.1.0")]
pub st_nlink: c_uint,
#[stable(feature = "raw_ext", since = "1.1.0")]
pub st_uid: uid_t,
#[stable(feature = "raw_ext", since = "1.1.0")]
pub st_gid: gid_t,
#[stable(feature = "raw_ext", since = "1.1.0")]
pub st_rdev: c_ulonglong,
#[stable(feature = "raw_ext", since = "1.1.0")]
pub __pad3: [c_uchar; 4],
#[stable(feature = "raw_ext", since = "1.1.0")]
pub st_size: c_longlong,
#[stable(feature = "raw_ext", since = "1.1.0")]
pub st_blksize: blksize_t,
#[stable(feature = "raw_ext", since = "1.1.0")]
pub st_blocks: c_ulonglong,
#[stable(feature = "raw_ext", since = "1.1.0")]
pub st_atime: time_t,
#[stable(feature = "raw_ext", since = "1.1.0")]
pub st_atime_nsec: c_ulong,
#[stable(feature = "raw_ext", since = "1.1.0")]
pub st_mtime: time_t,
#[stable(feature = "raw_ext", since = "1.1.0")]
pub st_mtime_nsec: c_ulong,
#[stable(feature = "raw_ext", since = "1.1.0")]
pub st_ctime: time_t,
#[stable(feature = "raw_ext", since = "1.1.0")]
pub st_ctime_nsec: c_ulong,
#[stable(feature = "raw_ext", since = "1.1.0")]
pub st_ino: c_ulonglong,
}

Expand All @@ -59,37 +89,64 @@ mod arch {
use os::raw::{c_uchar, c_ulong};
use os::unix::raw::{uid_t, gid_t};

#[stable(feature = "raw_ext", since = "1.1.0")]
pub type dev_t = u64;
#[stable(feature = "raw_ext", since = "1.1.0")]
pub type mode_t = u32;

#[stable(feature = "raw_ext", since = "1.1.0")]
pub type blkcnt_t = u64;
#[stable(feature = "raw_ext", since = "1.1.0")]
pub type blksize_t = u32;
#[stable(feature = "raw_ext", since = "1.1.0")]
pub type ino_t = u64;
#[stable(feature = "raw_ext", since = "1.1.0")]
pub type nlink_t = u32;
#[stable(feature = "raw_ext", since = "1.1.0")]
pub type off_t = i64;
#[stable(feature = "raw_ext", since = "1.1.0")]
pub type time_t = i64;

#[repr(C)]
#[stable(feature = "raw_ext", since = "1.1.0")]
pub struct stat {
#[stable(feature = "raw_ext", since = "1.1.0")]
pub st_dev: dev_t,
#[stable(feature = "raw_ext", since = "1.1.0")]
pub __pad0: [c_uchar; 4],
#[stable(feature = "raw_ext", since = "1.1.0")]
pub __st_ino: ino_t,
#[stable(feature = "raw_ext", since = "1.1.0")]
pub st_mode: mode_t,
#[stable(feature = "raw_ext", since = "1.1.0")]
pub st_nlink: nlink_t,
#[stable(feature = "raw_ext", since = "1.1.0")]
pub st_uid: uid_t,
#[stable(feature = "raw_ext", since = "1.1.0")]
pub st_gid: gid_t,
#[stable(feature = "raw_ext", since = "1.1.0")]
pub st_rdev: dev_t,
#[stable(feature = "raw_ext", since = "1.1.0")]
pub __pad3: [c_uchar; 4],
#[stable(feature = "raw_ext", since = "1.1.0")]
pub st_size: off_t,
#[stable(feature = "raw_ext", since = "1.1.0")]
pub st_blksize: blksize_t,
#[stable(feature = "raw_ext", since = "1.1.0")]
pub st_blocks: blkcnt_t,
#[stable(feature = "raw_ext", since = "1.1.0")]
pub st_atime: time_t,
#[stable(feature = "raw_ext", since = "1.1.0")]
pub st_atime_nsec: c_ulong,
#[stable(feature = "raw_ext", since = "1.1.0")]
pub st_mtime: time_t,
#[stable(feature = "raw_ext", since = "1.1.0")]
pub st_mtime_nsec: c_ulong,
#[stable(feature = "raw_ext", since = "1.1.0")]
pub st_ctime: time_t,
#[stable(feature = "raw_ext", since = "1.1.0")]
pub st_ctime_nsec: c_ulong,
#[stable(feature = "raw_ext", since = "1.1.0")]
pub st_ino: ino_t,
}

}
3 changes: 2 additions & 1 deletion src/libstd/os/bitrig/mod.rs
Expand Up @@ -10,10 +10,11 @@

//! Bitrig-specific definitions

#![unstable(feature = "raw_ext", reason = "recently added API")]
#![stable(feature = "raw_ext", since = "1.1.0")]

pub mod raw;

pub mod fs {
#![stable(feature = "raw_ext", since = "1.1.0")]
pub use sys::fs::MetadataExt;
}

0 comments on commit 50ab23d

Please sign in to comment.