swift-foundation
swift-foundation copied to clipboard
`Data.write(to:options:)` crashes if `[.atomic, .withoutOverwriting]` are passed together
https://github.com/swiftlang/swift-foundation/blob/c0532f8c99491949d146fbd9b9f2bac5384e6dbd/Sources/FoundationEssentials/Data/Data.swift#L2445-L2447
Severe, source breaking bug here. In 5.10 and below, [.atomic, .withoutOverwriting] worked just fine (possibly not achieving the desired behaviour). We've got to back out this change because
- It's source breaking (works in 5.10, crashes in 6.0)
- The docs don't mention that
.atomicand.withoutOverwritingare mutually exclusive - They shouldn't be mutually exclusive
3.1. On Linux, the man page for open's example for
O_TMPFILEcontains how to implement[.atomic, .withoutOverwriting]3.2. On systems that lackO_TMPFILE, this can still be approximated with write to.tmp_XXXXXX, then rename tmp file (and remove if that fails). That still prevents half-written files
Hi! My idea is to remove the fatalError and make it safe to use .atomic and .withoutOverwriting together by:
- Writing the data to a temporary file first (using
.atomic) - If the destination file already exists, delete the temp file and throw a standard Cocoa error (
NSFileWriteFileExistsError) - If it doesn't exist, move the temp file to the destination path
This should match the behavior we had in Swift 5.10 and keep things safe without overwriting files unexpectedly. Let me know if this direction works — I’ll send in a draft PR soon so we can review it together.
Thanks!