README.md

# execvp

`execvp` is a small library that allows a running BEAM instance to hand over
control to another OS process. Just like `exec` replaces the current process
with another command in bash. This is particularly useful for **escripts or CLI
tools** that need to replace themselves with another process as their final
step. This means when that other process exits, execution does not return to
the BEAM.

```erlang
  execvp:cmd("git", ["help", "rebase"]).
```

> ⚠️  **Warning:** Calling `execvp:cmd/2` **replaces the current BEAM process**.
> Any further Erlang/Elixir code will not run. Concurrent BEAM processes are
> brutally killed. Use this only if you know what you are doing. Otherwise
> consider using ports or `os:cmd`.

---

## Installation

### Mix

Add this to your `mix.exs` dependencies:

```elixir
  def deps do
    [
      {:execvp, "~> 1.0.0"}
    ]
  end
```

Then run:

```bash
  mix deps.get
  mix deps.compile
```

### Rebar3

Add this to your rebar.config:

```erlang
  {deps, [
    {execvp, "~> 1.0.0"}
  ]}.
```

Compile with:

```bash
  rebar3 compile
```

The NIF is built automatically and placed in `priv/`.

## Usage

### Erlang

```erlang
  % Replace current VM with `ls -l /etc`
  execvp:cmd("ls", ["-l", "/etc"]).
```

### Elixir

```elixir
  # Replace current VM with `ls -l /etc`
  :execvp.cmd("ls", ["-l", "/etc"])
```

## Behavior

* On success, the BEAM VM is replaced; your script ends.
* On failure (e.g., command not found), returns:

```erlang
  {error, Reason} % Reason is a binary describing the failure
```

Examples:

```erlang
  bash$ rebar3 shell
  erl> execvp:cmd("nosuchcommand", []).
  {error, <<"No such file or directory">>}
  erl> execvp:cmd("echo", ["1", "2", "3"]).
  1 2 3
  bash$ _
```

```elixir
  bash$ iex -S mix
  iex> :execvp.cmd("nosuchcommand", [])
  {:error, "No such file or directory"}
  erl> :execvp.cmd("echo", ["1", "2", "3"])
  1 2 3
  bash$ _
```

## Intended Use Case

`execvp` is designed for:

* Designed for escripts that need to execute a final system command.
* May be useful in CLI tools written in Erlang or Elixir that wish to "handoff"
  to another executable without leaving a lingering BEAM process.
* Intended use is in scripts where the BEAM process is only a bootstrap or
  wrapper.
* It is not intended for general runtime use inside a long-running VM.
* Once executed successfully, `execvp:cmd/2` cannot return.
* Terminal settings are automatically restored to "sane" mode before executing
  the external command.
* Parts of your code _after_ `execvp:cmd` may not run, unless the execution of
  the external command was not possible (missing executable, no execution
  right, etc.).

## Development

* `c_src/` contains the NIF source code.
* `src/execvp.erl` contains the Erlang wrapper module.
* The `.so` NIF is built in `priv/` automatically by Rebar3.
* Execute `rebar3 eunit` to run the tests.