lyng/docs/lyng.io.process.md

4.6 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 Scope

The process module is not installed automatically. You must explicitly register it in the scope’s ImportManager using createProcessModule. You can customize access control via ProcessAccessPolicy.

Kotlin (host) bootstrap example:

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

// ... inside a suspend function or runBlocking
val scope: Scope = Script.newScope()
createProcessModule(PermitAllProcessAccessPolicy, scope)

// In scripts (or via scope.eval), import the module:
scope.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.