Runs a program on a pseudoterminal and hands its byte stream to the caller.
spawn/2 allocates a pty, runs program on it in a new session with the pty as
its controlling terminal, and returns a handle holding two ports. No relaying
process stands between the caller and the program; os_pid/1 is the program's own
pid.
{:ok, pty} = Drafter.Pty.spawn("/bin/sh", args: ["-i"], cols: 100, rows: 30)
Drafter.Pty.write(pty, "echo hi\n")The process that called spawn/2 owns both ports and receives:
{port, {:data, bytes}}— output, whereportis the handle'sioport{port, {:exit_status, status}}— exit, whereportis the handle'scontrolport
Bytes written with write/2 go to the program's standard input. resize/3 sets the
terminal size, which makes the kernel deliver SIGWINCH to the foreground process
group.
The slave descriptor stays open for the lifetime of the handle. Exit is therefore
reported only through :exit_status on the control port; the io port does not
reach end-of-file when the program exits. close/1 releases both descriptors.
Setup failures are reported as an exit status rather than written to the host's error output:
64— too few arguments71— the pseudoterminal could not be opened or redirected127— the program could not be executed; the reason is written to the pseudoterminal and so appears in the terminal output
Summary
Functions
Shut the pseudoterminal down.
The operating system pid of the running program.
Set the terminal size to cols by rows cells.
Run program on a new pseudoterminal.
Send bytes to the program's standard input.
Types
Functions
@spec close(t()) :: :ok
Shut the pseudoterminal down.
Closes both ports and releases both descriptors. Releasing the last descriptor
makes the kernel send SIGHUP to the session, ending the program if it is still
running. Safe to call more than once; the handle is unusable afterwards.
@spec os_pid(t()) :: {:ok, non_neg_integer()} | :error
The operating system pid of the running program.
Returns :error once the control port has closed, which is the case after the
program exits or close/1 runs.
@spec resize(t(), pos_integer(), pos_integer()) :: :ok | {:error, :ioctl_failed}
Set the terminal size to cols by rows cells.
The kernel then reports the new size to the program and delivers SIGWINCH to the
foreground process group. {:error, :ioctl_failed} means the master descriptor is
no longer a pty, which is the case once close/1 has run.
Run program on a new pseudoterminal.
program is an executable, resolved with execvp: a name without a slash is
looked up on the PATH the emulator was started with, and a name with one is
used as given.
Options:
:args— argument list, default[]:cols,:rows— initial terminal size in cells, default80by24:env— extra environment as a list of{name, value}string pairs, default[]. It is added toTERMrather than to the caller's environment: the program inherits the emulator's environment with these entries applied on top.:term— value forTERM, default"xterm-256color":cd— working directory for the program, default the caller's
Returns {:ok, handle}. {:error, :helper_missing} means the pty_spawn helper
is not in priv; {:error, reason} from the pty allocation means no
pseudoterminal was available, and carries the strerror text as a binary. The
calling process becomes the owner of both ports and must call close/1 when
finished.
A program that cannot be executed is still reported as a successful spawn; the failure arrives as an exit status on the control port.
Send bytes to the program's standard input.