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

fs::copy on Windows has a 260 character filename limit #67403

Closed
jdm opened this issue Dec 18, 2019 · 5 comments
Closed

fs::copy on Windows has a 260 character filename limit #67403

jdm opened this issue Dec 18, 2019 · 5 comments
Labels
O-windows Operating system: Windows T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.

Comments

@jdm
Copy link
Contributor

jdm commented Dec 18, 2019

It relies on the CopyFileExW Windows API, which has path limits that yield surprising runtime behaviour. We could opt in to longer path limits (32k instead of 260) by prepending \? to the string, according to that same documentation.

@jdm jdm added O-windows Operating system: Windows T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. labels Dec 18, 2019
@retep998
Copy link
Member

CopyFileExW isn't special in this regard. All Rust filesystem code on Windows currently bumps into this limitation, and it's not just as simple as prepending \\?\.

@jdm
Copy link
Contributor Author

jdm commented Dec 18, 2019

One option might be to document this so it's a little bit less inexplicable to people who don't know the platform details.

@andrewbanchich
Copy link
Contributor

@retep998 The official Microsoft docs suggest doing what @jdm mentioned. The only exception I'm aware of is if it's a UNC then you need to use \\?\UNC\.

What kind of issues would this not address?

@ChrisDenton
Copy link
Member

ChrisDenton commented Oct 1, 2020

Win32 has four types of absolute path:

Type Win32 Example
DOS C:\Windows
UNC \\server\share\
Device \\.\PIPE\name
Verbatim \\?\C:\Windows
\\?\UNC\server\share\
\\?\PIPE\name

It also has three types of relative path:

Type Win32 Example
Path Relative file.ext
.\file.ext
..\file.ext
Root Relative \file.ext
Drive Relative D:file.ext

Rust's file system APIs would at least need to be internally consistent with how they handle all these paths.

A smarter std::path::Path could resolve this issue by having a function to make the path both absolute and verbatim. Or another option is to have an internal API function that automatically gets called before almost* every use of a Windows filesystem API which would do the same thing when necessary.

* I say "almost" because setting the Current Directory does not support verbatim paths. Only DOS and UNC paths are supported.

@ChrisDenton
Copy link
Member

ChrisDenton commented Nov 2, 2021

This should hopefully be fixed in nightly by #89174, which is currently scheduled for the 1.58.0 release.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
O-windows Operating system: Windows T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

5 participants