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

bug: eza output wrong child items in directory symbolic link on windows. #1025

Open
ulic-youthlic opened this issue Jun 16, 2024 · 14 comments
Open
Labels
errors Something isn't working

Comments

@ulic-youthlic
Copy link

Hi,

basically, I created a folder type symlink using mklink that comes with windows command prompt, and when I go to that symlink and use eza, eza prints the wrong subitems.


Steps to reproduce:

  1. Open cmd.
  2. Create a test folder.
  • md test1
  1. Create a temporary file for testing.
  • echo test > test1\temp.txt
  1. Create a symlink.
  • mklink /D test2 test1
  1. Go to the folder type symbolic link.
  • cd test2
  1. Use the self-contained dir to view the files in the folder.
  • dir
  1. Use eza to view the files under the folder.
  • eza -l

Screenshots:

  • Result of using dir:
    image
  • Result of using eza:
    image

Platform Information:

  • OS: Windows11 Professional 23H2 (Internal version: 22631.3737)
  • Hardware:
    • CPU: 12th Gen Intel(R) Core(TM) i7-12700H 2.30 GHz
  • eza version: v0.18.17 [+git](installed from scoop)
  • shell: cmd
  • terminal: wezterm 20240203-110809-5046fc22

thx.

@ulic-youthlic ulic-youthlic added the errors Something isn't working label Jun 16, 2024
@ulic-youthlic
Copy link
Author

Specifically, eza will have no problems if symbolic links are created using pwersehll's New-Item -ItemType symboliclink -Target "D:\Code\test1" -Path "D:\Code\test2".

@MartinFillon
Copy link
Contributor

Hello, would you mind running EZA_DEBUG=1 eza -l, and sendingthe output in codeblock as I cannot test in a windows environnement. But I might be able to discern why is this happening

@ulic-youthlic
Copy link
Author

Hi, I created a test, pointing to c (using a relative adress form). Here is the output:

[INFO eza] matching on exa.run
[DEBUG eza] Running with options: Options {
    dir_action: List,
    filter: FileFilter {
        list_dirs_first: false,
        sort_field: Name(
            AaBbCc,
        ),
        flags: [],
        dot_filter: JustFiles,
        ignore_patterns: IgnorePatterns {
            patterns: [],
        },
        git_ignore: Off,
    },
    view: View {
        mode: Details(
            Options {
                table: Some(
                    Options {
                        size_format: DecimalBytes,
                        time_format: DefaultFormat,
                        user_format: Name,
                        group_format: Regular,
                        flags_format: Long,
                        columns: Columns {
                            time_types: TimeTypes {
                                modified: true,
                                changed: false,
                                accessed: false,
                                created: false,
                            },
                            inode: false,
                            links: false,
                            blocksize: false,
                            group: false,
                            git: false,
                            subdir_git_repos: false,
                            subdir_git_repos_no_stat: false,
                            octal: false,
                            security_context: false,
                            file_flags: false,
                            permissions: true,
                            filesize: true,
                            user: true,
                        },
                    },
                ),
                header: false,
                xattr: false,
                secattr: false,
                mounts: false,
                color_scale: ColorScaleOptions {
                    mode: Gradient,
                    min_luminance: 40,
                    size: false,
                    age: false,
                },
            },
        ),
        width: Automatic,
        file_style: Options {
            classify: JustFilenames,
            show_icons: Never,
            quote_style: QuoteSpaces,
            embed_hyperlinks: Off,
            absolute: Off,
            is_a_tty: true,
        },
        deref_links: false,
        total_size: false,
    },
    theme: Options {
        use_colours: Automatic,
        colour_scale: ColorScaleOptions {
            mode: Gradient,
            min_luminance: 40,
            size: false,
            age: false,
        },
        definitions: Definitions {
            ls: None,
            exa: None,
        },
    },
    stdin: Args,
}
[DEBUG eza::fs::file] Statting file "."
[DEBUG eza::fs::file] deref_links false
[DEBUG eza::fs::file] Reading link "."
[ERROR eza::fs::file] Error following link "c": Os {
    code: 2,
    kind: NotFound,
    message: "系统找不到指定的文件。",
}
[DEBUG eza::output::table] Creating table with columns: [Permissions, FileSize, Timestamp(Modified)]
[DEBUG eza::fs::file] Reading link "."
[ERROR eza::fs::file] Error following link "c": Os {
    code: 2,
    kind: NotFound,
    message: "系统找不到指定的文件。",
}
[DEBUG eza::output::details] file_name TextCell { contents: TextCellContents([AnsiGenericString { style: Style { fg(Cyan) }, string: ".", oscontrol: None }, AnsiGenericString { style: Style {}, string: " ", oscontrol: None }, AnsiGenericString { style: Style { fg(Red) }, string: "->", oscontrol: None }, AnsiGenericString { style: Style {}, string: " ", oscontrol: None }, AnsiGenericString { style: Style { fg(Red), underline }, string: "c", oscontrol: None }]), width: DisplayWidth(6) }
l---- 0 20 Jun 14:06 . -> c

