POSIX error asserters and minor improvements in other classes
This commit is contained in:
parent
bcb2ba3dee
commit
53db2f0d71
@ -1 +1 @@
|
||||
Subproject commit 4b799c0ecfac0d501ce335147c2ed021e5d4bea9
|
||||
Subproject commit e57851782134ca0613646efdf7b44d2e5a23de08
|
||||
@ -2,7 +2,7 @@ package ru.landgrafhomyak.utility.kotlin_native_interop_stdlib_0.posix
|
||||
|
||||
import kotlinx.cinterop.ExperimentalForeignApi
|
||||
import kotlinx.cinterop.toKStringFromUtf8
|
||||
import platform.posix.errno
|
||||
import platform.posix.errno as native_errnoVar
|
||||
import platform.posix.strerror
|
||||
import ru.landgrafhomyak.utility.kotlin_native_interop_stdlib_0.OsException
|
||||
|
||||
@ -31,20 +31,22 @@ public class PosixApiException : OsException {
|
||||
}
|
||||
|
||||
override fun toString(): String =
|
||||
"<windows api exception errno=${this.errno}>"
|
||||
"<posix api exception errno=${this.errno}>"
|
||||
|
||||
public companion object {
|
||||
public fun throwFromLastWindowsErr(): Nothing {
|
||||
throw this.formatFromLastWindowsErr()
|
||||
public fun getLastErrno(): Int = native_errnoVar
|
||||
|
||||
public fun throwFromLastPosixErr(): Nothing {
|
||||
throw this.formatFromLastPosixErr()
|
||||
}
|
||||
|
||||
public fun throwFromWindowsErrCode(code: Int): Nothing {
|
||||
throw this.formatFromWindowsErrCode(code)
|
||||
public fun throwFromPosixErrCode(code: Int): Nothing {
|
||||
throw this.formatFromPosixErrCode(code)
|
||||
}
|
||||
|
||||
public fun formatFromLastWindowsErr(): PosixApiException = this.formatFromWindowsErrCode(errno)
|
||||
public fun formatFromLastPosixErr(): PosixApiException = this.formatFromPosixErrCode(native_errnoVar)
|
||||
|
||||
public fun formatFromWindowsErrCode(code: Int): PosixApiException {
|
||||
public fun formatFromPosixErrCode(code: Int): PosixApiException {
|
||||
var err = PosixApiException(errno = code, nativeMessage = null, customMessage = "[errno=${code}]")
|
||||
try {
|
||||
val nativeMessage = this.getNativeMessageByErrno(code)
|
||||
@ -61,7 +63,7 @@ public class PosixApiException : OsException {
|
||||
if (raw != null) {
|
||||
return raw.toKStringFromUtf8()
|
||||
} else {
|
||||
val strerrErrno = errno
|
||||
val strerrErrno = native_errnoVar
|
||||
throw PosixApiException(errno = strerrErrno, nativeMessage = null, "[errno=${strerrErrno}]")
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,56 @@
|
||||
@file:OptIn(ExperimentalContracts::class)
|
||||
|
||||
package ru.landgrafhomyak.utility.kotlin_native_interop_stdlib_0.posix
|
||||
|
||||
import kotlin.contracts.ExperimentalContracts
|
||||
import kotlin.contracts.InvocationKind
|
||||
import kotlin.contracts.contract
|
||||
import kotlinx.cinterop.ExperimentalForeignApi
|
||||
|
||||
|
||||
private fun _checkErrnoAndThrow(): Nothing {
|
||||
val code = PosixApiException.getLastErrno()
|
||||
if (code == 0)
|
||||
throw RuntimeException("Function returned error status, but no error set")
|
||||
PosixApiException.throwFromLastPosixErr()
|
||||
}
|
||||
|
||||
public fun Int.zeroToWinApiErr(): Int {
|
||||
if (this != 0)
|
||||
return this
|
||||
|
||||
_checkErrnoAndThrow()
|
||||
}
|
||||
|
||||
public fun zeroToWinApiErr(call: () -> Int): Int {
|
||||
contract {
|
||||
callsInPlace(call, InvocationKind.EXACTLY_ONCE)
|
||||
}
|
||||
|
||||
val status = call()
|
||||
if (status != 0)
|
||||
return status
|
||||
|
||||
_checkErrnoAndThrow()
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalForeignApi::class)
|
||||
public fun <R : Any> R?.nullToWinApiErr(): R {
|
||||
if (this != null)
|
||||
return this
|
||||
|
||||
_checkErrnoAndThrow()
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalForeignApi::class)
|
||||
public fun <R : Any> nullToWinApiErr(call: () -> R?): R {
|
||||
contract {
|
||||
callsInPlace(call, InvocationKind.EXACTLY_ONCE)
|
||||
}
|
||||
|
||||
val ref = call()
|
||||
if (ref != null)
|
||||
return ref
|
||||
|
||||
_checkErrnoAndThrow()
|
||||
}
|
||||
@ -9,6 +9,7 @@ import kotlinx.cinterop.ptr
|
||||
import kotlinx.cinterop.reinterpret
|
||||
import kotlinx.cinterop.toKString
|
||||
import kotlinx.cinterop.value
|
||||
import platform.posix.errno
|
||||
import platform.windows.FORMAT_MESSAGE_ALLOCATE_BUFFER
|
||||
import platform.windows.FORMAT_MESSAGE_FROM_SYSTEM
|
||||
import platform.windows.FORMAT_MESSAGE_IGNORE_INSERTS
|
||||
@ -46,6 +47,8 @@ public class WindowsApiException : OsException {
|
||||
"<windows api exception errno=${this.errno}>"
|
||||
|
||||
public companion object {
|
||||
public fun getLastErrno(): UInt = GetLastError()
|
||||
|
||||
public fun throwFromLastWindowsErr(): Nothing {
|
||||
throw this.formatFromLastWindowsErr()
|
||||
}
|
||||
|
||||
@ -9,6 +9,7 @@ import platform.windows.HANDLE
|
||||
import ru.landgrafhomyak.utility.closeable_state_1.CloseableState
|
||||
import ru.landgrafhomyak.utility.closeable_state_1.HandleWrapper
|
||||
import ru.landgrafhomyak.utility.closeable_state_1.ManualStateManipulation
|
||||
import ru.landgrafhomyak.utility.highlevel_try_finally.safeAutoClose1
|
||||
|
||||
@OptIn(ExperimentalForeignApi::class)
|
||||
public class WindowsHandleWrapper(
|
||||
@ -32,4 +33,21 @@ public class WindowsHandleWrapper(
|
||||
this._orig.close()
|
||||
zeroToWinApiErr { CloseHandle(this._orig.handle) }
|
||||
}
|
||||
|
||||
public companion object {
|
||||
@OptIn(ExperimentalContracts::class, ManualStateManipulation::class)
|
||||
public fun <R> autoClosed(state: () -> CloseableState, constructor: () -> HANDLE, block: (WindowsHandleWrapper) -> R) {
|
||||
contract {
|
||||
callsInPlace(state, InvocationKind.EXACTLY_ONCE)
|
||||
callsInPlace(constructor, InvocationKind.EXACTLY_ONCE)
|
||||
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||
}
|
||||
|
||||
val wrapper = WindowsHandleWrapper(constructor(), state())
|
||||
safeAutoClose1(
|
||||
action = { block(wrapper) },
|
||||
finally = { wrapper.close() }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -7,11 +7,10 @@ import kotlin.contracts.InvocationKind
|
||||
import kotlin.contracts.contract
|
||||
import kotlinx.cinterop.ExperimentalForeignApi
|
||||
import platform.windows.ERROR_SUCCESS
|
||||
import platform.windows.GetLastError
|
||||
import platform.windows.NULL
|
||||
|
||||
private fun _checkErrnoAndThrow(): Nothing {
|
||||
val code = GetLastError()
|
||||
val code = WindowsApiException.getLastErrno()
|
||||
if (code == ERROR_SUCCESS.toUInt())
|
||||
throw RuntimeException("Function returned error status, but no error set")
|
||||
WindowsApiException.throwFromLastWindowsErr()
|
||||
|
||||
Loading…
Reference in New Issue
Block a user