# `Linx.Seccomp.Builder`
[🔗](https://github.com/oshlabs/linx/blob/v0.2.0/lib/linx/seccomp/builder.ex#L1)

Fluent builder DSL for `%Linx.Seccomp.Filter{}`.

Sugar over `Linx.Seccomp.from_rules/1` — the rules are accumulated
in the builder and compiled to BPF on `build/1`. The same
validation paths (unknown syscalls, malformed actions, duplicate
rules) apply.

## Example

    Linx.Seccomp.builder()
    |> Linx.Seccomp.Builder.allow(:read)
    |> Linx.Seccomp.Builder.allow(:write)
    |> Linx.Seccomp.Builder.deny(:ptrace, errno: :eperm)
    |> Linx.Seccomp.Builder.deny(:kexec_load, action: :kill_process)
    |> Linx.Seccomp.Builder.build(default: :allow)
    # => {:ok, %Linx.Seccomp.Filter{}}

# `t`

```elixir
@type t() :: %Linx.Seccomp.Builder{rules: [{Linx.Seccomp.Filter.action(), atom()}]}
```

Internal accumulator type for the builder. The `:rules` field is
a reversed list of `{action, syscall_atom}` tuples; `build/1`
reverses it back to source order before handing off.

# `allow`

```elixir
@spec allow(t(), atom()) :: t()
```

Adds an `:allow` rule for `syscall` to the builder.

Rules accumulate in source order — duplicate-detection happens
at `build/1` time, the same place `from_rules/1` does its
validation.

# `build`

```elixir
@spec build(
  t(),
  keyword()
) :: {:ok, Linx.Seccomp.Filter.t()} | {:error, term()}
```

Compiles the accumulated rules to a `%Linx.Seccomp.Filter{}`.

Options:

  * `:default` — the fallthrough action for syscalls no rule
    matched. Defaults to `:kill_process`, matching
    `Linx.Seccomp.allow_list/2`'s default — builders are
    typically used for tight filters where unknown syscalls
    should fail loudly.

Errors mirror `Linx.Seccomp.from_rules/1`: `{:bad_action, _}`,
`{:unknown_syscall, _}`, `{:duplicate_rule, _}`,
`{:unsupported_arch, _}`, and the jump-overflow
`%Linx.Seccomp.Error{}`.

# `deny`

```elixir
@spec deny(t(), atom(), keyword()) :: t()
```

Adds a deny rule for `syscall` to the builder.

Options:

  * `:errno` — short form for `{:errno, atom_or_int}`. The
    default deny action is `{:errno, :eperm}`.
  * `:action` — pass a full action verdict (`:kill_process`,
    `:kill_thread`, `:trap`, `:log`, `{:errno, _}`). Wins over
    `:errno` if both are given.

## Examples

    builder |> deny(:ptrace)                       # → {:errno, :eperm}
    builder |> deny(:ptrace, errno: :eacces)        # → {:errno, :eacces}
    builder |> deny(:kexec_load, action: :kill_process)

# `new`

```elixir
@spec new() :: t()
```

An empty builder — the starting point for the pipeline.

Equivalent to `Linx.Seccomp.builder/0`; the latter is the form
in the headline example.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
