lyng/docs/lyng.io.process.md

4.7 KiB

lyng.io.process — Process execution and control for Lyng scripts

This module provides a way to run external processes and shell commands from Lyng scripts. It is designed to be multiplatform and uses coroutines for non-blocking execution.

Note: lyngio is a separate library module. It must be explicitly added as a dependency to your host application and initialized in your Lyng scopes.


Add the library to your project (Gradle)

If you use this repository as a multi-module project, add a dependency on :lyngio:

dependencies {
    implementation("net.sergeych:lyngio:0.0.1-SNAPSHOT")
}

For external projects, ensure you have the appropriate Maven repository configured (see lyng.io.fs documentation).


Install the module into a Lyng session

The process module is not installed automatically. The preferred host runtime is EvalSession: create the session, get its underlying scope, install the module there, and execute scripts through the session. You can customize access control via ProcessAccessPolicy.

Kotlin (host) bootstrap example:

import net.sergeych.lyng.Scope
import net.sergeych.lyng.EvalSession
import net.sergeych.lyng.io.process.createProcessModule
import net.sergeych.lyngio.process.security.PermitAllProcessAccessPolicy

suspend fun bootstrapProcess() {
    val session = EvalSession()
    val scope: Scope = session.getScope()
    createProcessModule(PermitAllProcessAccessPolicy, scope)

    // In scripts (or via session.eval), import the module:
    session.eval("import lyng.io.process")
}

Using from Lyng scripts

import lyng.io.process

// Execute a process with arguments
val p = Process.execute("ls", ["-l", "/tmp"])
for (line in p.stdout) {
    println("OUT: " + line)
}
val exitCode = p.waitFor()
println("Process exited with: " + exitCode)

// Run a shell command
val sh = Process.shell("echo 'Hello from shell' | wc -w")
for (line in sh.stdout) {
    println("Word count: " + line.trim())
}

// Platform information
val details = Platform.details()
println("OS: " + details.name + " " + details.version + " (" + details.arch + ")")
if (details.kernelVersion != null) {
    println("Kernel: " + details.kernelVersion)
}

if (Platform.isSupported()) {
    println("Processes are supported!")
}

API Reference

Process (static methods)
  • execute(executable: String, args: List<String>): RunningProcess — Start an external process.
  • shell(command: String): RunningProcess — Run a command through the system shell (e.g., /bin/sh or cmd.exe).
RunningProcess (instance methods)
  • stdout: Flow — Standard output stream as a Lyng Flow of lines.
  • stderr: Flow — Standard error stream as a Lyng Flow of lines.
  • waitFor(): Int — Wait for the process to exit and return the exit code.
  • signal(name: String) — Send a signal to the process (e.g., "SIGINT", "SIGTERM", "SIGKILL").
  • destroy() — Forcefully terminate the process.
Platform (static methods)
  • details(): Map — Get platform details. Returned map keys: name, version, arch, kernelVersion.
  • isSupported(): Bool — True if process execution is supported on the current platform.

Security Policy

Process execution is a sensitive operation. lyngio uses ProcessAccessPolicy to control access to execute and shell operations.

  • ProcessAccessPolicy — Interface for custom policies.
  • PermitAllProcessAccessPolicy — Allows all operations.
  • ProcessAccessOp (sealed) — Operations to check:
    • Execute(executable, args)
    • Shell(command)

Example of a restricted policy in Kotlin:

import net.sergeych.lyngio.fs.security.AccessDecision
import net.sergeych.lyngio.fs.security.Decision
import net.sergeych.lyngio.process.security.ProcessAccessOp
import net.sergeych.lyngio.process.security.ProcessAccessPolicy

val restrictedPolicy = object : ProcessAccessPolicy {
    override suspend fun check(op: ProcessAccessOp, ctx: AccessContext): AccessDecision {
        return when (op) {
            is ProcessAccessOp.Execute -> {
                if (op.executable == "ls") AccessDecision(Decision.Allow)
                else AccessDecision(Decision.Deny, "Only 'ls' is allowed")
            }
            is ProcessAccessOp.Shell -> AccessDecision(Decision.Deny, "Shell is forbidden")
        }
    }
}
createProcessModule(restrictedPolicy, scope)

Platform Support

  • JVM: Full support using ProcessBuilder.
  • Native (Linux/macOS): Support via POSIX.
  • Windows: Support planned.
  • Android/JS/iOS/Wasm: Currently not supported; isSupported() returns false and attempts to run processes will throw UnsupportedOperationException.