Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Process.exitCodeOrNull #112

Merged
merged 1 commit into from
Jun 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion library/process/api/process.api
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,8 @@ public abstract class io/matthewnelson/kmp/process/Process : io/matthewnelson/km
public final field startTime Lkotlin/time/ComparableTimeMark;
public final field stdio Lio/matthewnelson/kmp/process/Stdio$Config;
public abstract fun destroy ()Lio/matthewnelson/kmp/process/Process;
public abstract fun exitCode ()I
public final fun exitCode ()I
public abstract fun exitCodeOrNull ()Ljava/lang/Integer;
public final fun isAlive ()Z
public abstract fun pid ()I
public final fun toString ()Ljava/lang/String;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,18 +142,21 @@ public abstract class Process internal constructor(
* not exited yet
* */
@Throws(IllegalStateException::class)
public abstract fun exitCode(): Int
public fun exitCode(): Int = exitCodeOrNull()
?: throw IllegalStateException("Process hasn't exited")

/**
* Returns the exit code for which the process
* completed with, or `null` if it has not
* exited yet.
* */
public abstract fun exitCodeOrNull(): Int?

/**
* Checks if the [Process] is still running
* */
@get:JvmName("isAlive")
public val isAlive: Boolean get() = try {
exitCode()
false
} catch (_: IllegalStateException) {
true
}
public val isAlive: Boolean get() = exitCodeOrNull() == null

/**
* Returns the [Process] identifier (PID).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
package io.matthewnelson.kmp.process.internal

import io.matthewnelson.kmp.process.Process
import io.matthewnelson.kmp.process.Stdio
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.InvocationKind
import kotlin.contracts.contract
Expand All @@ -42,17 +41,16 @@ internal inline fun Process.commonWaitFor(
var remainingNanos = timeout.inWholeNanoseconds

do {
try {
return exitCode()
} catch (_: IllegalStateException) {
if (remainingNanos > 0) {
val millis = min(
(remainingNanos.nanoseconds.inWholeMilliseconds + 1).toDouble(),
100.0
).toLong().milliseconds

sleep(millis)
}
val code = exitCodeOrNull()
if (code != null) return code

if (remainingNanos > 0) {
val millis = min(
(remainingNanos.nanoseconds.inWholeMilliseconds + 1).toDouble(),
100.0
).toLong().milliseconds

sleep(millis)
}

remainingNanos = (timeout - startMark.elapsedNow()).inWholeNanoseconds
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,7 @@ internal class NodeJsProcess internal constructor(
return this
}

// @Throws(IllegalStateException::class)
override fun exitCode(): Int {
override fun exitCodeOrNull(): Int? {
_exitCode?.let { return it }

jsProcess.exitCode?.toInt()?.let {
Expand All @@ -123,7 +122,7 @@ internal class NodeJsProcess internal constructor(
return code
}

return _exitCode ?: throw IllegalStateException("Process hasn't exited")
return _exitCode
}

override fun pid(): Int {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,18 +99,18 @@ internal class JvmProcess private constructor(
}

_stdinThread?.let { thread ->
_stdinThread = null
if (thread.isInterrupted) return@let
thread.interrupt()
}

return this
}

@Throws(IllegalStateException::class)
override fun exitCode(): Int = try {
override fun exitCodeOrNull(): Int? = try {
jProcess.exitValue().correctExitCode()
} catch (_: IllegalThreadStateException) {
throw IllegalStateException("Process hasn't exited")
null
}

override fun pid(): Int = _pid
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,7 @@ internal constructor(
this
}

@Throws(IllegalStateException::class)
override fun exitCode(): Int {
override fun exitCodeOrNull(): Int? {
_exitCode.value?.let { return it }

@OptIn(ExperimentalForeignApi::class)
Expand All @@ -156,14 +155,11 @@ internal constructor(

_exitCode.compareAndSet(null, code)
}
else -> {
val message = strerror(errno)?.toKString() ?: "errno: $errno"
throw IllegalStateException(message)
}
else -> {}
}
}

return _exitCode.value ?: throw IllegalStateException("Process hasn't exited")
return _exitCode.value
}

override fun pid(): Int = pid
Expand Down
Loading