diff --git a/core/apple/src/files/FileSystemApple.kt b/core/apple/src/files/FileSystemApple.kt index f7c07dca0..ed2632997 100644 --- a/core/apple/src/files/FileSystemApple.kt +++ b/core/apple/src/files/FileSystemApple.kt @@ -11,7 +11,7 @@ import kotlinx.cinterop.cstr import kotlinx.cinterop.memScoped import kotlinx.cinterop.toKString import kotlinx.io.IOException -import platform.Foundation.NSTemporaryDirectory +import platform.Foundation.* import platform.posix.* @@ -55,3 +55,15 @@ internal actual fun realpathImpl(path: String): String { free(res) } } + +internal actual fun metadataOrNullImpl(path: Path): FileMetadata? { + val attributes = NSFileManager.defaultManager().fileAttributesAtPath(path.path, traverseLink = true) ?: return null + val fileType = attributes[NSFileType] as String + val isFile = fileType == NSFileTypeRegular + val isDir = fileType == NSFileTypeDirectory + return FileMetadata( + isRegularFile = isFile, + isDirectory = isDir, + size = if (isFile) attributes[NSFileSize] as Long else -1 + ) +} diff --git a/core/native/src/files/FileSystemNative.kt b/core/native/src/files/FileSystemNative.kt index b7c0d5f18..05b4795b1 100644 --- a/core/native/src/files/FileSystemNative.kt +++ b/core/native/src/files/FileSystemNative.kt @@ -63,23 +63,7 @@ public actual val SystemFileSystem: FileSystem = object : SystemFileSystemImpl() atomicMoveImpl(source, destination) } - @OptIn(ExperimentalForeignApi::class, UnsafeNumber::class) - override fun metadataOrNull(path: Path): FileMetadata? { - memScoped { - val struct_stat = alloc() - if (stat(path.path, struct_stat.ptr) != 0) { - if (errno == ENOENT) return null - throw IOException("stat failed to ${path.path}: ${strerror(errno)?.toKString()}") - } - val mode = struct_stat.st_mode.toInt() - val isFile = (mode and S_IFMT) == S_IFREG - return FileMetadata( - isRegularFile = isFile, - isDirectory = (mode and S_IFMT) == S_IFDIR, - if (isFile) struct_stat.st_size.toLong() else -1L - ) - } - } + override fun metadataOrNull(path: Path): FileMetadata? = metadataOrNullImpl(path) override fun resolve(path: Path): Path { if (!exists(path)) throw FileNotFoundException(path.path) @@ -104,6 +88,8 @@ public actual val SystemFileSystem: FileSystem = object : SystemFileSystemImpl() } } +internal expect fun metadataOrNullImpl(path: Path): FileMetadata? + internal expect fun atomicMoveImpl(source: Path, destination: Path) internal expect fun mkdirImpl(path: String) diff --git a/core/nonApple/src/files/FileSystemNonApple.kt b/core/nonApple/src/files/FileSystemNonApple.kt index 6c69cca3c..631aea1a2 100644 --- a/core/nonApple/src/files/FileSystemNonApple.kt +++ b/core/nonApple/src/files/FileSystemNonApple.kt @@ -5,10 +5,28 @@ package kotlinx.io.files -import kotlinx.cinterop.ExperimentalForeignApi -import kotlinx.cinterop.toKString -import platform.posix.getenv +import kotlinx.cinterop.* +import kotlinx.io.IOException +import platform.posix.* @OptIn(ExperimentalForeignApi::class) public actual val SystemTemporaryDirectory: Path get() = Path(getenv("TMPDIR")?.toKString() ?: getenv("TMP")?.toKString() ?: "") + +@OptIn(ExperimentalForeignApi::class, UnsafeNumber::class) +internal actual fun metadataOrNullImpl(path: Path): FileMetadata? { + memScoped { + val struct_stat = alloc() + if (stat(path.path, struct_stat.ptr) != 0) { + if (errno == ENOENT) return null + throw IOException("stat failed to ${path.path}: ${strerror(errno)?.toKString()}") + } + val mode = struct_stat.st_mode.toInt() + val isFile = (mode and S_IFMT) == S_IFREG + return FileMetadata( + isRegularFile = isFile, + isDirectory = (mode and S_IFMT) == S_IFDIR, + if (isFile) struct_stat.st_size.toLong() else -1L + ) + } +}