These reported errors indicate that eza doesn't seem to support resolving relative addresses in symbolic links; I tried creating that link using an absolute address and found that eza worked fine. Of course, I'm not asking eza to add symbolic links for resolving relative links (although I don't really know why it hasn't), as it seems that symbolic links for relative addresses seem to be something rather outdated:

Specifically, eza will have no problems if symbolic links are created using pwersehll's New-Item -ItemType symboliclink -Target "D:\Code\test1" -Path "D:\Code\test2".

As mentioned in that comment, PowerShell also allows the creation of symbolic links, but New-Item already enforces the use of absolute addresse as Target. Anyway, it seems that only cmd's dir now supports resolving symbolic links to relative addresses.


thx your reply

@MartinFillon
Copy link
Contributor

Hey just added some debug infos to the program on the linked branch so that we get more infos, but it seems that the problem might come from path resolving or metadata resolving

@ulic-youthlic
Copy link
Author

Hi, i clone the repo and checkout to branch 1025-bug. The following is the output:

[INFO eza] matching on exa.run
[DEBUG eza] Running with options: Options {
    dir_action: List,
    filter: FileFilter {
        list_dirs_first: false,
        sort_field: Name(
            AaBbCc,
        ),
        flags: [],
        dot_filter: JustFiles,
        ignore_patterns: IgnorePatterns {
            patterns: [],
        },
        git_ignore: Off,
    },
    view: View {
        mode: Details(
            Options {
                table: Some(
                    Options {
                        size_format: DecimalBytes,
                        time_format: DefaultFormat,
                        user_format: Name,
                        group_format: Regular,
                        flags_format: Long,
                        columns: Columns {
                            time_types: TimeTypes {
                                modified: true,
                                changed: false,
                                accessed: false,
                                created: false,
                            },
                            inode: false,
                            links: false,
                            blocksize: false,
                            group: false,
                            git: false,
                            subdir_git_repos: false,
                            subdir_git_repos_no_stat: false,
                            octal: false,
                            security_context: false,
                            file_flags: false,
                            permissions: true,
                            filesize: true,
                            user: true,
                        },
                    },
                ),
                header: false,
                xattr: false,
                secattr: false,
                mounts: false,
                color_scale: ColorScaleOptions {
                    mode: Gradient,
                    min_luminance: 40,
                    size: false,
                    age: false,
                },
            },
        ),
        width: Automatic,
        file_style: Options {
            classify: JustFilenames,
            show_icons: Never,
            quote_style: QuoteSpaces,
            embed_hyperlinks: Off,
            absolute: Off,
            is_a_tty: true,
        },
        deref_links: false,
        total_size: false,
    },
    theme: Options {
        use_colours: Automatic,
        colour_scale: ColorScaleOptions {
            mode: Gradient,
            min_luminance: 40,
            size: false,
            age: false,
        },
        definitions: Definitions {
            ls: None,
            exa: None,
        },
    },
    stdin: Args,
}
[DEBUG eza::fs::file] Statting file "."
[DEBUG eza::fs::file] deref_links false
[DEBUG eza::fs::file] Reading link "."
[DEBUG eza::fs::file] Error 系统找不到指定的文件。 (os error 2) following "c"
[ERROR eza::fs::file] Error following link "c": Os {
    code: 2,
    kind: NotFound,
    message: "系统找不到指定的文件。",
}
[DEBUG eza::output::table] Creating table with columns: [Permissions, FileSize, Timestamp(Modified)]
[DEBUG eza::fs::file] Reading link "."
[DEBUG eza::fs::file] Error 系统找不到指定的文件。 (os error 2) following "c"
[ERROR eza::fs::file] Error following link "c": Os {
    code: 2,
    kind: NotFound,
    message: "系统找不到指定的文件。",
}
[DEBUG eza::output::details] file_name TextCell { contents: TextCellContents([AnsiGenericString { style: Style { fg(Cyan) }, string: ".", oscontrol: None }, AnsiGenericString { style: Style {}, string: " ", oscontrol: None }, AnsiGenericString { style: Style { fg(Red) }, string: "->", oscontrol: None }, AnsiGenericString { style: Style {}, string: " ", oscontrol: None }, AnsiGenericString { style: Style { fg(Red), underline }, string: "c", oscontrol: None }]), width: DisplayWidth(6) }
l---- 0 20 Jun 15:43 . -> c

