-
Notifications
You must be signed in to change notification settings - Fork 165
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
Use SHCreateDirectoryExW
to create a directory with intermediate directories on Windows
#1033
Conversation
@swift-ci Please test |
7d0d507
to
47a904c
Compare
@swift-ci Please test |
47a904c
to
0ab5153
Compare
@swift-ci Please test |
Ah, looks like |
241368a
to
9ec9778
Compare
OK, after some more thinking, maybe using The Gist for creating a directory with intermediate directories is now:
We have two different states that we store in this implementation:
One thing that I’m not entire sure about is whether
And I’m not exactly sure what that means. I was able to create directories inside hidden folders alright, so that doesn’t seem to be it. But really I’m trying to figure out if there will be a bunch of these subtle differences or whether |
@swift-ci Please test |
SHCreateDirectory
to create a directory with intermediate directories on WindowsSHCreateDirectoryExW
to create a directory with intermediate directories on Windows
@swift-ci Please test |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks so much for iterating on this - I personally like this approach and am in favor of it over the added fileExists
check to the existing implementation assuming @compnerd doesn't see any issues with using SHCreateDirectoryExW
. I agree with your assessment on the possible asynchronous state changing that I think based on the nature of it here, it doesn't matter and wouldn't result in a true TOCTOU issue. Thanks!!
guard let currentDirectoryPath else { | ||
// The path is not absolute but we don't have a current path either. | ||
// Pretending that the path is absolute is the best we can do. | ||
return try body(pwszPath) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When exactly can this happen? Unlike Unix, the current path cannot be removed from under you as you have an open handle. The path cannot have been constructed after you entered as it would not exist. This feels like we could precondition
it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I’m not sure when there would be no working directory on Windows. GetCurrentDirectory
says
If the function fails, the return value is zero. To get extended error information, call GetLastError.
Which leads me to believe that there are ways for it to fail.
Happy to change this to a precondition though. Crashing is probably preferable to doing unknown file system operations.
While looking into this, I also noticed that currentDirectoryPath
can be nil
due to a race condition, but I don’t think we need to cover that here: #1034
// A directory already exists at this path, which is not an error if we have | ||
// `createIntermediates == true`. | ||
break | ||
} else { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the else
necessary? Can we not just drop the else
and undent the body of the clause?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, can be flattened
…tories on Windows Instead of recursively creating all the parent directories, which is racy if the directory is created between the check if the parent directory exists and the actual directory creation, use `SHCreateDirectoryExW`, which also creates intermediate directories.
9ec9778
to
1a22c48
Compare
@swift-ci Please test |
…tories on Windows (swiftlang#1033)
Instead of recursively creating all the parent directories, which is racy if the directory is created between the check if the parent directory exists and the actual directory creation, use
SHCreateDirectoryExW
, which also creates intermediate directories.Alternative to #1021