Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

std: Expand the area of std::fs #24711

Merged
merged 2 commits into from
Apr 30, 2015
Merged

std: Expand the area of std::fs #24711

merged 2 commits into from
Apr 30, 2015

Conversation

alexcrichton
Copy link
Member

This commit is an implementation of RFC 1044 which adds additional
surface area to the std::fs module. All new APIs are #[unstable] behind
assorted feature names for each one.

The new APIs added are:

  • fs::canonicalize - bindings to realpath on unix and
    GetFinalPathNameByHandle on windows.
  • fs::symlink_metadata - similar to lstat on unix
  • fs::FileType and accessor methods as is_{file,dir,symlink}
  • fs::Metadata::file_type - accessor for the raw file type
  • fs::DirEntry::metadata - acquisition of metadata which is free on Windows
    but requires a syscall on unix.
  • fs::DirEntry::file_type - access the file type which may not require a
    syscall on most platforms.
  • fs::DirEntry::file_name - access just the file name without leading
    components.
  • fs::PathExt::symlink_metadata - convenience method for the top-level
    function.
  • fs::PathExt::canonicalize - convenience method for the top-level
    function.
  • fs::PathExt::read_link - convenience method for the top-level
    function.
  • fs::PathExt::read_dir - convenience method for the top-level
    function.
  • std::os::raw - type definitions for raw OS/C types available on all
    platforms.
  • std::os::$platform - new modules have been added for all currently supported
    platforms (e.g. those more specific than just unix).
  • std::os::$platform::raw - platform-specific type definitions. These modules
    are populated with the bare essentials necessary for lowing I/O types into
    their raw representations, and currently largely consist of the stat
    definition for unix platforms.

This commit also deprecates Metadata::{modified, accessed} in favor of
inspecting the raw representations via the lowering methods of Metadata.

Closes #24796

@rust-highfive
Copy link
Collaborator

r? @pcwalton

(rust_highfive has picked a reviewer for you, use r? to override)

@alexcrichton
Copy link
Member Author

r? @aturon

Note that this should not be merged until the RFC is approved.

-> io::Result<()>
{
sys::fs2::symlink_inner(src.as_ref(), dst.as_ref(), true)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like you missed moving the new symlink APIs when breaking these modules out into separate files.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops! I had a feeling I shouldn't have ignored that merge conflict.

@alexcrichton
Copy link
Member Author

@lambda

Thanks for the info! I'm moving discussion out here as your comment is now collapsed. This actually poses some difficulties and the current solution makes me feel uncomfortable. There are currently two methods of acquiring a FileType, one through DirEntry and the other through FileAttr (speaking in fs2 terms). The DirEntry one knows whether it's a symlink or not (by reading the dwReserved0 field you mentioned), but the FileAttr does not).

There are a few places which we can get a FileAttr:

  • DirEntry::metadata - this is fine as it already knows whether it's a symlink or not
  • File::metadata - this is problematic as to learn about whether the file is a symlink it requires a syscall
  • lstat - this is less problematic as we can switch to using FindFirstFile as you mentioned, but it is somewhat unnerving that accidental * or ? characters in the path could produce some odd results.
  • stat - this suffers the same problems as File::metadata and lstat

Overall this basically means that we need to have an extra syscall or some different semantics (which now makes me worry about read_dir...). This is an unfortunate deviation for what may not be that important all the time, so I suppose it suffices to say that I'm glad that these functions are #[unstable] for now!

Regardless, though, I think the current implementation is at least "more correct", although I'm not convinced that we actually want it!

@lambda
Copy link
Contributor

lambda commented Apr 24, 2015

I think that the latest approach that you've added looks fine, and I think that the abstraction is reasonable; having to spend an extra syscall to find out if a file is a symlink or not doesn't seem unreasonable, especially since you only pay that extra cost for reparse points, which should be fairly rare. And I think your current approach is fine, you're right, there are some concerns using FindFirstFile so this way of doing it should be fine.

On the other hand, I'm not a Windows expert; I just noticed the problem since I'd been reading the documentation closely while reviewing rust-lang/rfcs#1044 and writing rust-lang/rfcs#1048. @retep998 do you have any opinion on this, you seem to have the most Windows API experience?

@retep998
Copy link
Member

As long as we're only doing that extra syscall for reparse points, the cost should be negligible since most files are not reparse points. That said, the implementation of invoking readlink just to find out whether a reparse point is a symlink seems a bit too heavy. It would be nice to eventually expose all the possible reparse tag variants, not just symbolic links.

@bors
Copy link
Contributor

bors commented Apr 25, 2015

☔ The latest upstream changes (presumably #24724) made this pull request unmergeable. Please resolve the merge conflicts.

self.root.join(&self.file_name())
}

