Fix socket example on POSIX (#966)
This commit is contained in:
+2
-1
@@ -26,5 +26,6 @@ class InteropConfiguration(
|
|||||||
val pkgName: String,
|
val pkgName: String,
|
||||||
val excludedFunctions: Set<String>,
|
val excludedFunctions: Set<String>,
|
||||||
val strictEnums: Set<String>,
|
val strictEnums: Set<String>,
|
||||||
val nonStrictEnums: Set<String>
|
val nonStrictEnums: Set<String>,
|
||||||
|
val noStringConversion: Set<String>
|
||||||
)
|
)
|
||||||
+8
-3
@@ -57,6 +57,10 @@ class StubGenerator(
|
|||||||
val excludedFunctions: Set<String>
|
val excludedFunctions: Set<String>
|
||||||
get() = configuration.excludedFunctions
|
get() = configuration.excludedFunctions
|
||||||
|
|
||||||
|
val noStringConversion: Set<String>
|
||||||
|
get() = configuration.noStringConversion
|
||||||
|
|
||||||
|
|
||||||
val platformWStringTypes = setOf("LPCWSTR")
|
val platformWStringTypes = setOf("LPCWSTR")
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -305,10 +309,11 @@ class StubGenerator(
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
fun representCFunctionParameterAsString(type: Type): Boolean {
|
fun representCFunctionParameterAsString(function: FunctionDecl, type: Type): Boolean {
|
||||||
val unwrappedType = type.unwrapTypedefs()
|
val unwrappedType = type.unwrapTypedefs()
|
||||||
return unwrappedType is PointerType && unwrappedType.pointeeIsConst &&
|
return unwrappedType is PointerType && unwrappedType.pointeeIsConst &&
|
||||||
unwrappedType.pointeeType.unwrapTypedefs() == CharType
|
unwrappedType.pointeeType.unwrapTypedefs() == CharType &&
|
||||||
|
!noStringConversion.contains(function.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
// We take this approach as generic 'const short*' shall not be used as String.
|
// We take this approach as generic 'const short*' shall not be used as String.
|
||||||
@@ -612,7 +617,7 @@ class StubGenerator(
|
|||||||
|
|
||||||
val representAsValuesRef = representCFunctionParameterAsValuesRef(parameter.type)
|
val representAsValuesRef = representCFunctionParameterAsValuesRef(parameter.type)
|
||||||
|
|
||||||
val bridgeArgument = if (representCFunctionParameterAsString(parameter.type)) {
|
val bridgeArgument = if (representCFunctionParameterAsString(func, parameter.type)) {
|
||||||
kotlinParameters.add(parameterName to KotlinTypes.string.makeNullable())
|
kotlinParameters.add(parameterName to KotlinTypes.string.makeNullable())
|
||||||
bodyGenerator.pushMemScoped()
|
bodyGenerator.pushMemScoped()
|
||||||
"$parameterName?.cstr?.getPointer(memScope)"
|
"$parameterName?.cstr?.getPointer(memScope)"
|
||||||
|
|||||||
+2
-1
@@ -310,7 +310,8 @@ private fun processLib(args: Map<String, List<String>>,
|
|||||||
pkgName = outKtPkg,
|
pkgName = outKtPkg,
|
||||||
excludedFunctions = excludedFunctions,
|
excludedFunctions = excludedFunctions,
|
||||||
strictEnums = def.config.strictEnums.toSet(),
|
strictEnums = def.config.strictEnums.toSet(),
|
||||||
nonStrictEnums = def.config.nonStrictEnums.toSet()
|
nonStrictEnums = def.config.nonStrictEnums.toSet(),
|
||||||
|
noStringConversion = def.config.noStringConversion.toSet()
|
||||||
)
|
)
|
||||||
|
|
||||||
val nativeIndex = buildNativeIndex(library)
|
val nativeIndex = buildNativeIndex(library)
|
||||||
|
|||||||
@@ -26,4 +26,11 @@ static int posix_errno() {
|
|||||||
// Wrapper to access h_errno variable.
|
// Wrapper to access h_errno variable.
|
||||||
static int posix_h_errno() {
|
static int posix_h_errno() {
|
||||||
return h_errno;
|
return h_errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int init_sockets() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void deinit_sockets() {
|
||||||
}
|
}
|
||||||
@@ -26,3 +26,10 @@ static int posix_errno() {
|
|||||||
static int posix_h_errno() {
|
static int posix_h_errno() {
|
||||||
return h_errno;
|
return h_errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int init_sockets() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void deinit_sockets() {
|
||||||
|
}
|
||||||
@@ -62,3 +62,10 @@ static void posix_FD_SET(int bit, fd_set *set) {
|
|||||||
static int posix_FD_ISSET(int bit, fd_set *set) {
|
static int posix_FD_ISSET(int bit, fd_set *set) {
|
||||||
return FD_ISSET(bit, set);
|
return FD_ISSET(bit, set);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int init_sockets() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void deinit_sockets() {
|
||||||
|
}
|
||||||
@@ -48,3 +48,10 @@ static void posix_FD_SET(int bit, fd_set *set) {
|
|||||||
static int posix_FD_ISSET(int bit, fd_set *set) {
|
static int posix_FD_ISSET(int bit, fd_set *set) {
|
||||||
return FD_ISSET(bit, set);
|
return FD_ISSET(bit, set);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int init_sockets() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void deinit_sockets() {
|
||||||
|
}
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
package = platform.posix
|
package = platform.posix
|
||||||
headers = stdio.h Windef.h Winsock2.h Ws2tcpip.h Ws2def.h io.h math.h
|
headers = stdio.h winsock.h io.h math.h
|
||||||
compilerOpts = -DUNICODE -Wno-incompatible-pointer-types -Wno-deprecated-declarations
|
compilerOpts = -DUNICODE -DWINVER=0x0601 -D_WIN32_WINNT=0x0601 -DWINAPI_FAMILY=3 \
|
||||||
|
-Wno-incompatible-pointer-types -Wno-deprecated-declarations
|
||||||
|
noStringConversion = send recv
|
||||||
linkerOpts = -lWs2_32
|
linkerOpts = -lWs2_32
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -29,3 +31,14 @@ static void posix_FD_SET(int bit, fd_set *set) {
|
|||||||
static int posix_FD_ISSET(int bit, fd_set *set) {
|
static int posix_FD_ISSET(int bit, fd_set *set) {
|
||||||
return FD_ISSET(bit, set);
|
return FD_ISSET(bit, set);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int init_sockets() {
|
||||||
|
WORD wVersionRequested = MAKEWORD(2, 2);
|
||||||
|
WSADATA wsaData;
|
||||||
|
return WSAStartup(wVersionRequested, &wsaData);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void deinit_sockets() {
|
||||||
|
WSACleanup();
|
||||||
|
return;
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package = platform.windows
|
package = platform.windows
|
||||||
headers = windows.h commctrl.h dwmapi.h shlobj.h shlwapi.h shobjidl.h \
|
headers = windows.h commctrl.h dwmapi.h shlobj.h shlwapi.h shobjidl.h \
|
||||||
urlmon.h usp10.h uxtheme.h vfw.h wininet.h
|
urlmon.h usp10.h uxtheme.h vfw.h wininet.h winsock2.h ws2tcpip.h ws2def.h
|
||||||
compilerOpts = -DUNICODE -DWINVER=0x0601 -D_WIN32_WINNT=0x0601 -DWINAPI_FAMILY=3 \
|
compilerOpts = -DUNICODE -DWINVER=0x0601 -D_WIN32_WINNT=0x0601 -DWINAPI_FAMILY=3 \
|
||||||
-Wno-incompatible-pointer-types -Wno-deprecated-declarations
|
-Wno-incompatible-pointer-types -Wno-deprecated-declarations
|
||||||
linkerOpts = -lcomctl32 -lcrypt32 -lshlwapi -lshell32 -limm32 -lusp10 -lwininet
|
linkerOpts = -lcomctl32 -lcrypt32 -lshlwapi -lshell32 -limm32 -lusp10 -lwininet
|
||||||
|
depends = posix
|
||||||
|
|||||||
@@ -25,55 +25,61 @@ fun main(args: Array<String>) {
|
|||||||
|
|
||||||
val port = args[0].toShort()
|
val port = args[0].toShort()
|
||||||
|
|
||||||
|
// Initialize sockets in platform-dependent way.
|
||||||
|
init_sockets()
|
||||||
|
|
||||||
memScoped {
|
memScoped {
|
||||||
|
|
||||||
val bufferLength = 100L
|
val buffer = ByteArray(1024)
|
||||||
val buffer = allocArray<ByteVar>(bufferLength)
|
val prefixBuffer = kotlin.text.toUtf8Array("echo: ", 0, 6)
|
||||||
val serverAddr = alloc<sockaddr_in>()
|
val serverAddr = alloc<sockaddr_in>()
|
||||||
|
|
||||||
val listenFd = socket(AF_INET, SOCK_STREAM, 0)
|
val listenFd = socket(AF_INET, SOCK_STREAM, 0)
|
||||||
.ensureUnixCallResult { it >= 0 }
|
.ensureUnixCallResult("socket") { it >= 0 }
|
||||||
|
|
||||||
with(serverAddr) {
|
with(serverAddr) {
|
||||||
memset(this.ptr, 0, sockaddr_in.size)
|
memset(this.ptr, 0, sockaddr_in.size)
|
||||||
sin_family = AF_INET.narrow()
|
sin_family = AF_INET.narrow()
|
||||||
sin_addr.s_addr = posix_htons(0).toInt()
|
|
||||||
sin_port = posix_htons(port)
|
sin_port = posix_htons(port)
|
||||||
}
|
}
|
||||||
|
|
||||||
bind(listenFd, serverAddr.ptr.reinterpret(), sockaddr_in.size.toInt())
|
bind(listenFd, serverAddr.ptr.reinterpret(), sockaddr_in.size.toInt())
|
||||||
.ensureUnixCallResult { it == 0 }
|
.ensureUnixCallResult("bind") { it == 0 }
|
||||||
|
|
||||||
listen(listenFd, 10)
|
listen(listenFd, 10)
|
||||||
.ensureUnixCallResult { it == 0 }
|
.ensureUnixCallResult("listen") { it == 0 }
|
||||||
|
|
||||||
val commFd = accept(listenFd, null, null)
|
val commFd = accept(listenFd, null, null)
|
||||||
.ensureUnixCallResult { it >= 0 }
|
.ensureUnixCallResult("accept") { it >= 0 }
|
||||||
|
|
||||||
while (true) {
|
buffer.usePinned { pinned ->
|
||||||
val length = read(commFd, buffer, bufferLength)
|
while (true) {
|
||||||
.ensureUnixCallResult { it >= 0 }
|
val length = recv(commFd, pinned.addressOf(0), buffer.size, 0)
|
||||||
|
.ensureUnixCallResult("read") { it >= 0 }
|
||||||
|
|
||||||
if (length.toInt() == 0) {
|
if (length == 0) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
write(commFd, buffer, length)
|
send(commFd, prefixBuffer.refTo(0), prefixBuffer.size, 0)
|
||||||
.ensureUnixCallResult { it >= 0 }
|
.ensureUnixCallResult("write") { it >= 0 }
|
||||||
|
send(commFd, pinned.addressOf(0), length, 0)
|
||||||
|
.ensureUnixCallResult("write") { it >= 0 }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun Int.ensureUnixCallResult(predicate: (Int) -> Boolean): Int {
|
inline fun Int.ensureUnixCallResult(op: String, predicate: (Int) -> Boolean): Int {
|
||||||
if (!predicate(this)) {
|
if (!predicate(this)) {
|
||||||
throw Error(strerror(posix_errno())!!.toKString())
|
throw Error("$op: ${strerror(posix_errno())!!.toKString()}")
|
||||||
}
|
}
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun Long.ensureUnixCallResult(predicate: (Long) -> Boolean): Long {
|
inline fun Long.ensureUnixCallResult(op: String, predicate: (Long) -> Boolean): Long {
|
||||||
if (!predicate(this)) {
|
if (!predicate(this)) {
|
||||||
throw Error(strerror(posix_errno())!!.toKString())
|
throw Error("$op: ${strerror(posix_errno())!!.toKString()}")
|
||||||
}
|
}
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,6 +72,10 @@ class DefFile(val file:File?, val config:DefFileConfig, val manifestAddendProper
|
|||||||
properties.getSpaceSeparated("nonStrictEnums")
|
properties.getSpaceSeparated("nonStrictEnums")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val noStringConversion by lazy {
|
||||||
|
properties.getSpaceSeparated("noStringConversion")
|
||||||
|
}
|
||||||
|
|
||||||
val depends by lazy {
|
val depends by lazy {
|
||||||
properties.getSpaceSeparated("depends")
|
properties.getSpaceSeparated("depends")
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user