wasm-posix-host
    Preparing search index...

    Interface CentralizedKernelCallbacks

    Callbacks for fork/exec/exit handling.

    interface CentralizedKernelCallbacks {
        onClone?: (attachment: ThreadChannelAttachment) => Promise<void>;
        onExec?: (
            pid: number,
            path: string,
            argv: string[],
            envp: string[],
            callerTid: number,
        ) => Promise<number>;
        onExit?: (pid: number, exitStatus: number) => void;
        onExitGroup?: (pid: number) => void;
        onFork?: (request: ForkLaunchRequest) => Promise<number[]>;
        onProcessMemoryTarget?: (memory: Memory, target: object) => void;
        onResolveSpawn?: (
            path: string,
            argv: string[],
        ) => Promise<SpawnProgramResolution | null>;
        onSpawn?: (
            parentPid: number,
            childPid: number,
            program: ResolvedSpawnProgram,
            envp: string[],
        ) => Promise<number>;
        onThreadExit?: (pid: number, tid: number, channelOffset: number) => boolean;
    }
    Index

    Properties

    onClone?: (attachment: ThreadChannelAttachment) => Promise<void>

    Called when a process calls clone (thread creation). The callback should spawn a thread Worker sharing the parent's Memory. The Rust kernel has already allocated the task identity. The host creates a one-shot transport proof bound to that exact clone result; the callback may read its fields for Worker initialization, then must consume it with attachThreadChannel. It cannot supply or replace the PID/TID.

    onExec?: (
        pid: number,
        path: string,
        argv: string[],
        envp: string[],
        callerTid: number,
    ) => Promise<number>

    Called when a process calls execve. The callback should resolve the program path, terminate the old Worker, create a new Worker with the new binary, and attach its channels to the existing kernel Process. Returns 0 on success, negative errno on error.

    onExit?: (pid: number, exitStatus: number) => void

    Called when a process exits.

    onExitGroup?: (pid: number) => void

    Called when a process calls exit_group (terminate all threads). The callback should forcefully terminate all thread workers for the process. Called BEFORE the process exit is processed.

    onFork?: (request: ForkLaunchRequest) => Promise<number[]>

    Called when a process forks. The kernel has already cloned the Process in its ProcessTable. The callback should spawn a child Worker with a copy of the parent's Memory and register it with the kernel. Returns the channel offsets allocated for the child.

    request.continuation.kind is "thread" when the parent issued the fork() syscall from a pthread-created thread (i.e. on a channel registered through a host-side ThreadChannelAttachment bound to the kernel's exact clone result, with tid > 0). The host must:

    • use the thread's forkBufAddr (not the main channel's) for the child's rewind so the saved frames + saved __tls_base / __stack_pointer match what the parent thread populated, and
    • have the child Worker enter the thread function (fnPtr/argPtr) directly instead of _start — _start is not in the thread's fork-path call chain and rewinding through it would never reach the saved fork() call site.

    Main-thread and pthread forks both carry the authoritative linked continuation address in request.continuation.forkBufAddr.

    onProcessMemoryTarget?: (memory: Memory, target: object) => void

    Observe an object in the persistent kernel realm that can retain one process-memory generation. The allocator uses this only for bounded weak retirement telemetry; explicit generation teardown remains authoritative.

    onResolveSpawn?: (
        path: string,
        argv: string[],
    ) => Promise<SpawnProgramResolution | null>

    Pre-flight resolution step for SYS_SPAWN. Returns the validated program bytes, their compiled module, and launch argv for path, { errno } for a located but unlaunchable program, or null for ENOENT. Must NOT have side effectshandleSpawn calls this BEFORE kernel_spawn_process so that file actions never run on a doomed PATH-iteration. POSIX requires file_actions to run "exactly once," and posix_spawnp's PATH-walk issues one posix_spawn per candidate; without this preflight the kernel applies file_actions on every failed iteration (sortix basic/spawn/posix_spawnp exercises an addopen(O_EXCL) "once" file that would conflict on iteration 2).

    Required if onSpawn is set; together they form the spawn surface.

    onSpawn?: (
        parentPid: number,
        childPid: number,
        program: ResolvedSpawnProgram,
        envp: string[],
    ) => Promise<number>

    Launch a worker for the spawned child with the already-resolved bytes, compiled module, and argv from onResolveSpawn. The kernel has constructed the child Process descriptor under childPid with parentPid as its authoritative parent and applied file actions + attrs by the time this is called. The callback instantiates a fresh Worker and attaches its channels to the Process the kernel already created.

    Returns 0 on success, negative errno on failure. On non-zero return the kernel descriptor is rolled back via kernel_remove_process.

    Distinct from onExec (which replaces the calling worker) and onFork (which clones the parent's Memory): onSpawn always creates a fresh Memory and runs the new program from _start.

    onThreadExit?: (pid: number, tid: number, channelOffset: number) => boolean

    Called after a pthread channel reaches SYS_EXIT and the kernel worker has performed the musl clear-TID wake and completed the exit channel. The host may now terminate the backing Worker without leaving its channel waiter attached to a slot that will later be reused.