-module(gleam@erlexec). -compile(no_auto_import). -export([new/0, debug/1, start/1, stop/1, manage_pid/2, which_children/0, kill_pid/2, kill_ospid/2, with_monitor/2, get_monitor/1, with_link/2, get_link/1, with_executable/2, get_executable/1, with_cd/2, get_cd/1, with_env/2, get_env/1, with_stdout/2, get_stdout/1, with_stderr/2, get_stderr/1, with_stdin/2, get_stdin/1, with_pty/2, get_pty/1, with_kill/2, get_kill/1, with_kill_timeout/2, with_group/2, with_user/2, with_winsz/3, winsz/3, with_nice/2, with_debug/2, with_success_exit_code/2, with_kill_group/2, with_pty_echo/2, run_async/2, run_sync/2, options_to_list/1, send/2, send_eof/1, to_ospid/1, find_executable/1, status/1, signal_to_int/1, int_to_signal/1, obtain/1]). -export_type([exec_atom/0, options/0, command/0, env_option/0, stdout_options/0, stderr_options/0, pty_options/0, pty_option/0, stdin_options/0, winsz_options/0, start_error/0, start_option/0, stop_error/0, pids/0, output/0, stdout_or_stderr/0, eof/0, find_executable_error/0, exit_status_or_signal/0, signal/0, obtain_ok/0, obtain_error/0]). -type exec_atom() :: cd | args | limit_users | portexe | verbose | root | alarm | clear | close | debug | env | executable | group | kill | winsz | kill_group | kill_timeout | link | monitor | nice | null | print | pty | pty_echo | stdin | string | success_exit_code | sync | user. -opaque options() :: {options, gleam@option:option(binary()), gleam@option:option(integer()), list(env_option()), gleam@option:option(binary()), gleam@option:option(integer()), boolean(), gleam@option:option(binary()), gleam@option:option(integer()), boolean(), boolean(), gleam@option:option(integer()), boolean(), boolean(), gleam@option:option(stderr_options()), gleam@option:option(stdin_options()), gleam@option:option(stdout_options()), gleam@option:option(integer()), boolean(), gleam@option:option(binary()), gleam@option:option(winsz_options()), integer()}. -type command() :: {shell, binary()} | {execve, list(binary())}. -type env_option() :: {env_string, binary()} | env_clear | {env_kv, binary(), binary()} | {env_unset, binary()}. -type stdout_options() :: stdout_capture | stdout_close | {stdout_fun, fun((gleam@erlang@atom:atom_(), integer(), binary()) -> nil)} | stdout_null | {stdout_pid, gleam@erlang@process:pid_()} | stdout_print | stdout_stderr | {stdout_string, binary()}. -type stderr_options() :: stderr_capture | stderr_close | {stderr_fun, fun((gleam@erlang@atom:atom_(), integer(), binary()) -> nil)} | stderr_null | {stderr_pid, gleam@erlang@process:pid_()} | stderr_print | stderr_stdout | {stderr_string, binary()}. -type pty_options() :: pty_enable | {pty_opts, list(pty_option())}. -type pty_option() :: {vintr, integer()} | {vquit, integer()} | {verase, integer()} | {vkill, integer()} | {veof, integer()} | {veol, integer()} | {veol2, integer()} | {vstart, integer()} | {vstop, integer()} | {vsusp, integer()} | {vdsusp, integer()} | {vreprint, integer()} | {vwerase, integer()} | {vlnext, integer()} | {vflush, integer()} | {vswtch, integer()} | {vstatus, integer()} | {vdiscard, integer()} | {ignpar, boolean()} | {parmrk, boolean()} | {inpck, boolean()} | {istrip, boolean()} | {inlcr, boolean()} | {igncr, boolean()} | {icrnl, boolean()} | {xcase, boolean()} | {iuclc, boolean()} | {ixon, boolean()} | {ixany, boolean()} | {ixoff, boolean()} | {imaxbel, boolean()} | {iutf8, boolean()} | {isig, boolean()} | {icanon, boolean()} | {echo, boolean()} | {echoe, boolean()} | {echok, boolean()} | {echonl, boolean()} | {noflsh, boolean()} | {tostop, boolean()} | {iexten, boolean()} | {echoctl, boolean()} | {echoke, boolean()} | {pendin, boolean()} | {opost, boolean()} | {olcuc, boolean()} | {onlcr, boolean()} | {ocrnl, boolean()} | {onocr, boolean()} | {onlret, boolean()} | {cs7, boolean()} | {cs8, boolean()} | {parenb, boolean()} | {parodd, boolean()} | {tty_op_ispeed, integer()} | {tty_op_ospeed, integer()}. -type stdin_options() :: stdin_close | stdin_null | stdin_pipe | {stdin_from, binary()}. -type winsz_options() :: {pseudo_terminal_size, integer(), integer()}. -type start_error() :: {already_started, gleam@erlang@process:pid_()}. -type start_option() :: {start_debug, integer()} | {start_root, boolean()} | start_verbose | {start_args, list(binary())} | {start_alarm, integer()} | {start_user, binary()} | {start_limit_users, list(binary())} | {start_portexe, binary()} | {start_env, list(env_option())}. -type stop_error() :: no_process. -type pids() :: {pids, gleam@erlang@process:pid_(), integer()}. -type output() :: {output, list(stdout_or_stderr())}. -type stdout_or_stderr() :: {stdout, list(binary())} | {stderr, list(binary())}. -type eof() :: eof. -type find_executable_error() :: executable_not_found. -type exit_status_or_signal() :: {exit_status, integer()} | {signal, signal(), boolean()}. -type signal() :: sighup | sigint | sigquit | sigill | sigtrap | sigabrt | sigbus | sigfpe | sigkill | sigusr1 | sigsegv | sigusr2 | sigpipe | sigalrm | sigterm | sigstkflt | sigchld | sigcont | sigstop | sigtstp | sigttin | sigttou | sigurg | sigxcpu | sigxfsz | sigvtalrm | sigprof | sigwinch | sigio | sigpwr | sigsys | {other, integer()}. -type obtain_ok() :: {obtain_stdout, integer(), binary()} | {obtain_stderr, integer(), binary()} | {obtain_down, gleam@erlang@process:pid_(), integer()}. -type obtain_error() :: obtain_timeout | {obtain_down_status, gleam@erlang@process:pid_(), integer(), integer()}. -spec new() -> options(). new() -> {options, none, none, [], none, none, false, none, none, false, false, none, false, false, none, none, none, none, false, none, none, 30000}. -spec debug(integer()) -> {ok, integer()} | {error, gleam@erlang@atom:atom_()}. debug(Level) -> exec:debug(Level). -spec start(list(start_option())) -> {ok, gleam@erlang@process:pid_()} | {error, start_error()}. start(Options) -> exec:start(start_options_to_list(Options)). -spec start_options_to_list(list(start_option())) -> list(gleam@dynamic:dynamic()). start_options_to_list(Options) -> _pipe = Options, gleam@list:map(_pipe, fun(O) -> case O of {start_debug, V} -> gleam@dynamic:from({debug, V}); {start_alarm, V@1} -> gleam@dynamic:from({alarm, V@1}); {start_args, V@2} -> gleam@dynamic:from({args, V@2}); {start_limit_users, V@3} -> gleam@dynamic:from({limit_users, V@3}); {start_portexe, V@4} -> gleam@dynamic:from({portexe, V@4}); {start_root, V@5} -> gleam@dynamic:from({root, V@5}); {start_user, V@6} -> gleam@dynamic:from({user, V@6}); start_verbose -> gleam@dynamic:from(verbose); {start_env, V@7} -> env_to_dynamic(V@7) end end). -spec stop(integer()) -> {ok, nil} | {error, gleam@dynamic:dynamic()}. stop(Pid) -> gleam_erlexec_ffi:stop(Pid). -spec manage_pid(gleam@erlang@process:pid_(), options()) -> gleam@dynamic:dynamic(). manage_pid(Pid, Options) -> exec:manage( gleam@dynamic:from(Pid), options_to_list(Options), erlang:element(22, Options) ). -spec which_children() -> list(integer()). which_children() -> exec:which_children(). -spec kill_pid(gleam@erlang@process:pid_(), integer()) -> {ok, nil} | {error, gleam@dynamic:dynamic()}. kill_pid(Pid, Signal) -> gleam_erlexec_ffi:kill(gleam@dynamic:from(Pid), Signal). -spec kill_ospid(integer(), integer()) -> {ok, nil} | {error, gleam@dynamic:dynamic()}. kill_ospid(Ospid, Signal) -> gleam_erlexec_ffi:kill(gleam@dynamic:from(Ospid), Signal). -spec with_monitor(options(), boolean()) -> options(). with_monitor(Old, Given) -> erlang:setelement(11, Old, Given). -spec get_monitor(options()) -> boolean(). get_monitor(Options) -> erlang:element(11, Options). -spec set_monitor(list(gleam@dynamic:dynamic()), options()) -> list(gleam@dynamic:dynamic()). set_monitor(Old, Option) -> case erlang:element(11, Option) of true -> [gleam@dynamic:from(monitor) | Old]; false -> Old end. -spec set_sync(list(gleam@dynamic:dynamic()), options()) -> list(gleam@dynamic:dynamic()). set_sync(Old, Option) -> case erlang:element(19, Option) of true -> [gleam@dynamic:from(sync) | Old]; false -> Old end. -spec with_link(options(), boolean()) -> options(). with_link(Old, Given) -> erlang:setelement(10, Old, Given). -spec get_link(options()) -> boolean(). get_link(Options) -> erlang:element(10, Options). -spec set_link(list(gleam@dynamic:dynamic()), options()) -> list(gleam@dynamic:dynamic()). set_link(Old, Option) -> case erlang:element(10, Option) of true -> [gleam@dynamic:from(link) | Old]; false -> Old end. -spec with_executable(options(), binary()) -> options(). with_executable(Old, Given) -> erlang:setelement(5, Old, {some, Given}). -spec get_executable(options()) -> gleam@option:option(binary()). get_executable(Options) -> erlang:element(5, Options). -spec set_executable(list(gleam@dynamic:dynamic()), options()) -> list(gleam@dynamic:dynamic()). set_executable(Old, Option) -> case erlang:element(5, Option) of {some, Executable} -> [gleam@dynamic:from({executable, Executable}) | Old]; none -> Old end. -spec with_cd(options(), binary()) -> options(). with_cd(Old, Given) -> erlang:setelement(2, Old, {some, Given}). -spec get_cd(options()) -> gleam@option:option(binary()). get_cd(Options) -> erlang:element(2, Options). -spec set_cd(list(gleam@dynamic:dynamic()), options()) -> list(gleam@dynamic:dynamic()). set_cd(Old, Option) -> case erlang:element(2, Option) of {some, Cd} -> [gleam@dynamic:from({cd, Cd}) | Old]; none -> Old end. -spec with_env(options(), list(env_option())) -> options(). with_env(Old, Given) -> erlang:setelement(4, Old, Given). -spec get_env(options()) -> list(env_option()). get_env(Options) -> erlang:element(4, Options). -spec set_env(list(gleam@dynamic:dynamic()), options()) -> list(gleam@dynamic:dynamic()). set_env(Old, Option) -> case gleam@list:length(erlang:element(4, Option)) of 0 -> Old; _@1 -> [env_to_dynamic(erlang:element(4, Option)) | Old] end. -spec env_to_dynamic(list(env_option())) -> gleam@dynamic:dynamic(). env_to_dynamic(Env) -> gleam@dynamic:from({env, gleam@list:map(Env, fun env_element_to_dynamic/1)}). -spec env_element_to_dynamic(env_option()) -> gleam@dynamic:dynamic(). env_element_to_dynamic(Element) -> case Element of {env_string, S} -> gleam@dynamic:from(S); env_clear -> gleam@dynamic:from(clear); {env_kv, K, V} -> gleam@dynamic:from({K, V}); {env_unset, K@1} -> gleam@dynamic:from({K@1, false}) end. -spec with_stdout(options(), stdout_options()) -> options(). with_stdout(Old, Given) -> erlang:setelement(17, Old, {some, Given}). -spec get_stdout(options()) -> gleam@option:option(stdout_options()). get_stdout(Options) -> erlang:element(17, Options). -spec set_stdout(list(gleam@dynamic:dynamic()), options()) -> list(gleam@dynamic:dynamic()). set_stdout(Old, Option) -> Stdout = gleam@erlang@atom:create_from_string(<<"stdout"/utf8>>), Stderr = gleam@erlang@atom:create_from_string(<<"stderr"/utf8>>), case erlang:element(17, Option) of {some, Value} -> [case Value of stdout_capture -> gleam@dynamic:from(Stdout); stdout_null -> gleam@dynamic:from({Stdout, null}); stdout_close -> gleam@dynamic:from({Stdout, close}); {stdout_pid, Pid} -> gleam@dynamic:from({Stdout, Pid}); stdout_print -> gleam@dynamic:from({Stdout, print}); stdout_stderr -> gleam@dynamic:from({Stdout, Stderr}); {stdout_string, S} -> gleam@dynamic:from({Stdout, S}); {stdout_fun, F} -> gleam@dynamic:from({Stdout, F}) end | Old]; none -> Old end. -spec with_stderr(options(), stderr_options()) -> options(). with_stderr(Old, Given) -> erlang:setelement(15, Old, {some, Given}). -spec get_stderr(options()) -> gleam@option:option(stderr_options()). get_stderr(Options) -> erlang:element(15, Options). -spec set_stderr(list(gleam@dynamic:dynamic()), options()) -> list(gleam@dynamic:dynamic()). set_stderr(Old, Option) -> Stdout = gleam@erlang@atom:create_from_string(<<"stdout"/utf8>>), Stderr = gleam@erlang@atom:create_from_string(<<"stderr"/utf8>>), case erlang:element(15, Option) of {some, Value} -> [case Value of stderr_capture -> gleam@dynamic:from(Stderr); stderr_null -> gleam@dynamic:from({Stderr, null}); stderr_close -> gleam@dynamic:from({Stderr, close}); {stderr_pid, Pid} -> gleam@dynamic:from({Stderr, Pid}); stderr_print -> gleam@dynamic:from({Stderr, print}); stderr_stdout -> gleam@dynamic:from({Stderr, Stdout}); {stderr_string, S} -> gleam@dynamic:from({Stderr, S}); {stderr_fun, F} -> gleam@dynamic:from({Stderr, F}) end | Old]; none -> Old end. -spec with_stdin(options(), stdin_options()) -> options(). with_stdin(Old, Given) -> erlang:setelement(16, Old, {some, Given}). -spec get_stdin(options()) -> gleam@option:option(stdin_options()). get_stdin(Options) -> erlang:element(16, Options). -spec set_stdin(list(gleam@dynamic:dynamic()), options()) -> list(gleam@dynamic:dynamic()). set_stdin(Old, Option) -> case erlang:element(16, Option) of {some, Stdin} -> [case Stdin of stdin_close -> gleam@dynamic:from({stdin, close}); stdin_null -> gleam@dynamic:from({stdin, null}); stdin_pipe -> gleam@dynamic:from(stdin); {stdin_from, S} -> gleam@dynamic:from({stdin, S}) end | Old]; none -> Old end. -spec with_pty(options(), boolean()) -> options(). with_pty(Old, Enable_pty) -> erlang:setelement(13, Old, Enable_pty). -spec get_pty(options()) -> boolean(). get_pty(Options) -> erlang:element(13, Options). -spec set_pty(list(gleam@dynamic:dynamic()), options()) -> list(gleam@dynamic:dynamic()). set_pty(Old, Option) -> case erlang:element(13, Option) of true -> [gleam@dynamic:from(pty) | Old]; false -> Old end. -spec with_kill(options(), binary()) -> options(). with_kill(Old, Command) -> erlang:setelement(8, Old, {some, Command}). -spec get_kill(options()) -> gleam@option:option(binary()). get_kill(Options) -> erlang:element(8, Options). -spec set_kill(list(gleam@dynamic:dynamic()), options()) -> list(gleam@dynamic:dynamic()). set_kill(Old, Option) -> case erlang:element(8, Option) of {some, Kill} -> [gleam@dynamic:from({kill, Kill}) | Old]; none -> Old end. -spec with_kill_timeout(options(), integer()) -> options(). with_kill_timeout(Old, Given) -> erlang:setelement(9, Old, {some, Given}). -spec set_kill_timeout(list(gleam@dynamic:dynamic()), options()) -> list(gleam@dynamic:dynamic()). set_kill_timeout(Old, Option) -> case erlang:element(9, Option) of {some, Kill_timeout} -> [gleam@dynamic:from({kill_timeout, Kill_timeout}) | Old]; none -> Old end. -spec with_group(options(), integer()) -> options(). with_group(Old, Given) -> erlang:setelement(6, Old, {some, Given}). -spec set_group(list(gleam@dynamic:dynamic()), options()) -> list(gleam@dynamic:dynamic()). set_group(Old, Option) -> case erlang:element(6, Option) of {some, Group} -> [gleam@dynamic:from({group, Group}) | Old]; none -> Old end. -spec with_user(options(), binary()) -> options(). with_user(Old, Given) -> erlang:setelement(20, Old, {some, Given}). -spec set_user(list(gleam@dynamic:dynamic()), options()) -> list(gleam@dynamic:dynamic()). set_user(Old, Option) -> case erlang:element(20, Option) of {some, User} -> [gleam@dynamic:from({user, User}) | Old]; none -> Old end. -spec with_winsz(options(), integer(), integer()) -> options(). with_winsz(Old, Rows, Columns) -> erlang:setelement(21, Old, {some, {pseudo_terminal_size, Rows, Columns}}). -spec set_winsz(list(gleam@dynamic:dynamic()), options()) -> list(gleam@dynamic:dynamic()). set_winsz(Old, Option) -> case erlang:element(21, Option) of {some, {pseudo_terminal_size, Rows, Columns}} -> [gleam@dynamic:from({winsz, {Rows, Columns}}) | Old]; none -> Old end. -spec winsz(integer(), integer(), integer()) -> {ok, nil} | {error, nil}. winsz(Pid, Rows, Columns) -> gleam_erlexec_ffi:winsz(Pid, Rows, Columns). -spec with_nice(options(), integer()) -> options(). with_nice(Old, Priority) -> erlang:setelement(12, Old, {some, Priority}). -spec set_nice(list(gleam@dynamic:dynamic()), options()) -> list(gleam@dynamic:dynamic()). set_nice(Old, Option) -> case erlang:element(12, Option) of {some, Nice} -> [gleam@dynamic:from({nice, Nice}) | Old]; none -> Old end. -spec with_debug(options(), integer()) -> options(). with_debug(Old, Level) -> erlang:setelement(3, Old, {some, Level}). -spec set_debug(list(gleam@dynamic:dynamic()), options()) -> list(gleam@dynamic:dynamic()). set_debug(Old, Option) -> case erlang:element(3, Option) of {some, Debug} -> [gleam@dynamic:from({debug, Debug}) | Old]; none -> Old end. -spec with_success_exit_code(options(), integer()) -> options(). with_success_exit_code(Old, Given) -> erlang:setelement(18, Old, {some, Given}). -spec set_success_exit_code(list(gleam@dynamic:dynamic()), options()) -> list(gleam@dynamic:dynamic()). set_success_exit_code(Old, Option) -> case erlang:element(18, Option) of {some, Success_exit_code} -> [gleam@dynamic:from({success_exit_code, Success_exit_code}) | Old]; none -> Old end. -spec with_kill_group(options(), boolean()) -> options(). with_kill_group(Old, Given) -> erlang:setelement(7, Old, Given). -spec set_kill_group(list(gleam@dynamic:dynamic()), options()) -> list(gleam@dynamic:dynamic()). set_kill_group(Old, Option) -> case erlang:element(7, Option) of true -> [gleam@dynamic:from(kill_group) | Old]; false -> Old end. -spec with_pty_echo(options(), boolean()) -> options(). with_pty_echo(Old, Given) -> erlang:setelement(14, Old, Given). -spec set_pty_echo(list(gleam@dynamic:dynamic()), options()) -> list(gleam@dynamic:dynamic()). set_pty_echo(Old, Option) -> case erlang:element(14, Option) of true -> [gleam@dynamic:from(pty_echo) | Old]; false -> Old end. -spec run_async(options(), command()) -> {ok, pids()} | {error, binary()}. run_async(Options, Command) -> Cmd_options = options_to_list(erlang:setelement(19, Options, false)), case Command of {execve, Cmd} -> gleam_erlexec_ffi:run( gleam@dynamic:from(Cmd), Cmd_options, erlang:element(22, Options) ); {shell, Cmd@1} -> gleam_erlexec_ffi:run( gleam@dynamic:from(Cmd@1), Cmd_options, erlang:element(22, Options) ) end. -spec run_sync(options(), command()) -> {ok, output()} | {error, binary()}. run_sync(Options, Command) -> Cmd_options = options_to_list(erlang:setelement(19, Options, true)), case Command of {execve, Cmd} -> gleam_erlexec_ffi:run( gleam@dynamic:from(Cmd), Cmd_options, erlang:element(22, Options) ); {shell, Cmd@1} -> gleam_erlexec_ffi:run( gleam@dynamic:from(Cmd@1), Cmd_options, erlang:element(22, Options) ) end. -spec options_to_list(options()) -> list(gleam@dynamic:dynamic()). options_to_list(Options) -> Setters = [fun set_monitor/2, fun set_sync/2, fun set_link/2, fun set_executable/2, fun set_cd/2, fun set_env/2, fun set_group/2, fun set_kill/2, fun set_kill_timeout/2, fun set_kill_group/2, fun set_group/2, fun set_user/2, fun set_nice/2, fun set_success_exit_code/2, fun set_stdout/2, fun set_stdin/2, fun set_stderr/2, fun set_winsz/2, fun set_pty/2, fun set_pty_echo/2, fun set_debug/2], _pipe = Setters, gleam@list:fold( _pipe, [], fun(Acc, Fun) -> _pipe@1 = Acc, Fun(_pipe@1, Options) end ). -spec send(integer(), binary()) -> {ok, nil} | {error, gleam@dynamic:dynamic()}. send(Ospid, Data) -> gleam_erlexec_ffi:send(Ospid, Data). -spec send_eof(integer()) -> {ok, nil} | {error, gleam@dynamic:dynamic()}. send_eof(Ospid) -> gleam_erlexec_ffi:send(Ospid, eof). -spec to_ospid(gleam@erlang@process:pid_()) -> {ok, integer()} | {error, gleam@dynamic:dynamic()}. to_ospid(Ospid) -> gleam_erlexec_ffi:ospid(Ospid). -spec find_executable(binary()) -> {ok, binary()} | {error, find_executable_error()}. find_executable(A) -> gleam_erlexec_ffi:find_executable(A). -spec status(integer()) -> exit_status_or_signal(). status(Status) -> Term_signal = erlang:'band'(Status, 16#7f), If_signaled = erlang:'bsr'(Term_signal + 1, 1) > 0, case If_signaled of true -> {signal, int_to_signal(Term_signal), erlang:'band'(Status, 16#80) =:= 16#80}; false -> {exit_status, erlang:'bsr'(erlang:'band'(Status, 16#FF00), 8)} end. -spec signal_to_int(signal()) -> integer(). signal_to_int(Signal) -> case Signal of sighup -> 1; sigint -> 2; sigquit -> 3; sigill -> 4; sigtrap -> 5; sigabrt -> 6; sigbus -> 7; sigfpe -> 8; sigkill -> 9; sigusr1 -> 10; sigsegv -> 11; sigusr2 -> 12; sigpipe -> 13; sigalrm -> 14; sigterm -> 15; sigstkflt -> 16; sigchld -> 17; sigcont -> 18; sigstop -> 19; sigtstp -> 20; sigttin -> 21; sigttou -> 22; sigurg -> 23; sigxcpu -> 24; sigxfsz -> 25; sigvtalrm -> 26; sigprof -> 27; sigwinch -> 28; sigio -> 29; sigpwr -> 30; sigsys -> 31; {other, Other} -> Other end. -spec int_to_signal(integer()) -> signal(). int_to_signal(Signal) -> case Signal of 1 -> sighup; 2 -> sigint; 3 -> sigquit; 4 -> sigill; 5 -> sigtrap; 6 -> sigabrt; 7 -> sigbus; 8 -> sigfpe; 9 -> sigkill; 10 -> sigusr1; 11 -> sigsegv; 12 -> sigusr2; 13 -> sigpipe; 14 -> sigalrm; 15 -> sigterm; 16 -> sigstkflt; 17 -> sigchld; 18 -> sigcont; 19 -> sigstop; 20 -> sigtstp; 21 -> sigttin; 22 -> sigttou; 23 -> sigurg; 24 -> sigxcpu; 25 -> sigxfsz; 26 -> sigvtalrm; 27 -> sigprof; 28 -> sigwinch; 29 -> sigio; 30 -> sigpwr; 31 -> sigsys; Other -> {other, Other} end. -spec obtain(integer()) -> {ok, obtain_ok()} | {error, obtain_error()}. obtain(A) -> gleam_erlexec_ffi:obtain(A).