-
Notifications
You must be signed in to change notification settings - Fork 28
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
FileManager.default.createFile()
doesn't work
#5593
Comments
Another solution is not to call diff --git a/Sources/FoundationEssentials/Data/Data+Writing.swift b/Sources/FoundationEssentials/Data/Data+Writing.swift
index 7c23e1e..29815b0 100644
--- a/Sources/FoundationEssentials/Data/Data+Writing.swift
+++ b/Sources/FoundationEssentials/Data/Data+Writing.swift
@@ -237,9 +237,28 @@ private func createProtectedTemporaryFile(at destinationPath: String, inPath: Pa
}
#endif
+#if os(WASI)
+ let url = URL(fileURLWithPath: destinationPath, isDirectory: false)
+ let temporaryDirectoryPath = try FileManager.default.url(for: .itemReplacementDirectory, in: .userDomainMask, appropriateFor: url, create: true).path(percentEncoded: false)
+ let auxFile = temporaryDirectoryPath.appendingPathComponent(destinationPath.lastPathcomponent)
+ return try auxFile.withFileSystemRepresentation { auxFileFileSystemRep in
+ guard let auxFileFileSystemRep else {
+ throw CocoaError(.fileWriteInvalidFileName)
+ }
+ let fd = openFileDescriptorProtected(path: auxFileFileSystemRep, flags: O_CREAT | O_EXCL | O_RDWR, options: options)
+ if fd >= 0 {
+ return (fd, auxFile, temporaryDirectoryPath)
+ } else {
+ let savedErrno = errno
+ cleanupTemporaryDirectory(at: temporaryDirectoryPath)
+ throw CocoaError.errorWithFilePath(inPath, errno: savedErrno, reading: false, variant: variant)
+ }
+ }
+#else
let temporaryDirectoryPath = destinationPath.deletingLastPathComponent()
let (fd, auxFile) = try createTemporaryFile(at: temporaryDirectoryPath, inPath: inPath, prefix: ".dat.nosync", options: options, variant: variant)
return (fd, auxFile, nil)
+#endif
}
private func write(buffer: UnsafeRawBufferPointer, toFileDescriptor fd: Int32, path: PathOrURL, parentProgress: Progress?) throws { |
I think |
That makes sense, and I agree with the use of non-atomic writing for On the other hand, though this is off the main topic of the issue, I think it would be worthwhile to support the creation of temporary files using |
How about allowing atomic file writing when |
Thank you for your consideration. However, this comment has changed my mind, and I'm beginning to think that relying on |
I created another issue #5594 for discussing atomic file writing. |
fixes swiftwasm/swift#5593 `FileManager.createFile()` currently doesn't work on WASI because it requires `.atomic`, it requires creating a temporary file, and it isn't suppported on WASI. So I have fixed that by removing the `.atomic` requirement only on WASI.
Description
FileManager.default.createFile()
doesn't work.Steps to reproduce
mkdir foo
cd foo
swift package init --type executable
Sources/main.swift
swift build --swift-sdk <Swift SDK for Wasm>
wasmtime run --dir /tmp .build/debug/foo.wasm
Expected behavior
Actual behavior
Environment
Supplement
swift-foundation's
createFile()
implementation forces to use the option.atomic
.So we can see the detailed error by running
try Data().write(to: URL(filePath: "/tmp/foo"), options: .atomic)
.If options contain
.atomic
,createFile()
will callwriteToFileAux()
, andwriteToFileAux()
will callcreateProtectedTemporaryFile()
andcreateTemporaryFile()
. However, SwiftWasm doesn't supportcreateTemporaryFile()
.How about stopping adding
.atomic
increateFile()
ifos(WASI)
?The text was updated successfully, but these errors were encountered: