Fix socket example on POSIX (#966)

This commit is contained in:
Nikolay Igotti
2017-10-23 14:15:28 +03:00
committed by GitHub
parent 85a782cd7e
commit 2dde9eda55
11 changed files with 84 additions and 25 deletions
@@ -26,5 +26,6 @@ class InteropConfiguration(
val pkgName: String,
val excludedFunctions: Set<String>,
val strictEnums: Set<String>,
val nonStrictEnums: Set<String>
val nonStrictEnums: Set<String>,
val noStringConversion: Set<String>
)
@@ -57,6 +57,10 @@ class StubGenerator(
val excludedFunctions: Set<String>
get() = configuration.excludedFunctions
val noStringConversion: Set<String>
get() = configuration.noStringConversion
val platformWStringTypes = setOf("LPCWSTR")
/**
@@ -305,10 +309,11 @@ class StubGenerator(
return false
}
fun representCFunctionParameterAsString(type: Type): Boolean {
fun representCFunctionParameterAsString(function: FunctionDecl, type: Type): Boolean {
val unwrappedType = type.unwrapTypedefs()
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.
@@ -612,7 +617,7 @@ class StubGenerator(
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())
bodyGenerator.pushMemScoped()
"$parameterName?.cstr?.getPointer(memScope)"
@@ -310,7 +310,8 @@ private fun processLib(args: Map<String, List<String>>,
pkgName = outKtPkg,
excludedFunctions = excludedFunctions,
strictEnums = def.config.strictEnums.toSet(),
nonStrictEnums = def.config.nonStrictEnums.toSet()
nonStrictEnums = def.config.nonStrictEnums.toSet(),
noStringConversion = def.config.noStringConversion.toSet()
)
val nativeIndex = buildNativeIndex(library)
+7
View File
@@ -26,4 +26,11 @@ static int posix_errno() {
// Wrapper to access h_errno variable.
static int posix_h_errno() {
return h_errno;
}
static int init_sockets() {
return 0;
}
static void deinit_sockets() {
}
+7
View File
@@ -26,3 +26,10 @@ static int posix_errno() {
static int posix_h_errno() {
return h_errno;
}
static int init_sockets() {
return 0;
}
static void deinit_sockets() {
}
+7
View File
@@ -62,3 +62,10 @@ static void posix_FD_SET(int bit, fd_set *set) {
static int posix_FD_ISSET(int bit, fd_set *set) {
return FD_ISSET(bit, set);
}
static int init_sockets() {
return 0;
}
static void deinit_sockets() {
}
+7
View File
@@ -48,3 +48,10 @@ static void posix_FD_SET(int bit, fd_set *set) {
static int posix_FD_ISSET(int bit, fd_set *set) {
return FD_ISSET(bit, set);
}
static int init_sockets() {
return 0;
}
static void deinit_sockets() {
}
+15 -2
View File
@@ -1,6 +1,8 @@
package = platform.posix
headers = stdio.h Windef.h Winsock2.h Ws2tcpip.h Ws2def.h io.h math.h
compilerOpts = -DUNICODE -Wno-incompatible-pointer-types -Wno-deprecated-declarations
headers = stdio.h winsock.h io.h math.h
compilerOpts = -DUNICODE -DWINVER=0x0601 -D_WIN32_WINNT=0x0601 -DWINAPI_FAMILY=3 \
-Wno-incompatible-pointer-types -Wno-deprecated-declarations
noStringConversion = send recv
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) {
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;
}
+2 -1
View File
@@ -1,6 +1,7 @@
package = platform.windows
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 \
-Wno-incompatible-pointer-types -Wno-deprecated-declarations
linkerOpts = -lcomctl32 -lcrypt32 -lshlwapi -lshell32 -limm32 -lusp10 -lwininet
depends = posix
+23 -17
View File
@@ -25,55 +25,61 @@ fun main(args: Array<String>) {
val port = args[0].toShort()
// Initialize sockets in platform-dependent way.
init_sockets()
memScoped {
val bufferLength = 100L
val buffer = allocArray<ByteVar>(bufferLength)
val buffer = ByteArray(1024)
val prefixBuffer = kotlin.text.toUtf8Array("echo: ", 0, 6)
val serverAddr = alloc<sockaddr_in>()
val listenFd = socket(AF_INET, SOCK_STREAM, 0)
.ensureUnixCallResult { it >= 0 }
.ensureUnixCallResult("socket") { it >= 0 }
with(serverAddr) {
memset(this.ptr, 0, sockaddr_in.size)
sin_family = AF_INET.narrow()
sin_addr.s_addr = posix_htons(0).toInt()
sin_port = posix_htons(port)
}
bind(listenFd, serverAddr.ptr.reinterpret(), sockaddr_in.size.toInt())
.ensureUnixCallResult { it == 0 }
.ensureUnixCallResult("bind") { it == 0 }
listen(listenFd, 10)
.ensureUnixCallResult { it == 0 }
.ensureUnixCallResult("listen") { it == 0 }
val commFd = accept(listenFd, null, null)
.ensureUnixCallResult { it >= 0 }
.ensureUnixCallResult("accept") { it >= 0 }
while (true) {
val length = read(commFd, buffer, bufferLength)
.ensureUnixCallResult { it >= 0 }
buffer.usePinned { pinned ->
while (true) {
val length = recv(commFd, pinned.addressOf(0), buffer.size, 0)
.ensureUnixCallResult("read") { it >= 0 }
if (length.toInt() == 0) {
if (length == 0) {
break
}
write(commFd, buffer, length)
.ensureUnixCallResult { it >= 0 }
send(commFd, prefixBuffer.refTo(0), prefixBuffer.size, 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)) {
throw Error(strerror(posix_errno())!!.toKString())
throw Error("$op: ${strerror(posix_errno())!!.toKString()}")
}
return this
}
inline fun Long.ensureUnixCallResult(predicate: (Long) -> Boolean): Long {
inline fun Long.ensureUnixCallResult(op: String, predicate: (Long) -> Boolean): Long {
if (!predicate(this)) {
throw Error(strerror(posix_errno())!!.toKString())
throw Error("$op: ${strerror(posix_errno())!!.toKString()}")
}
return this
}
@@ -72,6 +72,10 @@ class DefFile(val file:File?, val config:DefFileConfig, val manifestAddendProper
properties.getSpaceSeparated("nonStrictEnums")
}
val noStringConversion by lazy {
properties.getSpaceSeparated("noStringConversion")
}
val depends by lazy {
properties.getSpaceSeparated("depends")
}