Forcola.Shim (forcola v0.2.0)

Copy Markdown View Source

Locates and speaks to the forcola_shim binary.

The shim is a Rust port program (source under native/forcola_shim). Release builds are published per target to GitHub Releases and fetched at compile time with SHA256 verification, so consumers need no Rust toolchain; a locally built binary in priv/ takes precedence during development.

Wire protocol (BEAM <-> shim), v0, documented in full in native/forcola_shim/src/main.rs:

Frames are {:packet, 4}-style: a 4-byte big-endian length prefix (handled by the Erlang port itself), then a 1-byte tag, then the payload. This module owns the tag constants and the JSON payload shapes for SPAWN/EXIT/ERROR; Forcola.run/2 drives the protocol.

Summary

Functions

Decodes an ERROR frame payload into its reason string.

Decodes an EXIT frame payload into {status_or_signal, timed_out}.

Encodes a SPAWN frame payload from Forcola.run/2 options.

Opens the shim binary as a port, framed with {:packet, 4}.

Absolute path to the shim binary for the current target.

Sends a tagged frame to the shim port.

Functions

decode_error(payload)

@spec decode_error(binary()) :: String.t()

Decodes an ERROR frame payload into its reason string.

decode_exit(payload)

@spec decode_exit(binary()) ::
  {non_neg_integer() | {:signal, non_neg_integer()}, boolean()}

Decodes an EXIT frame payload into {status_or_signal, timed_out}.

encode_spawn(argv, opts)

@spec encode_spawn(
  term(),
  keyword()
) :: binary()

Encodes a SPAWN frame payload from Forcola.run/2 options.

Shared by all four modes. Besides :cd/:env/:merge_stderr/:timeout_ms/ :kill_grace_ms and the pty options, it threads :user and :group (each a string name or an integer id) through to the shim so the child can be run as a different user; see Forcola.run/2 for the semantics.

open()

@spec open() :: {:ok, port()} | {:error, :not_found}

Opens the shim binary as a port, framed with {:packet, 4}.

The caller owns the returned port: send it SPAWN/STDIN/EOF/KILL frames via send_frame/2 and receive {port, {:data, <<tag, payload::binary>>}} messages for STDOUT/STDERR/EXIT/ERROR frames.

path()

@spec path() :: {:ok, Path.t()} | {:error, :not_found}

Absolute path to the shim binary for the current target.

Returns {:error, :not_found} if no binary has been built or downloaded yet.

send_frame(port, tag, payload \\ "")

@spec send_frame(port(), non_neg_integer(), iodata()) :: true

Sends a tagged frame to the shim port.