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

read_link cannot open some files reported as symbolic links on windows #28528

Closed
BurntSushi opened this issue Sep 20, 2015 · 8 comments
Closed
Labels
O-windows Operating system: Windows

Comments

@BurntSushi
Copy link
Member

rustc on Windows 7 32 bit:

C:\Users\andrew\walkdir\symlinks>rustc --version
rustc 1.5.0-nightly (6e5a32547 2015-09-19)

Test program:

use std::fs;

fn main() {
    let md = fs::symlink_metadata("is_a_symlink").unwrap();
    println!("is symlink? {}", md.file_type().is_symlink());
    match fs::read_link("is_a_symlink") {
        Ok(p) => println!("{}", p.display()),
        Err(err) => println!("{:?}", err),
    }
}

Create a symlink on Windows at is_a_symlink pointing to not_a_symlink and
run above program (working as intended):

C:\Users\andrew\walkdir\symlinks>mklink is_a_symlink C:\Users\andrew\walkdir\symlinks\not_a_symlink
symbolic link created for is_a_symlink <<===>> C:\Users\andrew\walkdir\symlinks\not_a_symlink

C:\Users\andrew\walkdir\symlinks>dir
09/19/2015  11:40 PM    <DIR>          .
09/19/2015  11:40 PM    <DIR>          ..
09/19/2015  11:40 PM    <SYMLINK>      is_a_symlink [C:\Users\andrew\walkdir\symlinks\not_a_symlink]
09/19/2015  11:32 PM                 0 not_a_symlink
09/19/2015  11:36 PM         2,118,989 win_symlink_test.exe
09/19/2015  11:36 PM               261 win_symlink_test.rs

C:\Users\andrew\walkdir\symlinks>win_symlink_test.exe
is symlink? true
\??\C:\Users\andrew\walkdir\symlinks\not_a_symlink

This correctly identifies the file as a symlink and resolves it correctly.

If we instead creation a junction and follow the same steps, we can observe an
inconsistency between file_type().is_symlink() and the behavior of
fs::read_link:

C:\Users\andrew\walkdir\symlinks>mklink /J is_a_symlink C:\Users\andrew\walkdir\symlinks\not_a_symlink
Junction created for is_a_symlink <<===>> C:\Users\andrew\walkdir\symlinks\not_a_symlink

C:\Users\andrew\walkdir\symlinks>dir
09/19/2015  11:46 PM    <DIR>          .
09/19/2015  11:46 PM    <DIR>          ..
09/19/2015  11:46 PM    <JUNCTION>     is_a_symlink [C:\Users\andrew\walkdir\symlinks\not_a_symlink]
09/19/2015  11:32 PM                 0 not_a_symlink
09/19/2015  11:44 PM         2,118,946 win_symlink_test.exe
09/19/2015  11:44 PM               286 win_symlink_test.rs

C:\Users\andrew\walkdir\symlinks>win_symlink_test.exe
is symlink? true
Error { repr: Custom(Custom { kind: Other, error: StringError("not a symlink") }) }

(The key difference is the use of mklink /J to create a junction.)

The output here shows that it is correctly detected as a symlink, but
read_link chokes on it.

I looked briefly at the implementation and I haven't the slightest clue what's
wrong (I'm not familiar with Windows).

@Diggsey
Copy link
Contributor

Diggsey commented Sep 20, 2015

The problem is that sys::fs::readlink only handles IO_REPARSE_TAG_SYMLINK, and not IO_REPARSE_TAG_MOUNT_POINT - it should handle both.

The data structures are similar, the main difference being that symlinks have an additional flags field that mount-points don't have: https://msdn.microsoft.com/en-us/library/cc232006.aspx vs https://msdn.microsoft.com/en-us/library/cc232007.aspx

This is where the changes are required: https://github.com/rust-lang/rust/blob/master/src/libstd/sys/windows/fs.rs#L345

@alexcrichton alexcrichton added O-windows Operating system: Windows A-io labels Sep 22, 2015
@SingingTree
Copy link
Contributor

Hey, I'd be keen to have a go at this issue.

@alexcrichton
Copy link
Member

@SingingTree feel free! If you've got any questions, feel free to reach out to me on IRC (acrichto) or here.

@SingingTree
Copy link
Contributor

@alexcrichton I have some work in progress, and would like to discuss what I'm doing. What would be the best process for this? Should I create a PR and mark it as WIP, or would it be better to discuss the work in a fork, sans PR?

@alexcrichton
Copy link
Member

Ah I'm fine discussing either here or with a PR, whichever you'd prefer!

@SingingTree
Copy link
Contributor

Soz I'm been slack on this. I've been working on it, but have a been a bit busier than anticipated, so if anyone else wants to grab this, go ahead, otherwise I'm hoping to continue when I've got a bit more time.

@pitdicker
Copy link
Contributor

I would like to take this on next weekend

@alexcrichton
Copy link
Member

Thanks @pitdicker!

@bors bors closed this as completed in 6403f91 Feb 14, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
O-windows Operating system: Windows
Projects
None yet
Development

No branches or pull requests

5 participants