Skip to content

Commit 9ef1f15

Browse files
committed
TSCBasic: repair the Windows build after swiftlang#277
This fixes multiple issues with the file locking implementation on Windows. `AbsolutePath.root` is meaningless on Windows - there is no concept of a singular root on Windows, instead you have have 26 individual roots - A-Z. Stripping the count of characters for the root path leaves us with an invalid path string as the root drives have been stripped. The next character is an invalid character on most file systems, and so we must replace `:`. Instead of using a `MAX_NAME` to compute a length of the ARC, enforce a limit for the complete path (though an ARC would be limited to 255 codepoints on NTFS). This incidentally also corrects the emitted path, previous path computation left us with the file in PWD.
1 parent bccbd93 commit 9ef1f15

File tree

1 file changed

+18
-1
lines changed

1 file changed

+18
-1
lines changed

Sources/TSCBasic/Lock.swift

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,23 @@ public final class FileLock {
178178
throw FileSystemError(.notDirectory, lockFilesDirectory)
179179
}
180180
// use the parent path to generate unique filename in temp
181-
var lockFileName = (resolveSymlinks(fileToLock.parentDirectory).appending(component: fileToLock.basename)).components.joined(separator: "_") + ".lock"
181+
var lockFileName = (resolveSymlinks(fileToLock.parentDirectory)
182+
.appending(component: fileToLock.basename))
183+
.components.joined(separator: "_")
184+
.replacingOccurrences(of: ":", with: "_") + ".lock"
185+
#if os(Windows)
186+
// NTFS has an ARC limit of 255 codepoints
187+
var lockFileUTF16 = lockFileName.utf16.suffix(255)
188+
while String(lockFileUTF16) == nil {
189+
lockFileUTF16 = lockFileUTF16.dropFirst()
190+
}
191+
lockFileName = String(lockFileUTF16) ?? lockFileName
192+
193+
let path = lockFilesDirectory.appending(component: lockFileName)
194+
if path.pathString.utf8.count > Int(MAX_PATH) {
195+
lockFileName = String(lockFileName.dropFirst(path.pathString.utf8.count - Int(MAX_PATH)))
196+
}
197+
#else
182198
if lockFileName.hasPrefix(AbsolutePath.root.pathString) {
183199
lockFileName = String(lockFileName.dropFirst(AbsolutePath.root.pathString.count))
184200
}
@@ -191,6 +207,7 @@ public final class FileLock {
191207
}
192208
// we will never end up with nil since we have ASCII characters at the end
193209
lockFileName = String(lockFileUTF8) ?? lockFileName
210+
#endif
194211
let lockFilePath = lockFilesDirectory.appending(component: lockFileName)
195212

196213
let lock = FileLock(at: lockFilePath)

0 commit comments

Comments
 (0)