Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion core/apple/src/files/FileSystemApple.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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.*


Expand Down Expand Up @@ -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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is invoking NSFileManager.defaultManager() is a cheap operation?
Can we lazily cache default manager?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
)
}
20 changes: 3 additions & 17 deletions core/native/src/files/FileSystemNative.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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<stat>()
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)
Expand All @@ -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)
Expand Down
24 changes: 21 additions & 3 deletions core/nonApple/src/files/FileSystemNonApple.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,28 @@

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No special Gradle configuring for the new source set?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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<stat>()
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
)
}
}