Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Fix UnixFileSystem.MoveFile on macOS when just changing file casing#18619

Merged
stephentoub merged 3 commits into
dotnet:masterfrom
stephentoub:file_move_fix
Apr 19, 2017
Merged

Fix UnixFileSystem.MoveFile on macOS when just changing file casing#18619
stephentoub merged 3 commits into
dotnet:masterfrom
stephentoub:file_move_fix

Conversation

@stephentoub
Copy link
Copy Markdown
Member

Neither the link/unlink nor copy-all-data approaches work well on a case-insensitive file system when just changing the casing of the file name. This PR adds an upfront check that detects when the files are the same, and in such cases, just does a rename.

(Note that this depends on System.Private.CoreLib having the same understanding of the size of Interop.Sys.FileStatus, and thus the Unix legs of CI will fail until dotnet/coreclr#11070 is merged and consumed into CoreFx.)

https://github.com/dotnet/corefx/issues/18521
cc: @ianhays, @JeremyKuhne, @bording

@ianhays ianhays added this to the 2.0.0 milestone Apr 19, 2017
// for case-insensitive file systems, so that we support changing the casing in the naming
// of the file. If this fails in any way (e.g. source file doesn't exist, dest file doesn't
// exist, rename fails, etc.), we just fall back to trying the link/unlink approach and
// generating any exceptional messages from there as necessary.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A concrete example (like from #18521) would help make understanding this a bit easier I think.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I can add a clarification to the comment that this is particularly impactful for changing the casing in a file name.

Copy link
Copy Markdown
Contributor

@ianhays ianhays left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good!

// generating any exceptional messages from there as necessary.
Interop.Sys.FileStatus sourceStat, destStat;
if (Interop.Sys.LStat(sourceFullPath, out sourceStat) == 0 && // source file exists
Interop.Sys.Stat(destFullPath, out destStat) == 0 && // dest file exists
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if the destination is a link?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We'll follow it (due to using stat). Does your question mean you think this should be LStat instead?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you think this should be LStat instead?

I'm unsure. If A links to B and you try to rename A to a it won't give you the same file descriptor, right? But we should still be renaming, no?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're probably right. It's probably safest to just not follow symlinks and purely look at the target being passed.

Neither the link/unlink nor copy-all-data approaches work well on a case-insensitive file system when just changing the casing of the file name.  This commit adds an upfront check that detects when the files are the same, and in such cases, just does a rename.
@stephentoub stephentoub merged commit 0ad9477 into dotnet:master Apr 19, 2017
@stephentoub stephentoub deleted the file_move_fix branch April 19, 2017 23:10
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants