Skip to content

Commit df90a54

Browse files
authored
Check error codes returned by POSIX-ish APIs and throw IOE (#427)
Closes #262
1 parent 03eb9ba commit df90a54

File tree

4 files changed

+43
-12
lines changed

4 files changed

+43
-12
lines changed

core/androidNative/src/files/FileSystemAndroid.kt

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,20 @@ internal actual class OpaqueDirEntry(private val dir: CPointer<cnames.structs.DI
3535
}
3636

3737
actual override fun close() {
38-
closedir(dir)
38+
if (closedir(dir) != 0) {
39+
val err = errno
40+
val strerr = strerror(err)?.toKString() ?: "unknown error"
41+
throw IOException("closedir failed with errno $err ($strerr)")
42+
}
3943
}
4044
}
4145

4246
@OptIn(ExperimentalForeignApi::class)
4347
internal actual fun opendir(path: String): OpaqueDirEntry {
4448
val dirent = platform.posix.opendir(path)
4549
if (dirent != null) return OpaqueDirEntry(dirent)
46-
throw IOException("Can't open directory $path: ${strerror(errno)?.toKString() ?: "reason unknown"}")
50+
51+
val err = errno
52+
val strerr = strerror(err)?.toKString() ?: "unknown error"
53+
throw IOException("Can't open directory $path: $err ($strerr)")
4754
}

core/native/src/files/PathsNative.kt

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,12 @@ internal expect fun isAbsoluteImpl(path: String): Boolean
6464

6565
public actual fun Path(path: String): Path = Path(path, null)
6666

67+
private fun throwIOExceptionForErrno(operation: String): Nothing {
68+
val err = errno
69+
val strerr = strerror(err)?.toKString() ?: "unknown error"
70+
throw IOException("$operation failed with errno $err ($strerr)")
71+
}
72+
6773
internal class FileSource(
6874
private val file: CPointer<FILE>
6975
) : RawSource {
@@ -85,15 +91,17 @@ internal class FileSource(
8591
return when {
8692
bytesRead == byteCount -> bytesRead
8793
feof(file) != 0 -> if (bytesRead == 0L) -1L else bytesRead
88-
ferror(file) != 0 -> throw IOException(errno.toString())
94+
ferror(file) != 0 -> throwIOExceptionForErrno("write")
8995
else -> bytesRead
9096
}
9197
}
9298

9399
override fun close() {
94100
if (closed) return
95101
closed = true
96-
fclose(file)
102+
if (fclose(file) != 0) {
103+
throwIOExceptionForErrno("fclose")
104+
}
97105
}
98106
}
99107

@@ -130,21 +138,21 @@ internal class FileSink(
130138
variantFwrite(pinned.addressOf(0), byteCount.toUInt(), file).toLong()
131139
}
132140
if (bytesWritten < byteCount) {
133-
throw IOException(errno.toString())
141+
throwIOExceptionForErrno("file write")
134142
}
135143
}
136144

137145
override fun flush() {
138146
if (fflush(file) != 0) {
139-
throw IOException(errno.toString())
147+
throwIOExceptionForErrno("fflush")
140148
}
141149
}
142150

143151
override fun close() {
144152
if (closed) return
145153
closed = true
146154
if (fclose(file) != 0) {
147-
throw IOException(errno.toString())
155+
throwIOExceptionForErrno("fclose")
148156
}
149157
}
150158
}

core/nativeNonAndroid/src/files/FileSystemNativeNonAndroid.kt

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,20 @@ internal actual class OpaqueDirEntry(private val dir: CPointer<DIR>) : AutoClose
2323
}
2424

2525
actual override fun close() {
26-
closedir(dir)
26+
if (closedir(dir) != 0) {
27+
val err = errno
28+
val strerr = strerror(err)?.toKString() ?: "unknown error"
29+
throw IOException("closedir failed with errno $err ($strerr)")
30+
}
2731
}
2832
}
2933

3034
@OptIn(ExperimentalForeignApi::class)
3135
internal actual fun opendir(path: String): OpaqueDirEntry {
3236
val dirent = platform.posix.opendir(path)
3337
if (dirent != null) return OpaqueDirEntry(dirent)
34-
throw IOException("Can't open directory $path: ${strerror(errno)?.toKString() ?: "reason unknown"}")
38+
39+
val err = errno
40+
val strerr = strerror(err)?.toKString() ?: "unknown error"
41+
throw IOException("Can't open directory $path: $err ($strerr)")
3542
}

core/wasmWasi/src/files/FileSystemWasm.kt

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,10 @@ internal object WasiFileSystem : SystemFileSystemImpl() {
344344
}
345345
return children
346346
} finally {
347-
fd_close(dir_fd)
347+
val res = Errno(fd_close(dir_fd))
348+
if (res != Errno.success) {
349+
throw IOException("fd_close failed for directory '$directory': ${res.description}")
350+
}
348351
}
349352
}
350353
}
@@ -488,7 +491,10 @@ private class FileSink(private val fd: Fd) : RawSink {
488491
override fun close() {
489492
if (!closed) {
490493
closed = true
491-
fd_close(fd)
494+
val res = Errno(fd_close(fd))
495+
if (res != Errno.success) {
496+
throw IOException("fd_close failed: ${res.description}")
497+
}
492498
}
493499
}
494500
}
@@ -536,7 +542,10 @@ private class FileSource(private val fd: Fd) : RawSource {
536542
override fun close() {
537543
if (!closed) {
538544
closed = true
539-
fd_close(fd)
545+
val res = Errno(fd_close(fd))
546+
if (res != Errno.success) {
547+
throw IOException("fd_close failed: ${res.description}")
548+
}
540549
}
541550
}
542551
}

0 commit comments

Comments
 (0)