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

Problem with isfile_casesensitive() on Windows #54799

Open
kimikage opened this issue Jun 14, 2024 · 2 comments · May be fixed by #55220
Open

Problem with isfile_casesensitive() on Windows #54799

kimikage opened this issue Jun 14, 2024 · 2 comments · May be fixed by #55220

Comments

@kimikage
Copy link
Contributor

An internal function isfile_casesensitive() uses Win32API GetLongPathNameW on Windows.

julia/base/loading.jl

Lines 11 to 16 in 222231f

elseif Sys.iswindows()
# GetLongPathName Win32 function returns the case-preserved filename on NTFS.
function isfile_casesensitive(path)
isaccessiblefile(path) || return false # Fail fast
basename(Filesystem.longpath(path)) == basename(path)
end

However, the API may not be able to handle non-existent directories.

julia> dir = joinpath(DEPOT_PATH[1], "environments", "v1.10") # just an example
"C:\\Users\\username\\.julia\\environments\\v1.10"

julia> Base.Filesystem.longpath(joinpath(dir, "Project.toml"))
"C:\\Users\\username\\.julia\\environments\\v1.10\\Project.toml"

julia> Base.Filesystem.longpath(joinpath(dir, "nonexistent", "..", "Project.toml"))
ERROR: SystemError: longpath: The system cannot find the file specified.
Stacktrace:
 [1] windowserror(p::Symbol, code::UInt32; extrainfo::Nothing)
   @ Base .\error.jl:200
 [2] windowserror
   @ .\error.jl:199 [inlined]
 [3] longpath(path::String)
   @ Base.Filesystem .\path.jl:479
 [4] top-level scope
   @ REPL[3]:1

julia> versioninfo()
Julia Version 1.12.0-DEV.727
Commit 3054c00d33 (2024-06-14 05:13 UTC)
Build Info:
  Official https://julialang.org/ release
Platform Info:
  OS: Windows (x86_64-w64-mingw32)
  CPU: 8 × 11th Gen Intel(R) Core(TM) i7-1165G7 @ 2.80GHz
  WORD_SIZE: 64
  LLVM: libLLVM-17.0.6 (ORCJIT, tigerlake)
Threads: 1 default, 0 interactive, 1 GC (on 8 virtual cores)

This problem can also be reproduced on Julia v1.6.7.
Perhaps `normpath()' would mitigate this problem.

Incidentally, parent directories of non-existent directories seem to be invalid on Linux from the beginning.

@kimikage
Copy link
Contributor Author

Or, (on Julia v1.11 and later)

function Base.isfile_casesensitive(path)
    Base.isaccessiblefile(path) || return false  # Fail fast
    name = basename(path)
    try
        for entry in Base.Filesystem._readdirx(dirname(path), sort = false)
            entry.name == name && return true
        end
    catch err
        isa(err, Base.IOError) || rethrow()
    end
    return false
end

@IanButterworth IanButterworth linked a pull request Jul 23, 2024 that will close this issue
@stevengj
Copy link
Member

Why should it succeed for paths that contain non-existent directories (even if they are cancelled out by ..)?

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 a pull request may close this issue.

2 participants