Search code examples
terminalposixkotlin-native

Kotlin-native execute command and get the output


I'd like to know if there's a way in kotlin native to call a command via posix and receive it's terminal output. For example, I'd like to get the "git diff" command working without having to create a temporary file, write output to it and then read from that file.

On SO I've only found solutions requiring ProcessBuilder, which isn't available on kotlin-native, as it's a Java library.


Solution

  • It's an improved version of exec command for Kotlin Native posted by mg-lolenstine, it throws an exception with command stderr instead of just returning exit(1) (which not always desirable behavior itself), also trim is now optional

    import kotlinx.cinterop.*
    import platform.posix.*
    
    fun executeCommand(
        command: String,
        trim: Boolean = true,
        redirectStderr: Boolean = true
    ): String {
        val commandToExecute = if (redirectStderr) "$command 2>&1" else command
        val fp = popen(commandToExecute, "r") ?: error("Failed to run command: $command")
    
        val stdout = buildString {
            val buffer = ByteArray(4096)
            while (true) {
                val input = fgets(buffer.refTo(0), buffer.size, fp) ?: break
                append(input.toKString())
            }
        }
    
        val status = pclose(fp)
        if (status != 0) {
            error("Command `$command` failed with status $status${if (redirectStderr) ": $stdout" else ""}")
        }
    
        return if (trim) stdout.trim() else stdout
    }