@MartinFillon
Copy link
Contributor

Okay so as I expected this looks like a rust std lib error, where it cannot find the file.

@ChrisDenton
Copy link

The debug output neglects to print the absolute_path being given to std::fs::metadata

match std::fs::metadata(&absolute_path) {

My guess would be there's something interesting about that path.

@ChrisDenton
Copy link

ChrisDenton commented Jun 20, 2024

Ah I think I understand the issue. This is caused by the difference between . on Windows and POSIX. In POSIX it's a real file that exists (if only in the mind of the kernel). Whereas on Windows there is no .. It's resolved by parsing the path.

So on Windows C:\path\to\dir\. is really just a fancy way of writing C:\path\to\dir (i.e. it's resolved just by modifying the path, the filesystem and kernel don't know anything about it). Whereas in POSIX /path/to/dir/. is an actual file you can stat or whatever that links to /path/to/dir. Mostly this difference doesn't matter but if C:\path\to\dir is a symlink then this causes confusion because the code assumes it's a POSIX . link. Instead it's reading the link from the parent dir.

So to try to put it more clearly reading test2\. reads the link from test2. This link is relative to test2's parent, not from test2 itself. Hence it's not found when looking within test2.

@ulic-youthlic
Copy link
Author

That may be right, when I created a c folder inside test, I ran eza inside test and it showed the contents of the c folder I created, not the c folder that test was originally pointing to. This means that when I run eza in test, my cwd is still inside test, but it is looking for a c folder here.

@MartinFillon
Copy link
Contributor

Ah I think I understand the issue. This is caused by the difference between . on Windows and POSIX. In POSIX it's a real file that exists (if only in the mind of the kernel). Whereas on Windows there is no .. It's resolved by parsing the path.

Is there a known way to resolve this that you might know of ?

@ChrisDenton
Copy link

I'm not familiar enough with eza's code base to say with any confidence. I'm not clear why it's trying to stat .. That's not normally shown, right? In any case it might be that . and .. need to be treated specially. I.e. decide that they are always considered links to their respective parent.

@MartinFillon
Copy link
Contributor

Oh okay I see, we will need some special case handling i guess.

Thoughts @PThorpe92 @cafkafk @gierens ?

@cafkafk
Copy link
Member

cafkafk commented Jul 16, 2024

Oh okay I see, we will need some special case handling i guess.

Thoughts @PThorpe92 @cafkafk @gierens ?

Honestly I'm not sure I fully understand the issue, but one way would maybe be to create separate code for unix/windows targets that deal with this. Likely something a windows user would have to do.

@MartinFillon
Copy link
Contributor

yes thats indeed what we need to have in order for those links to be handled

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
errors Something isn't working
Projects
None yet
Development

When branches are created from issues, their pull requests are automatically linked.

4 participants