pub fn file_name(&self) -> OsString {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Like I pointed out in the RFC (a little lately, sorry for that). If the entry is a directory or something else, is file_name is still a good method name ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This matches the file_name methods of Path, which was the source for this name. The directory/file distinction here is known to not apply much.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not really fine with that. I find it not clear. It's really a shame that I was aware of the RFC so lately...


/// Return the metadata for the file that this entry points at.
///
/// This function may not require an extra system call on some platforms
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about: "This function may require an extra system call on some platforms" (or, better yet: we could go ahead and add the # Platform behavior section and give a fuller breakdown).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea! I've started out with the platform behavior sections to see where it takes us.

This commit is an implementation of [RFC 1044][rfc] which adds additional
surface area to the `std::fs` module. All new APIs are `#[unstable]` behind
assorted feature names for each one.

[rfc]: rust-lang/rfcs#1044

The new APIs added are:

* `fs::canonicalize` - bindings to `realpath` on unix and
  `GetFinalPathNameByHandle` on windows.
* `fs::symlink_metadata` - similar to `lstat` on unix
* `fs::FileType` and accessor methods as `is_{file,dir,symlink}`
* `fs::Metadata::file_type` - accessor for the raw file type
* `fs::DirEntry::metadata` - acquisition of metadata which is free on Windows
  but requires a syscall on unix.
* `fs::DirEntry::file_type` - access the file type which may not require a
  syscall on most platforms.
* `fs::DirEntry::file_name` - access just the file name without leading
  components.
* `fs::PathExt::symlink_metadata` - convenience method for the top-level
  function.
* `fs::PathExt::canonicalize` - convenience method for the top-level
  function.
* `fs::PathExt::read_link` - convenience method for the top-level
  function.
* `fs::PathExt::read_dir` - convenience method for the top-level
  function.
* `std::os::raw` - type definitions for raw OS/C types available on all
  platforms.
* `std::os::$platform` - new modules have been added for all currently supported
  platforms (e.g. those more specific than just `unix`).
* `std::os::$platform::raw` - platform-specific type definitions. These modules
  are populated with the bare essentials necessary for lowing I/O types into
  their raw representations, and currently largely consist of the `stat`
  definition for unix platforms.

This commit also deprecates `Metadata::{modified, accessed}` in favor of
inspecting the raw representations via the lowering methods of `Metadata`.
@alexcrichton
Copy link
Member Author

@bors: r=aturon 9348700

@alexcrichton
Copy link
Member Author

@aturon I actually forgot that I didn't implement DirBuilder. I've just added a small commit which does so, re-r?

@aturon
Copy link
Member

aturon commented Apr 28, 2015

@alexcrichton Lovely!

@bors: r+

@bors
Copy link
Contributor

bors commented Apr 28, 2015

📌 Commit ebc2440 has been approved by aturon

@bors
Copy link
Contributor

bors commented Apr 28, 2015

⌛ Testing commit ebc2440 with merge a23c862...

@bors
Copy link
Contributor

bors commented Apr 28, 2015

💔 Test failed - auto-win-64-nopt-t

This is the last remaining portion of rust-lang#24796
@alexcrichton
Copy link
Member Author

@bors: r+ 0368abb

@bors
Copy link
Contributor

bors commented Apr 29, 2015

⌛ Testing commit 0368abb with merge e3c5027...

@bors
Copy link
Contributor

bors commented Apr 29, 2015

💔 Test failed - auto-linux-32-nopt-t

@alexcrichton
Copy link
Member Author

@bors: retry

On Wed, Apr 29, 2015 at 12:22 AM, bors notifications@github.com wrote:

[image: 💔] Test failed - auto-linux-32-nopt-t
http://buildbot.rust-lang.org/builders/auto-linux-32-nopt-t/builds/4726


Reply to this email directly or view it on GitHub
#24711 (comment).

bors added a commit that referenced this pull request Apr 29, 2015
This commit is an implementation of [RFC 1044][rfc] which adds additional
surface area to the `std::fs` module. All new APIs are `#[unstable]` behind
assorted feature names for each one.

[rfc]: rust-lang/rfcs#1044

The new APIs added are:

* `fs::canonicalize` - bindings to `realpath` on unix and
  `GetFinalPathNameByHandle` on windows.
* `fs::symlink_metadata` - similar to `lstat` on unix
* `fs::FileType` and accessor methods as `is_{file,dir,symlink}`
* `fs::Metadata::file_type` - accessor for the raw file type
* `fs::DirEntry::metadata` - acquisition of metadata which is free on Windows
  but requires a syscall on unix.
* `fs::DirEntry::file_type` - access the file type which may not require a
  syscall on most platforms.
* `fs::DirEntry::file_name` - access just the file name without leading
  components.
* `fs::PathExt::symlink_metadata` - convenience method for the top-level
  function.
* `fs::PathExt::canonicalize` - convenience method for the top-level
  function.
* `fs::PathExt::read_link` - convenience method for the top-level
  function.
* `fs::PathExt::read_dir` - convenience method for the top-level
  function.
* `std::os::raw` - type definitions for raw OS/C types available on all
  platforms.
* `std::os::$platform` - new modules have been added for all currently supported
  platforms (e.g. those more specific than just `unix`).
* `std::os::$platform::raw` - platform-specific type definitions. These modules
  are populated with the bare essentials necessary for lowing I/O types into
  their raw representations, and currently largely consist of the `stat`
  definition for unix platforms.

This commit also deprecates `Metadata::{modified, accessed}` in favor of
inspecting the raw representations via the lowering methods of `Metadata`.

Closes #24796
@bors
Copy link
Contributor

bors commented Apr 29, 2015

⌛ Testing commit 0368abb with merge 1696dcf...

@bors
Copy link
Contributor

bors commented Apr 29, 2015

💔 Test failed - auto-linux-32-opt

@alexcrichton
Copy link
Member Author

@bors: retry

On Wed, Apr 29, 2015 at 10:48 AM, bors notifications@github.com wrote:

[image: 💔] Test failed - auto-linux-32-opt
http://buildbot.rust-lang.org/builders/auto-linux-32-opt/builds/4742


Reply to this email directly or view it on GitHub
#24711 (comment).

@bors
Copy link
Contributor

bors commented Apr 29, 2015

@bors
Copy link
Contributor

bors commented Apr 29, 2015

💔 Test failed - auto-linux-32-nopt-t

@alexcrichton
Copy link
Member Author

@bors: retry

On Wed, Apr 29, 2015 at 1:16 PM, bors notifications@github.com wrote:

[image: 💔] Test failed - auto-linux-32-nopt-t
http://buildbot.rust-lang.org/builders/auto-linux-32-nopt-t/builds/4737


Reply to this email directly or view it on GitHub
#24711 (comment).

@bors
Copy link
Contributor

bors commented Apr 29, 2015

alexcrichton added a commit to alexcrichton/rust that referenced this pull request Apr 29, 2015
This commit is an implementation of [RFC 1044][rfc] which adds additional
surface area to the `std::fs` module. All new APIs are `#[unstable]` behind
assorted feature names for each one.

[rfc]: rust-lang/rfcs#1044

The new APIs added are:

* `fs::canonicalize` - bindings to `realpath` on unix and
  `GetFinalPathNameByHandle` on windows.
* `fs::symlink_metadata` - similar to `lstat` on unix
* `fs::FileType` and accessor methods as `is_{file,dir,symlink}`
* `fs::Metadata::file_type` - accessor for the raw file type
* `fs::DirEntry::metadata` - acquisition of metadata which is free on Windows
  but requires a syscall on unix.
* `fs::DirEntry::file_type` - access the file type which may not require a
  syscall on most platforms.
* `fs::DirEntry::file_name` - access just the file name without leading
  components.
* `fs::PathExt::symlink_metadata` - convenience method for the top-level
  function.
* `fs::PathExt::canonicalize` - convenience method for the top-level
  function.
* `fs::PathExt::read_link` - convenience method for the top-level
  function.
* `fs::PathExt::read_dir` - convenience method for the top-level
  function.
* `std::os::raw` - type definitions for raw OS/C types available on all
  platforms.
* `std::os::$platform` - new modules have been added for all currently supported
  platforms (e.g. those more specific than just `unix`).
* `std::os::$platform::raw` - platform-specific type definitions. These modules
  are populated with the bare essentials necessary for lowing I/O types into
  their raw representations, and currently largely consist of the `stat`
  definition for unix platforms.

This commit also deprecates `Metadata::{modified, accessed}` in favor of
inspecting the raw representations via the lowering methods of `Metadata`.

Closes rust-lang#24796
@bors
Copy link
Contributor

bors commented Apr 29, 2015

⛄ The build was interrupted to prioritize another pull request.

@bors
Copy link
Contributor

bors commented Apr 29, 2015

@bors
Copy link
Contributor

bors commented Apr 30, 2015

⛄ The build was interrupted to prioritize another pull request.

@bors bors merged commit 0368abb into rust-lang:master Apr 30, 2015
@alexcrichton alexcrichton deleted the fs2.1 branch April 30, 2015 02:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Tracking issue for std::fs extensions (RFC #1044)
8 participants