readLine() in native returns null

I am trying to start an interactive shell for my Kotlin/Native test app, but get null when I write input using readLine(). (It works in Kotlin/Jvm :sweat_smile:)

// Main.kt
fun main() {
    println("Tell your name:")
    val name = readLine()
    println("Hello, $name!")
}
// build.gradle.kts
plugins {
    kotlin("multiplatform") version "1.6.10"
}

group = "angelos"
version = "1.0"

repositories {
    mavenCentral()
}

kotlin {
    val hostOs = System.getProperty("os.name")
    val isMingwX64 = hostOs.startsWith("Windows")
    val nativeTarget = when {
        hostOs == "Mac OS X" -> macosX64("native")
        hostOs == "Linux" -> linuxX64("native")
        isMingwX64 -> mingwX64("native")
        else -> throw GradleException("Host OS is not supported in Kotlin/Native.")
    }

    nativeTarget.apply {
        binaries {
            executable {
                entryPoint = "main"
                runTask!!.standardInput = System.`in`
            }
        }
    }
    sourceSets {
        val nativeMain by getting
        val nativeTest by getting
    }
}

Skärmavbild 2022-04-02 kl. 18.33.41

Not sure of the bug there, but just FYI it isn’t returning null, it is returning an empty string "" because null.toString() evaluates to "null"

1 Like

I tried a second time to run this example. If I type the text directly at prompt, I will have to press enter twice before readLine() returns, then It returns the last row which is empty.

When I press enter first, and then write my text, and then enter, it will catch the line. So [Enter] [Some text] [Enter] works, but not [Some text] [Enter] [Enter].

Why is their a need for an extra enter?

1 Like

Are you sure the code you’re running is exactly this?:

fun main() {
    println("Tell your name:")
    val name = readLine()
    println("Hello, $name!")
}

My guess would be that there’s an extra readLine in your code somewhere which might be causing the issue

Yes

The solution is to run it from the terminal solution:

./gradlew -q --console=plain runReleaseExecutableNative

Then it works!

Yeah, it’s usual problem with Gradle which also interacts with the console.
If your app is an interactive console app I would recommend assembling it first and run executable directly, you always wrap it to a script

2 Likes