Core LibraryunreleasedTopics

Choose documentation 1

latest

Current version

latest
English

Unreleased libtmux_erlang has not been released. Its API may change during development. This site's structure and URLs may change too.

Control connections

Attach to an existing session, verify identity on that persistent connection, inspect its attachment effects and close the client. This currently qualifies connection lifetime only. Commands still execute through the one-shot APIs; control submission and groups remain implementation work.

The example owns its session. The runner provides a private tmux fixture and verifies final cleanup:

Terminal window
$ mise exec -- escript tools/run_examples.escript control
-module(control_demo).
-moduledoc "Attach explicitly, inspect captured values and prove detachment.".
-export([run/2]).
-spec run(binary(), binary()) -> map().
run(Socket, Executable) ->
{ok, Server} = tmux_server:open(
#{socket_path => Socket, executable => Executable}),
tmux_scope:run_or_error(fun() ->
{ok, Session} = tmux_session:create(Server,
#{name => <<"control-demo">>, width => 120, height => 30,
launch => #{argv => [<<"/bin/cat">>]}}),
tmux_scope:run_or_error(fun() ->
Id = tmux_model:get(id, Session),
0 = tmux_model:get(attached_count, Session),
{ok, Control} = tmux_control:attach(Server, Session, #{}),
tmux_scope:run_or_error(fun() ->
{ok, #{phase := open, identity := same_connection}} =
tmux_control:status(Control),
{ok, Attached} = tmux_session:get(Server, Id),
1 = tmux_model:get(attached_count, Attached),
{ok, Graph} = tmux_server:snapshot(Server),
[Window] = tmux_snapshot:windows(Graph),
120 = tmux_model:get(width, Window),
30 = tmux_model:get(height, Window),
ok = tmux_control:close(Control),
{ok, #{phase := closed, cleanup := complete}} =
tmux_control:status(Control),
{ok, Detached} = tmux_session:get(Server, Id),
0 = tmux_model:get(attached_count, Detached),
0 = tmux_model:get(attached_count, Session),
#{identity => same_connection, attached_count => 1,
detached_count => 0, window_size => [120, 30],
cleanup => complete, session_preserved => true}
end, fun() ->
ok = tmux_control:close(Control)
end)
end, fun() ->
{ok, _} = tmux_session:kill(Session),
ok
end)
end, fun() ->
ok = tmux_server:close(Server)
end).
{
"identity": "same_connection",
"attached_count": 1,
"detached_count": 0,
"window_size": [120, 30],
"cleanup": "complete",
"session_preserved": true
}

The archive check repeats this complete program through the installed core package. The initial session record keeps its captured count of zero; fresh reads observe one attachment and later detachment. ignore-size preserves the 120-by-30 window. In this isolated fixture without mutating hooks, closing the client preserves the session and daemon.

An attachment requires a session captured or bound through the same endpoint. A second endpoint handle returns different_owner even for the same socket. The library uses attach-session with no-output, ignore-size and -E. It issues no session-creation or session-option write commands. -E skips the native attachment environment update. Configured attachment/detachment hooks can still change state, create or destroy resources. Native policies such as destroy-unattached can remove a session when its last client detaches. Failure and cleanup do not roll back those effects. Other clients may also change state concurrently. Close retires its client/helper without issuing session or daemon destruction commands. Attachment changes attached_count. On tmux 3.6 and newer it also uses no-detach-on-destroy; earlier versions retain native destruction behavior.

The caller owns the control lifetime. Caller death, parent closing or parent invalidation requests retirement. Close the control handle before closing its parent endpoint when cleanup proof matters. Parent close proves its one-shot clients’ cleanup; it does not wait for separate control clients.

tmux_control:close/1 returns ok only after native client/helper retirement. cleanup_incomplete preserves a supervised owner: retain the handle and retry close after repairing the cleanup problem. status distinguishes closing from closed and reports cleanup explicitly. Successfully closed handles remain usable for status and idempotent close for 60 seconds. Application shutdown alone does not prove cleanup.

Unexpected hook output or reply blocks reject attachment and retire the client. The library does not disable borrowed hooks. Bounded startup includes parent registration, native exec and the identity probe. An incomplete error carries its control handle for explicit cleanup recovery.

See daemon ownership for private versus borrowed lifetimes, jobs for one-shot operation waits and cancellation, and support and gaps for matrix and delivery evidence.

Esc

Type to search.

Reference previewOpen reference