[samples] samples uses platform libs
This commit is contained in:
committed by
Vasily Levchenko
parent
3777d86be2
commit
c90985ea8a
@@ -1,11 +1,5 @@
|
|||||||
apply plugin: 'konan'
|
apply plugin: 'konan'
|
||||||
|
|
||||||
konanInterop {
|
|
||||||
stdio { }
|
|
||||||
}
|
|
||||||
|
|
||||||
konanArtifacts {
|
konanArtifacts {
|
||||||
CsvParser {
|
CsvParser
|
||||||
useInterop 'stdio'
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
headers = stdio.h stdlib.h string.h
|
|
||||||
compilerOpts = -D_ANSI_SOURCE
|
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import kotlinx.cinterop.*
|
import kotlinx.cinterop.*
|
||||||
import stdio.*
|
import posix.*
|
||||||
|
|
||||||
fun parseLine(line: String, separator: Char) : List<String> {
|
fun parseLine(line: String, separator: Char) : List<String> {
|
||||||
val result = mutableListOf<String>()
|
val result = mutableListOf<String>()
|
||||||
|
|||||||
@@ -1,11 +1,5 @@
|
|||||||
apply plugin: 'konan'
|
apply plugin: 'konan'
|
||||||
|
|
||||||
konanInterop {
|
|
||||||
sockets { }
|
|
||||||
}
|
|
||||||
|
|
||||||
konanArtifacts {
|
konanArtifacts {
|
||||||
EchoServer {
|
EchoServer
|
||||||
useInterop "sockets"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,24 +0,0 @@
|
|||||||
headers = sys/socket.h sys/errno.h sys/select.h fcntl.h netdb.h stdio.h string.h unistd.h stdlib.h netinet/in.h
|
|
||||||
excludeDependentModules.osx = true
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
static int interop_errno() {
|
|
||||||
return errno;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int interop_htons(int x) {
|
|
||||||
return htons(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void interop_FD_ZERO(fd_set *set) {
|
|
||||||
FD_ZERO(set);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void interop_FD_SET(int bit, fd_set *set) {
|
|
||||||
FD_SET(bit, set);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int interop_FD_ISSET(int bit, fd_set *set) {
|
|
||||||
return FD_ISSET(bit, set);
|
|
||||||
}
|
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import kotlinx.cinterop.*
|
import kotlinx.cinterop.*
|
||||||
import sockets.*
|
import posix.*
|
||||||
import kotlin.coroutines.experimental.*
|
import kotlin.coroutines.experimental.*
|
||||||
import kotlin.coroutines.experimental.intrinsics.*
|
import kotlin.coroutines.experimental.intrinsics.*
|
||||||
|
|
||||||
@@ -37,8 +37,8 @@ fun main(args: Array<String>) {
|
|||||||
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 = htons(0).toInt()
|
sin_addr.s_addr = posix_htons(0).toInt()
|
||||||
sin_port = 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())
|
||||||
@@ -93,7 +93,7 @@ class Client(val clientFd: Int, val waitingList: MutableMap<Int, WaitingFor>) {
|
|||||||
val length = read(clientFd, data, dataLength)
|
val length = read(clientFd, data, dataLength)
|
||||||
if (length >= 0)
|
if (length >= 0)
|
||||||
return length
|
return length
|
||||||
if (errno != EWOULDBLOCK)
|
if (posix_errno() != EWOULDBLOCK)
|
||||||
throw IOException(getUnixError())
|
throw IOException(getUnixError())
|
||||||
// Save continuation and suspend.
|
// Save continuation and suspend.
|
||||||
return suspendCoroutineOrReturn { continuation ->
|
return suspendCoroutineOrReturn { continuation ->
|
||||||
@@ -106,7 +106,7 @@ class Client(val clientFd: Int, val waitingList: MutableMap<Int, WaitingFor>) {
|
|||||||
val written = write(clientFd, data, length)
|
val written = write(clientFd, data, length)
|
||||||
if (written >= 0)
|
if (written >= 0)
|
||||||
return
|
return
|
||||||
if (errno != EWOULDBLOCK)
|
if (posix_errno() != EWOULDBLOCK)
|
||||||
throw IOException(getUnixError())
|
throw IOException(getUnixError())
|
||||||
// Save continuation and suspend.
|
// Save continuation and suspend.
|
||||||
return suspendCoroutineOrReturn { continuation ->
|
return suspendCoroutineOrReturn { continuation ->
|
||||||
@@ -130,23 +130,25 @@ fun acceptClientsAndRun(serverFd: Int, block: suspend Client.() -> Unit) {
|
|||||||
val errorfds = alloc<fd_set>()
|
val errorfds = alloc<fd_set>()
|
||||||
var maxfd = serverFd
|
var maxfd = serverFd
|
||||||
while (true) {
|
while (true) {
|
||||||
FD_ZERO(readfds)
|
posix_FD_ZERO(readfds.ptr)
|
||||||
FD_ZERO(writefds)
|
posix_FD_ZERO(writefds.ptr)
|
||||||
FD_ZERO(errorfds)
|
posix_FD_ZERO(errorfds.ptr)
|
||||||
for ((socketFd, watingFor) in waitingList) {
|
for ((socketFd, watingFor) in waitingList) {
|
||||||
when (watingFor) {
|
when (watingFor) {
|
||||||
is WaitingFor.Accept -> FD_SET(socketFd, readfds)
|
is WaitingFor.Accept -> posix_FD_SET(socketFd, readfds.ptr)
|
||||||
is WaitingFor.Read -> FD_SET(socketFd, readfds)
|
is WaitingFor.Read -> posix_FD_SET(socketFd, readfds.ptr)
|
||||||
is WaitingFor.Write -> FD_SET(socketFd, writefds)
|
is WaitingFor.Write -> posix_FD_SET(socketFd, writefds.ptr)
|
||||||
}
|
}
|
||||||
FD_SET(socketFd, errorfds)
|
posix_FD_SET(socketFd, errorfds.ptr)
|
||||||
}
|
}
|
||||||
pselect(maxfd + 1, readfds.ptr, writefds.ptr, errorfds.ptr, null, null)
|
pselect(maxfd + 1, readfds.ptr, writefds.ptr, errorfds.ptr, null, null)
|
||||||
.ensureUnixCallResult { it >= 0 }
|
.ensureUnixCallResult { it >= 0 }
|
||||||
loop@for (socketFd in 0..maxfd) {
|
loop@for (socketFd in 0..maxfd) {
|
||||||
val waitingFor = waitingList[socketFd]
|
val waitingFor = waitingList[socketFd]
|
||||||
val errorOccured = FD_ISSET(socketFd, errorfds)
|
val errorOccured = posix_FD_ISSET(socketFd, errorfds.ptr) != 0
|
||||||
if (FD_ISSET(socketFd, readfds) || FD_ISSET(socketFd, writefds) || errorOccured) {
|
if (posix_FD_ISSET(socketFd, readfds.ptr) != 0
|
||||||
|
|| posix_FD_ISSET(socketFd, writefds.ptr) != 0
|
||||||
|
|| errorOccured) {
|
||||||
when (waitingFor) {
|
when (waitingFor) {
|
||||||
is WaitingFor.Accept -> {
|
is WaitingFor.Accept -> {
|
||||||
if (errorOccured)
|
if (errorOccured)
|
||||||
@@ -155,7 +157,7 @@ fun acceptClientsAndRun(serverFd: Int, block: suspend Client.() -> Unit) {
|
|||||||
// Accept new client.
|
// Accept new client.
|
||||||
val clientFd = accept(serverFd, null, null)
|
val clientFd = accept(serverFd, null, null)
|
||||||
if (clientFd < 0) {
|
if (clientFd < 0) {
|
||||||
if (errno != EWOULDBLOCK)
|
if (posix_errno() != EWOULDBLOCK)
|
||||||
throw Error(getUnixError())
|
throw Error(getUnixError())
|
||||||
break@loop
|
break@loop
|
||||||
}
|
}
|
||||||
@@ -196,18 +198,7 @@ fun acceptClientsAndRun(serverFd: Int, block: suspend Client.() -> Unit) {
|
|||||||
|
|
||||||
class IOException(message: String): RuntimeException(message)
|
class IOException(message: String): RuntimeException(message)
|
||||||
|
|
||||||
val errno: Int
|
fun getUnixError() = strerror(posix_errno())!!.toKString()
|
||||||
get() = interop_errno()
|
|
||||||
|
|
||||||
fun FD_ZERO(set: fd_set): Unit = interop_FD_ZERO(set.ptr)
|
|
||||||
|
|
||||||
fun FD_SET(bit: Int, set: fd_set): Unit = interop_FD_SET(bit, set.ptr)
|
|
||||||
|
|
||||||
fun FD_ISSET(bit: Int, set: fd_set) = interop_FD_ISSET(bit, set.ptr) != 0
|
|
||||||
|
|
||||||
fun htons(value: Short) = interop_htons(value.toInt()).toShort()
|
|
||||||
|
|
||||||
fun getUnixError() = strerror(errno)!!.toKString()
|
|
||||||
|
|
||||||
inline fun Int.ensureUnixCallResult(predicate: (Int) -> Boolean): Int {
|
inline fun Int.ensureUnixCallResult(predicate: (Int) -> Boolean): Int {
|
||||||
if (!predicate(this)) {
|
if (!predicate(this)) {
|
||||||
|
|||||||
@@ -1,11 +1,5 @@
|
|||||||
apply plugin: 'konan'
|
apply plugin: 'konan'
|
||||||
|
|
||||||
konanInterop {
|
|
||||||
sockets { }
|
|
||||||
}
|
|
||||||
|
|
||||||
konanArtifacts {
|
konanArtifacts {
|
||||||
EchoServer {
|
EchoServer
|
||||||
useInterop "sockets"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import kotlinx.cinterop.*
|
import kotlinx.cinterop.*
|
||||||
import sockets.*
|
import posix.*
|
||||||
|
|
||||||
fun main(args: Array<String>) {
|
fun main(args: Array<String>) {
|
||||||
if (args.size < 1) {
|
if (args.size < 1) {
|
||||||
@@ -37,8 +37,8 @@ fun main(args: Array<String>) {
|
|||||||
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 = htons(0).toInt()
|
sin_addr.s_addr = posix_htons(0).toInt()
|
||||||
sin_port = 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())
|
||||||
@@ -64,21 +64,16 @@ fun main(args: Array<String>) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val errno: Int
|
|
||||||
get() = interop_errno()
|
|
||||||
|
|
||||||
fun htons(value: Short) = interop_htons(value.toInt()).toShort()
|
|
||||||
|
|
||||||
inline fun Int.ensureUnixCallResult(predicate: (Int) -> Boolean): Int {
|
inline fun Int.ensureUnixCallResult(predicate: (Int) -> Boolean): Int {
|
||||||
if (!predicate(this)) {
|
if (!predicate(this)) {
|
||||||
throw Error(strerror(errno)!!.toKString())
|
throw Error(strerror(posix_errno())!!.toKString())
|
||||||
}
|
}
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun Long.ensureUnixCallResult(predicate: (Long) -> Boolean): Long {
|
inline fun Long.ensureUnixCallResult(predicate: (Long) -> Boolean): Long {
|
||||||
if (!predicate(this)) {
|
if (!predicate(this)) {
|
||||||
throw Error(strerror(errno)!!.toKString())
|
throw Error(strerror(posix_errno())!!.toKString())
|
||||||
}
|
}
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user