-
Notifications
You must be signed in to change notification settings - Fork 17.7k
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
os: handle relative paths in fixLongPath on Windows #41734
Comments
Change https://golang.org/cl/263538 mentions this issue: |
@rasky I think fixLongPath() will need to return an error since syscall.FullPath() can. |
Change https://golang.org/cl/291291 mentions this issue: |
I've just submitted a patch that avoids the need for any long path nonsense on Windows 10: https://golang.org/cl/291291 That's not as good as a solution that works on all Windows, but we'll eventually drop support for old Windows anyway. So consider this a forward-looking improvement. cc @jstarks |
@zx2c4, this is quite clever, but I have some reservations about force-setting the bit--Windows only sets the bit for a process if both the system has long paths enabled and the application statically opts in via manifest (ugh). Replacing this policy (which is process-global, of course) with your own for all Go processes might cause problems. Or it may work just fine! A safer approach for now would be to query the bit. This would rely on Go developers including a manifest in their binary, though, and most won't. Not great. I will follow up with the team who built this mechanism to see if they have any guidance. |
Many Go users build for Windows on Linux, etc, so don't have easy access to a Windows manifest tool. Maybe Go needs a Windows manifest tool or go-build option? |
See also #17835. |
I'm pretty sure it would work fine. Unlike random win32 programs, the Go runtime actually controls what's going on, and we're not worried about MAX_PATH buffer overflows or whatever. And if there's a place where it doesn't work fine, we're in a position for it to work fine. And since the "policy" is per process, Go is in a good place to change it. Currently the thing setting it is just good old kernel32.dll at initialization time (actually kernelbase.dll), nothing fancy.
I'm not a huge fan of the manifest approach. And I don't like the idea of us twiddling with the registry or even having to only have this if the registry key is enabled. The Go runtime owns its process, so we can very safely just unconditionally enable it.
Thanks. Please do relay any interesting concerns that the team that owns this code has. Maybe there's something I don't know about that will come up. |
I don't know anything about this, but what happens if a |
Then the resultant C program will handle long paths! IMO, that's a good thing, and a side effect that we can document. If people are writing new software with new Go they're in a place to do things well. OTOH, if you disagree, we could enable this automatically only for exe/pie mode, and put it behind some sort of flag for c-archive/c-shared. |
See also #44466. |
I do not believe that issue is very relevant to this issue, because enabling long paths in a manifest file still requires that a global registry knob be turned, which is not something we can rely on happening, and wouldn't want to induce. On the other hand, https://golang.org/cl/291291 enables the feature per-process, with no global affect, which sounds much more like exactly what we want. |
Windows 10 >= 1607 allows CreateFile and friends to use long paths if bit 0x80 of the PEB's BitField member is set. In time this means we'll be able to entirely drop our long path hacks, which have never really worked right (see bugs below). Until that point, we'll simply have things working well on recent Windows. Updates #41734. Updates #21782. Updates #36375. Change-Id: I765de6ea4859dd4e4b8ca80af7f337994734118e Reviewed-on: https://go-review.googlesource.com/c/go/+/291291 Trust: Jason A. Donenfeld <[email protected]> Run-TryBot: Jason A. Donenfeld <[email protected]> TryBot-Result: Go Bot <[email protected]> Reviewed-by: Brad Fitzpatrick <[email protected]>
Change https://go.dev/cl/570995 mentions this issue: |
I've marked CL 570995 as a fix for this issue. It adds support for UNC paths and Relative paths can't be used with the extended path prefix, so there is nothing to fix there. Quote from Microsoft docs:
|
I'm reopening this issue, as it should be possible to support relative paths in |
Change https://go.dev/cl/574695 mentions this issue: |
Change https://go.dev/cl/607437 mentions this issue: |
CL 574695 added caching the os.Chdir argument for Windows, and used the cached value to assess the length of the current working directory in addExtendedPrefix (used by fixLongPath). It did not take into account that Chdir can accept relative paths, and thus the pathLength calculation in addExtendedPrefix can be wrong. Let's only cache the os.Chdir argument if it's absolute, and clean the cache otherwise, thus improving the correctness of fixLongPath. For #41734 For #21782 For #36375 Change-Id: Ie24a5ed763a7aacc310666d2e4cbb8e298768670 Reviewed-on: https://go-review.googlesource.com/c/go/+/607437 Reviewed-by: Ian Lance Taylor <[email protected]> Reviewed-by: Alex Brainman <[email protected]> Reviewed-by: Damien Neil <[email protected]> Auto-Submit: Ian Lance Taylor <[email protected]> Reviewed-by: Quim Muntal <[email protected]> Reviewed-by: Cherry Mui <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]>
The os package has a function fixLongPath that is used on Windows to turn a very long name like
c:\very\long\name.txt
to\\?\c:\very\long\name.txt
.This function bails out on relative path names. It also bails out on paths containing
..
.This has caused no end of problems and confusion with certain APIs that do or don't accept certain paths.
We should fix fixLongPath to correctly handle all possible inputs and eliminate all those problems.
The text was updated successfully, but these errors were encountered: