NAME

Linux::Event::Fork - Minimal async child spawning on top of Linux::Event

SYNOPSIS

use v5.36;
use Linux::Event;
use Linux::Event::Fork;   # installs $loop->fork

my $loop = Linux::Event->new;

$loop->fork(
  tag => "job:42",

  cmd => [ $^X, '-we', 'print "hello\n"; exit 0' ],

  on_stdout => sub ($child, $chunk) {
    print "[stdout] $chunk";
  },

  on_exit => sub ($child, $exit) {
    say "pid=" . $child->pid . " code=" . ($exit->exited ? $exit->code : 'n/a');
    $loop->stop;
  },
);

$loop->run;

DESCRIPTION

Linux::Event::Fork is a small policy-layer helper built on top of Linux::Event. It installs an opt-in method $loop->fork(...) into Linux::Event::Loop.

It uses only public primitives:

  • $loop->watch(...) for pipes

  • $loop->pid(...) for exit observation

  • $loop->after(...) for timeouts

Constraints

  • No restarts/backoff.

  • No hidden ownership of user resources.

  • Explicit, idempotent teardown.

  • Drain-first: on_exit fires only after exit is observed and captured pipes reach EOF.

SPAWN ARGUMENTS

Exactly one of cmd or child is required.

cmd

cmd => [ $program, @argv ]

Uses exec. If exec fails, the child exits 127 and writes a short diagnostic to STDERR.

child

child => sub { ... }

Runs a Perl callback in the child after stdio plumbing and setup options are applied. Typically you call exec from inside the callback.

If the callback throws an exception or returns normally, the child exits 127 and writes a best-effort diagnostic to STDERR.

Output capture

on_stdout => sub ($child, $chunk) { ... }
on_stderr => sub ($child, $chunk) { ... }

$chunk is raw bytes from sysread(); it is not line-oriented and may split arbitrarily. Buffer in user code if you want line/message framing.

By default, stdout/stderr pipes are only created if their callback is provided.

Override with:

capture_stdout => 1|0
capture_stderr => 1|0

Enabling capture without a callback drains and discards output so the child cannot block on a full pipe.

Exit

on_exit => sub ($child, $exit) { ... }

$exit is a Linux::Event::Fork::Exit object.

Stdin

One-shot stdin bytes

stdin => $bytes

Creates a pipe, writes the bytes, and closes stdin.

Streaming stdin with backpressure

stdin_pipe => 1

Creates a pipe and keeps it open. Stream with:

$child->stdin_write($bytes);
$child->close_stdin;

Writes are non-blocking and backpressure-aware.

SIGPIPE is ignored during writes and EPIPE is treated as a normal close condition.

Minimal timeout

timeout    => $seconds,
on_timeout => sub ($child) { ... },   # optional

When the timer fires and the child has not yet exited:

1. Calls on_timeout (if provided)
2. Sends TERM to the child once

No escalation and no restart policy.

Child setup options

Applied in the child after stdio plumbing and before exec/callback:

cwd       => "/path"
umask     => 027
env       => { KEY => "value", ... }   # overlays onto inherited %ENV
clear_env => 1                         # start with empty %ENV before overlay

Metadata

tag  => $label
data => $opaque

Both are stored on the returned handle.

RETURN VALUE

Returns a Linux::Event::Fork::Child handle.

SEE ALSO

Linux::Event, Linux::Event::Fork::Child, Linux::Event::Fork::Exit

AUTHOR

Joshua S. Day (HAX)

LICENSE

Same terms as Perl itself.