diff --git a/okio-fakefilesystem/api/okio-fakefilesystem.api b/okio-fakefilesystem/api/okio-fakefilesystem.api index 1d319e4340..f921a157c6 100644 --- a/okio-fakefilesystem/api/okio-fakefilesystem.api +++ b/okio-fakefilesystem/api/okio-fakefilesystem.api @@ -8,6 +8,7 @@ public final class okio/fakefilesystem/FakeFileSystem : okio/FileSystem { public fun atomicMove (Lokio/Path;Lokio/Path;)V public fun canonicalize (Lokio/Path;)Lokio/Path; public final fun checkNoOpenFiles ()V + public fun close ()V public fun createDirectory (Lokio/Path;Z)V public fun createSymlink (Lokio/Path;Lokio/Path;)V public fun delete (Lokio/Path;Z)V diff --git a/okio-fakefilesystem/src/commonMain/kotlin/okio/fakefilesystem/FakeFileSystem.kt b/okio-fakefilesystem/src/commonMain/kotlin/okio/fakefilesystem/FakeFileSystem.kt index fb2bd655a9..96f076d2ac 100644 --- a/okio-fakefilesystem/src/commonMain/kotlin/okio/fakefilesystem/FakeFileSystem.kt +++ b/okio-fakefilesystem/src/commonMain/kotlin/okio/fakefilesystem/FakeFileSystem.kt @@ -59,6 +59,12 @@ import okio.fakefilesystem.FakeFileSystem.Operation.WRITE * Programs that do not attempt any of the above operations should work fine on both UNIX and * Windows systems. Relax these constraints individually or call [emulateWindows] or [emulateUnix]; * to apply the constraints of a particular operating system. + * + * Closeable + * --------- + * + * This file system cannot be used after it is closed. Closing it does not close any of its open + * streams; those must be closed directly. */ class FakeFileSystem( @JvmField @@ -71,6 +77,9 @@ class FakeFileSystem( /** Files that are currently open and need to be closed to avoid resource leaks. */ private val openFiles = mutableListOf() + /** Forbid all access after [close]. */ + private var closed = false + /** * An absolute path with this file system's current working directory. Relative paths will be * resolved against this directory when they are used. @@ -218,6 +227,7 @@ class FakeFileSystem( /** Don't throw [FileNotFoundException] if the path doesn't identify a file. */ private fun canonicalizeInternal(path: Path): Path { + check(!closed) { "closed" } return workingDirectory.resolve(path, normalize = true) } @@ -764,5 +774,9 @@ class FakeFileSystem( override fun toString() = "FileHandler(${openFile.canonicalPath})" } + override fun close() { + closed = true + } + override fun toString() = "FakeFileSystem" } diff --git a/okio-nodefilesystem/src/test/kotlin/okio/NodeJsFileSystemTest.kt b/okio-nodefilesystem/src/test/kotlin/okio/NodeJsFileSystemTest.kt index 3afc3ed62f..2766448165 100644 --- a/okio-nodefilesystem/src/test/kotlin/okio/NodeJsFileSystemTest.kt +++ b/okio-nodefilesystem/src/test/kotlin/okio/NodeJsFileSystemTest.kt @@ -24,4 +24,5 @@ class NodeJsFileSystemTest : AbstractFileSystemTest( allowClobberingEmptyDirectories = Path.DIRECTORY_SEPARATOR == "\\", allowAtomicMoveFromFileToDirectory = false, temporaryDirectory = FileSystem.SYSTEM_TEMPORARY_DIRECTORY, + closeBehavior = CloseBehavior.DoesNothing, ) diff --git a/okio-testing-support/src/commonMain/kotlin/okio/AbstractFileSystemTest.kt b/okio-testing-support/src/commonMain/kotlin/okio/AbstractFileSystemTest.kt index 31ec6cba83..26a34661ec 100644 --- a/okio-testing-support/src/commonMain/kotlin/okio/AbstractFileSystemTest.kt +++ b/okio-testing-support/src/commonMain/kotlin/okio/AbstractFileSystemTest.kt @@ -40,6 +40,7 @@ abstract class AbstractFileSystemTest( val allowClobberingEmptyDirectories: Boolean, val allowAtomicMoveFromFileToDirectory: Boolean, val allowRenameWhenTargetIsOpen: Boolean = !windowsLimitations, + val closeBehavior: CloseBehavior, temporaryDirectory: Path, ) { val base: Path = temporaryDirectory / "${this::class.simpleName}-${randomToken(16)}" @@ -2553,6 +2554,110 @@ abstract class AbstractFileSystemTest( } } + @Test + fun readAfterFileSystemClose() { + val path = base / "file" + + path.writeUtf8("hello, world!") + + when (closeBehavior) { + CloseBehavior.Closes -> { + fileSystem.close() + + assertFailsWith { + fileSystem.canonicalize(path) + } + assertFailsWith { + fileSystem.exists(path) + } + assertFailsWith { + fileSystem.metadata(path) + } + assertFailsWith { + fileSystem.openReadOnly(path) + } + assertFailsWith { + fileSystem.source(path) + } + } + + CloseBehavior.DoesNothing -> { + fileSystem.close() + fileSystem.canonicalize(path) + fileSystem.exists(path) + fileSystem.metadata(path) + fileSystem.openReadOnly(path).use { + } + fileSystem.source(path).use { + } + } + + CloseBehavior.Unsupported -> { + assertFailsWith { + fileSystem.close() + } + } + } + } + + @Test + fun writeAfterFileSystemClose() { + val path = base / "file" + + when (closeBehavior) { + CloseBehavior.Closes -> { + fileSystem.close() + + assertFailsWith { + fileSystem.appendingSink(path) + } + assertFailsWith { + fileSystem.atomicMove(path, base / "file2") + } + assertFailsWith { + fileSystem.createDirectory(base / "directory") + } + assertFailsWith { + fileSystem.delete(path) + } + assertFailsWith { + fileSystem.openReadWrite(path) + } + assertFailsWith { + fileSystem.sink(path) + } + if (supportsSymlink()) { + assertFailsWith { + fileSystem.createSymlink(base / "symlink", base) + } + } + } + + CloseBehavior.DoesNothing -> { + fileSystem.close() + + fileSystem.appendingSink(path).use { + } + fileSystem.atomicMove(path, base / "file2") + fileSystem.createDirectory(base / "directory") + fileSystem.delete(path) + fileSystem.sink(path).use { + } + fileSystem.openReadWrite(path).use { + } + if (supportsSymlink()) { + fileSystem.createSymlink(base / "symlink", base) + } + } + + CloseBehavior.Unsupported -> { + assertFailsWith { + fileSystem.close() + } + } + } + } + protected fun supportsSymlink(): Boolean { if (fileSystem.isFakeFileSystem) return fileSystem.allowSymlinks if (windowsLimitations) return false diff --git a/okio-testing-support/src/commonMain/kotlin/okio/CloseBehavior.kt b/okio-testing-support/src/commonMain/kotlin/okio/CloseBehavior.kt new file mode 100644 index 0000000000..e0ada5e3df --- /dev/null +++ b/okio-testing-support/src/commonMain/kotlin/okio/CloseBehavior.kt @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2024 Square, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package okio + +enum class CloseBehavior { + Closes, + DoesNothing, + Unsupported, +} diff --git a/okio-wasifilesystem/src/wasmWasiTest/kotlin/okio/WasiFileSystemTest.kt b/okio-wasifilesystem/src/wasmWasiTest/kotlin/okio/WasiFileSystemTest.kt index b6846b45d0..a32361173f 100644 --- a/okio-wasifilesystem/src/wasmWasiTest/kotlin/okio/WasiFileSystemTest.kt +++ b/okio-wasifilesystem/src/wasmWasiTest/kotlin/okio/WasiFileSystemTest.kt @@ -24,4 +24,5 @@ class WasiFileSystemTest : AbstractFileSystemTest( allowClobberingEmptyDirectories = Path.DIRECTORY_SEPARATOR == "\\", allowAtomicMoveFromFileToDirectory = false, temporaryDirectory = "/tmp".toPath(), + closeBehavior = CloseBehavior.DoesNothing, ) diff --git a/okio/api/okio.api b/okio/api/okio.api index e124cd36a2..e23255edb3 100644 --- a/okio/api/okio.api +++ b/okio/api/okio.api @@ -448,7 +448,7 @@ public final class okio/FileMetadata { public fun toString ()Ljava/lang/String; } -public abstract class okio/FileSystem { +public abstract class okio/FileSystem : java/io/Closeable { public static final field Companion Lokio/FileSystem$Companion; public static final field RESOURCES Lokio/FileSystem; public static final field SYSTEM Lokio/FileSystem; @@ -462,6 +462,7 @@ public abstract class okio/FileSystem { public static synthetic fun appendingSink$default (Lokio/FileSystem;Lokio/Path;ZILjava/lang/Object;)Lokio/Sink; public abstract fun atomicMove (Lokio/Path;Lokio/Path;)V public abstract fun canonicalize (Lokio/Path;)Lokio/Path; + public fun close ()V public fun copy (Lokio/Path;Lokio/Path;)V public final fun createDirectories (Lokio/Path;)V public final fun createDirectories (Lokio/Path;Z)V @@ -504,6 +505,7 @@ public abstract class okio/ForwardingFileSystem : okio/FileSystem { public fun appendingSink (Lokio/Path;Z)Lokio/Sink; public fun atomicMove (Lokio/Path;Lokio/Path;)V public fun canonicalize (Lokio/Path;)Lokio/Path; + public fun close ()V public fun createDirectory (Lokio/Path;Z)V public fun createSymlink (Lokio/Path;Lokio/Path;)V public final fun delegate ()Lokio/FileSystem; diff --git a/okio/build.gradle.kts b/okio/build.gradle.kts index 901b38f1aa..f38cce34ca 100644 --- a/okio/build.gradle.kts +++ b/okio/build.gradle.kts @@ -78,6 +78,7 @@ kotlin { } val nonWasmTest by creating { + dependsOn(commonTest) dependencies { implementation(libs.kotlin.time) implementation(projects.okioFakefilesystem) diff --git a/okio/src/commonMain/kotlin/okio/FileSystem.kt b/okio/src/commonMain/kotlin/okio/FileSystem.kt index 9535880b62..5797e17b9c 100644 --- a/okio/src/commonMain/kotlin/okio/FileSystem.kt +++ b/okio/src/commonMain/kotlin/okio/FileSystem.kt @@ -79,8 +79,20 @@ package okio * because the `Paths.get()` function automatically uses the default (ie. system) file system. * In Okio's API paths are just identifiers; you must use a specific `FileSystem` object to do * I/O with. + * + * Closeable + * --------- + * + * Implementations of this interface may need to be closed to release resources. + * + * It is the file system implementor's responsibility to document whether a file system instance + * must be closed, and what happens to its open streams when the file system is closed. For example, + * the Java NIO FileSystem closes all of its open streams when the file system is closed. + * + * The built-in `FileSystem.SYSTEM` implementation does not need to be closed and closing it has no + * effect. */ -expect abstract class FileSystem() { +expect abstract class FileSystem() : Closeable { /** * Resolves [path] against the current working directory and symlinks in this file system. The @@ -376,6 +388,9 @@ expect abstract class FileSystem() { @Throws(IOException::class) abstract fun createSymlink(source: Path, target: Path) + @Throws(IOException::class) + override fun close() + companion object { /** * Returns a writable temporary directory on [SYSTEM]. diff --git a/okio/src/commonMain/kotlin/okio/ForwardingFileSystem.kt b/okio/src/commonMain/kotlin/okio/ForwardingFileSystem.kt index 2fe5cd4f06..cdacb80bc6 100644 --- a/okio/src/commonMain/kotlin/okio/ForwardingFileSystem.kt +++ b/okio/src/commonMain/kotlin/okio/ForwardingFileSystem.kt @@ -100,6 +100,10 @@ import kotlin.jvm.JvmName * **This class forwards only the abstract functions;** non-abstract functions delegate to the * other functions of this class. If desired, subclasses may override non-abstract functions to * forward them. + * + * ### Closeable + * + * Closing this file system closes the delegate file system. */ abstract class ForwardingFileSystem( /** [FileSystem] to which this instance is delegating. */ @@ -238,5 +242,10 @@ abstract class ForwardingFileSystem( delegate.createSymlink(source, target) } + @Throws(IOException::class) + override fun close() { + delegate.close() + } + override fun toString() = "${this::class.simpleName}($delegate)" } diff --git a/okio/src/jsMain/kotlin/okio/FileSystem.kt b/okio/src/jsMain/kotlin/okio/FileSystem.kt index ea1bb4bf30..51c16534ea 100644 --- a/okio/src/jsMain/kotlin/okio/FileSystem.kt +++ b/okio/src/jsMain/kotlin/okio/FileSystem.kt @@ -23,7 +23,7 @@ import okio.internal.commonExists import okio.internal.commonListRecursively import okio.internal.commonMetadata -actual abstract class FileSystem { +actual abstract class FileSystem : Closeable { actual abstract fun canonicalize(path: Path): Path actual fun metadata(path: Path): FileMetadata = commonMetadata(path) @@ -84,6 +84,9 @@ actual abstract class FileSystem { actual abstract fun createSymlink(source: Path, target: Path) + actual override fun close() { + } + actual companion object { actual val SYSTEM_TEMPORARY_DIRECTORY: Path = tmpdir.toPath() } diff --git a/okio/src/jvmMain/kotlin/okio/FileSystem.kt b/okio/src/jvmMain/kotlin/okio/FileSystem.kt index 7a552cc551..eb97ca0bdd 100644 --- a/okio/src/jvmMain/kotlin/okio/FileSystem.kt +++ b/okio/src/jvmMain/kotlin/okio/FileSystem.kt @@ -25,7 +25,7 @@ import okio.internal.commonExists import okio.internal.commonListRecursively import okio.internal.commonMetadata -actual abstract class FileSystem { +actual abstract class FileSystem : Closeable { @Throws(IOException::class) actual abstract fun canonicalize(path: Path): Path @@ -125,6 +125,10 @@ actual abstract class FileSystem { @Throws(IOException::class) actual abstract fun createSymlink(source: Path, target: Path) + @Throws(IOException::class) + actual override fun close() { + } + actual companion object { /** * The current process's host file system. Use this instance directly, or dependency inject a @@ -150,6 +154,8 @@ actual abstract class FileSystem { * In applications that compose multiple class loaders, this holds only the resources of * whichever class loader includes Okio classes. Use [ClassLoader.asResourceFileSystem] for the * resources of a specific class loader. + * + * This file system does not need to be closed. Calling its close function does nothing. */ @JvmField val RESOURCES: FileSystem = ResourceFileSystem( @@ -157,6 +163,12 @@ actual abstract class FileSystem { indexEagerly = false, ) + /** + * Closing the returned file system will close the underlying [java.nio.file.FileSystem]. + * + * Note that the [default file system][java.nio.file.FileSystems.getDefault] is not closeable + * and calling its close function will throw an [UnsupportedOperationException]. + */ @JvmName("get") @JvmStatic fun JavaNioFileSystem.asOkioFileSystem(): FileSystem = NioFileSystemWrappingFileSystem(this) diff --git a/okio/src/jvmMain/kotlin/okio/NioFileSystemWrappingFileSystem.kt b/okio/src/jvmMain/kotlin/okio/NioFileSystemWrappingFileSystem.kt index ddf11d8196..c1a3c337c4 100644 --- a/okio/src/jvmMain/kotlin/okio/NioFileSystemWrappingFileSystem.kt +++ b/okio/src/jvmMain/kotlin/okio/NioFileSystemWrappingFileSystem.kt @@ -187,5 +187,9 @@ internal class NioFileSystemWrappingFileSystem(private val nioFileSystem: NioFil source.resolve().createSymbolicLinkPointingTo(target.resolve()) } + override fun close() { + nioFileSystem.close() + } + override fun toString() = nioFileSystem::class.simpleName!! } diff --git a/okio/src/jvmTest/kotlin/okio/FileHandleFileSystemTest.kt b/okio/src/jvmTest/kotlin/okio/FileHandleFileSystemTest.kt index 021ffb4cbb..14f3f911f0 100644 --- a/okio/src/jvmTest/kotlin/okio/FileHandleFileSystemTest.kt +++ b/okio/src/jvmTest/kotlin/okio/FileHandleFileSystemTest.kt @@ -33,6 +33,7 @@ class FileHandleFileSystemTest : AbstractFileSystemTest( allowClobberingEmptyDirectories = Path.DIRECTORY_SEPARATOR == "\\", allowAtomicMoveFromFileToDirectory = false, temporaryDirectory = FileSystem.SYSTEM_TEMPORARY_DIRECTORY, + closeBehavior = CloseBehavior.DoesNothing, ) { /** * A testing-only file system that implements all reading and writing operations with @@ -75,6 +76,7 @@ class FileHandleNioJimFileSystemWrapperFileSystemTest : AbstractFileSystemTest( allowClobberingEmptyDirectories = true, allowAtomicMoveFromFileToDirectory = true, temporaryDirectory = FileSystem.SYSTEM_TEMPORARY_DIRECTORY, + closeBehavior = CloseBehavior.Closes, ) class FileHandleNioDefaultFileSystemWrapperFileSystemTest : AbstractFileSystemTest( @@ -87,4 +89,5 @@ class FileHandleNioDefaultFileSystemWrapperFileSystemTest : AbstractFileSystemTe allowAtomicMoveFromFileToDirectory = false, allowRenameWhenTargetIsOpen = Path.DIRECTORY_SEPARATOR != "\\", temporaryDirectory = FileSystem.SYSTEM_TEMPORARY_DIRECTORY, + closeBehavior = CloseBehavior.Unsupported, ) diff --git a/okio/src/jvmTest/kotlin/okio/JvmSystemFileSystemTest.kt b/okio/src/jvmTest/kotlin/okio/JvmSystemFileSystemTest.kt index fc4b7c0910..ff06ec2f84 100644 --- a/okio/src/jvmTest/kotlin/okio/JvmSystemFileSystemTest.kt +++ b/okio/src/jvmTest/kotlin/okio/JvmSystemFileSystemTest.kt @@ -37,6 +37,7 @@ class NioSystemFileSystemTest : AbstractFileSystemTest( allowClobberingEmptyDirectories = Path.DIRECTORY_SEPARATOR == "\\", allowAtomicMoveFromFileToDirectory = false, temporaryDirectory = FileSystem.SYSTEM_TEMPORARY_DIRECTORY, + closeBehavior = CloseBehavior.DoesNothing, ) class JvmSystemFileSystemTest : AbstractFileSystemTest( @@ -46,6 +47,7 @@ class JvmSystemFileSystemTest : AbstractFileSystemTest( allowClobberingEmptyDirectories = Path.DIRECTORY_SEPARATOR == "\\", allowAtomicMoveFromFileToDirectory = false, temporaryDirectory = FileSystem.SYSTEM_TEMPORARY_DIRECTORY, + closeBehavior = CloseBehavior.DoesNothing, ) { @Test fun checkInterruptedBeforeDeleting() { @@ -73,6 +75,7 @@ class NioJimFileSystemWrappingFileSystemTest : AbstractFileSystemTest( allowClobberingEmptyDirectories = true, allowAtomicMoveFromFileToDirectory = true, temporaryDirectory = FileSystem.SYSTEM_TEMPORARY_DIRECTORY, + closeBehavior = CloseBehavior.Closes, ) class NioDefaultFileSystemWrappingFileSystemTest : AbstractFileSystemTest( @@ -83,4 +86,5 @@ class NioDefaultFileSystemWrappingFileSystemTest : AbstractFileSystemTest( allowAtomicMoveFromFileToDirectory = false, allowRenameWhenTargetIsOpen = Path.DIRECTORY_SEPARATOR != "\\", temporaryDirectory = FileSystem.SYSTEM_TEMPORARY_DIRECTORY, + closeBehavior = CloseBehavior.Unsupported, ) diff --git a/okio/src/nativeMain/kotlin/okio/FileSystem.kt b/okio/src/nativeMain/kotlin/okio/FileSystem.kt index 7672c919b3..d575a62a4c 100644 --- a/okio/src/nativeMain/kotlin/okio/FileSystem.kt +++ b/okio/src/nativeMain/kotlin/okio/FileSystem.kt @@ -22,7 +22,7 @@ import okio.internal.commonExists import okio.internal.commonListRecursively import okio.internal.commonMetadata -actual abstract class FileSystem { +actual abstract class FileSystem : Closeable { @Throws(IOException::class) actual abstract fun canonicalize(path: Path): Path @@ -102,6 +102,10 @@ actual abstract class FileSystem { @Throws(IOException::class) actual abstract fun createSymlink(source: Path, target: Path) + @Throws(IOException::class) + actual override fun close() { + } + actual companion object { /** * The current process's host file system. Use this instance directly, or dependency inject a diff --git a/okio/src/nativeTest/kotlin/okio/NativeSystemFileSystemTest.kt b/okio/src/nativeTest/kotlin/okio/NativeSystemFileSystemTest.kt index e4db5eff15..68bd596b1d 100644 --- a/okio/src/nativeTest/kotlin/okio/NativeSystemFileSystemTest.kt +++ b/okio/src/nativeTest/kotlin/okio/NativeSystemFileSystemTest.kt @@ -24,4 +24,5 @@ class NativeSystemFileSystemTest : AbstractFileSystemTest( allowClobberingEmptyDirectories = Path.DIRECTORY_SEPARATOR == "\\", allowAtomicMoveFromFileToDirectory = false, temporaryDirectory = FileSystem.SYSTEM_TEMPORARY_DIRECTORY, + closeBehavior = CloseBehavior.DoesNothing, ) diff --git a/okio/src/nonWasmTest/kotlin/okio/FakeFileSystemTest.kt b/okio/src/nonWasmTest/kotlin/okio/FakeFileSystemTest.kt index 07dfad8d9e..6a86b0a4e0 100644 --- a/okio/src/nonWasmTest/kotlin/okio/FakeFileSystemTest.kt +++ b/okio/src/nonWasmTest/kotlin/okio/FakeFileSystemTest.kt @@ -51,6 +51,7 @@ abstract class FakeFileSystemTest internal constructor( allowClobberingEmptyDirectories = fakeFileSystem.allowClobberingEmptyDirectories, allowAtomicMoveFromFileToDirectory = false, temporaryDirectory = temporaryDirectory, + closeBehavior = CloseBehavior.Closes, ) { private val fakeClock: FakeClock = fakeFileSystem.clock as FakeClock diff --git a/okio/src/nonWasmTest/kotlin/okio/ForwardingFileSystemTest.kt b/okio/src/nonWasmTest/kotlin/okio/ForwardingFileSystemTest.kt index 6b7e089ba6..6b2fb526de 100644 --- a/okio/src/nonWasmTest/kotlin/okio/ForwardingFileSystemTest.kt +++ b/okio/src/nonWasmTest/kotlin/okio/ForwardingFileSystemTest.kt @@ -30,6 +30,7 @@ class ForwardingFileSystemTest : AbstractFileSystemTest( allowClobberingEmptyDirectories = false, allowAtomicMoveFromFileToDirectory = false, temporaryDirectory = "/".toPath(), + closeBehavior = CloseBehavior.Closes, ) { @Test fun pathBlocking() { @@ -169,4 +170,19 @@ class ForwardingFileSystemTest : AbstractFileSystemTest( assertEquals(listOf("metadataOrNull(path=$source)", "metadataOrNull($target)"), log) } + + /** Closing the ForwardingFileSystem closes the delegate. */ + @Test + fun closeForwards() { + val delegate = FakeFileSystem() + + val forwardingFileSystem = object : ForwardingFileSystem(delegate) { + } + + forwardingFileSystem.close() + + assertFailsWith { + delegate.list(base) + } + } } diff --git a/okio/src/wasmMain/kotlin/okio/FileSystem.kt b/okio/src/wasmMain/kotlin/okio/FileSystem.kt index 2152a91b0c..190bba8b16 100644 --- a/okio/src/wasmMain/kotlin/okio/FileSystem.kt +++ b/okio/src/wasmMain/kotlin/okio/FileSystem.kt @@ -23,7 +23,7 @@ import okio.internal.commonExists import okio.internal.commonListRecursively import okio.internal.commonMetadata -actual abstract class FileSystem { +actual abstract class FileSystem : Closeable { actual abstract fun canonicalize(path: Path): Path actual fun metadata(path: Path): FileMetadata = commonMetadata(path) @@ -84,6 +84,9 @@ actual abstract class FileSystem { actual abstract fun createSymlink(source: Path, target: Path) + actual override fun close() { + } + actual companion object { actual val SYSTEM_TEMPORARY_DIRECTORY: Path = "/tmp".toPath() } diff --git a/okio/src/zlibMain/kotlin/okio/ZlibOkio.kt b/okio/src/zlibMain/kotlin/okio/ZlibOkio.kt index cf4c0315ae..827e001d52 100644 --- a/okio/src/zlibMain/kotlin/okio/ZlibOkio.kt +++ b/okio/src/zlibMain/kotlin/okio/ZlibOkio.kt @@ -22,5 +22,14 @@ package okio import kotlin.jvm.JvmMultifileClass import kotlin.jvm.JvmName +/** + * Returns a new read-only file system. + * + * This function processes the ZIP file's central directory and builds an index of its files and + * their offsets within the ZIP. If the ZIP file is changed after this function returns, this + * file system will be broken and may return inconsistent data or crash when it is accessed. + * + * Closing the returned file system is not necessary and does nothing. + */ @Throws(IOException::class) fun FileSystem.openZip(zipPath: Path): FileSystem = okio.internal.openZip(zipPath, this)