PTY

Inherits: Node < Object

A pseudoterminal for forking and managing processes.

Description

Creates pseudoterminals for forking and managing processes (such as bash, zsh, or PowerShell, or one-off commands). It provides bidirectional communication channels for interacting with terminal-based applications.

Operates in two modes:

  • Fork: Starts a new process and connects it to the PTY using fork().

  • Open: Creates a PTY without starting a process using open(), allowing manual interaction.

Can be used with the Terminal node to create a fully functional shell interface.

Note: Not supported on Web. On Windows, requires Windows 10 version 1903 (May 2019) or later due to the use of ConPTY.

Tutorials

Properties

int

cols

80

Dictionary

env

{ "COLORTERM": "truecolor", "TERM": "xterm-256color" }

int

rows

24

NodePath

terminal_path

NodePath("")

bool

use_os_env

true

bool

use_threads

true

Methods

Error

fork(file: String = “”, args: PackedStringArray = PackedStringArray(), cwd: String = “.”, cols: int = 80, rows: int = 24)

String

get_pts_name() const

void

kill(signal: int)

Error

open(cols: int = 80, rows: int = 24)

void

resize(cols: int, rows: int)

void

resizev(size: Vector2i)

void

write(data: Variant) const


Signals

data_received(data: PackedByteArray) 🔗

Emitted when data is read from the pseudoterminal. This typically occurs when the child process writes to stdout or stderr.

data contains raw bytes that should typically be forwarded to a Terminal node for display.


exited(exit_code: int, signal_code: int) 🔗

Emitted when the child program exits. exit_code is the exit status (0 typically means success). signal_code is the signal number that terminated the program, or 0 if the program exited normally.


Enumerations

enum IPCSignal: 🔗

IPCSignal IPCSIGNAL_SIGHUP = 1

Hangup signal. Traditionally sent when a terminal disconnects.

IPCSignal IPCSIGNAL_SIGINT = 2

Interrupt signal. Typically sent when the user presses Ctrl + C.

IPCSignal IPCSIGNAL_SIGQUIT = 3

Quit signal. Typically sent when the user presses Ctrl + \‌.

IPCSignal IPCSIGNAL_SIGILL = 4

Illegal instruction signal. Sent when a process attempts to execute an invalid instruction.

IPCSignal IPCSIGNAL_SIGTRAP = 5

Trace/breakpoint trap signal. Used by debuggers.

IPCSignal IPCSIGNAL_SIGABRT = 6

Abort signal. Sent when a process calls abort().

IPCSignal IPCSIGNAL_SIGFPE = 8

Floating-point exception signal. Sent on arithmetic errors like division by zero.

IPCSignal IPCSIGNAL_SIGKILL = 9

Kill signal. Cannot be caught, blocked, or ignored. Forcefully terminates the process.

IPCSignal IPCSIGNAL_SIGSEGV = 11

Segmentation violation signal. Sent when a process accesses invalid memory.

IPCSignal IPCSIGNAL_SIGPIPE = 13

Broken pipe signal. Sent when writing to a pipe with no readers.

IPCSignal IPCSIGNAL_SIGALRM = 14

Alarm signal. Sent when a timer set by alarm() expires.

IPCSignal IPCSIGNAL_SIGTERM = 15

Termination signal. Requests graceful termination of the process.


Property Descriptions

int cols = 80 🔗

  • void set_cols(value: int)

  • int get_cols()

The number of columns (width) of the terminal in characters.


Dictionary env = { "COLORTERM": "truecolor", "TERM": "xterm-256color" } 🔗

Environment variables to set for the child program.

Note: The default includes COLORTERM and TERM variables that enable full color support in most terminal applications.


int rows = 24 🔗

  • void set_rows(value: int)

  • int get_rows()

The number of rows (height) of the terminal in characters.


NodePath terminal_path = NodePath("") 🔗

NodePath to a Terminal node. Setting this path automatically connects the appropriate signals of both nodes for standard operation. Also disconnects signals from any previously connected terminal.

When connected, the PTY automatically resizes to match the Terminal’s size and data flows bidirectionally between them.


bool use_os_env = true 🔗

  • void set_use_os_env(value: bool)

  • bool get_use_os_env()

If true, environment variables from env are merged with the current program’s environment variables (Godot).

If false, only variables from env are used.

Note: Variables from env take precedence over the current program’s environment variables.


bool use_threads = true 🔗

  • void set_use_threads(value: bool)

  • bool is_using_threads()

If true, the PTY uses threads for non-blocking I/O operations. This improves performance by preventing the main thread from blocking during PTY operations.

Should generally remain true unless you have specific threading requirements.


Method Descriptions

Error fork(file: String = “”, args: PackedStringArray = PackedStringArray(), cwd: String = “.”, cols: int = 80, rows: int = 24) 🔗

Opens a pseudoterminal and starts a new process using the specified program. file defaults to the SHELL environment variable, or platform defaults if not set: sh on Linux, zsh on macOS, or cmd.exe on Windows. args are arguments passed to the program. cwd is the working directory (defaults to current directory). cols and rows set the initial terminal dimensions.

Returns @GlobalScope.OK on success, or an Error code on failure.

# Fork a default shell
var result = pty.fork()
if result == OK:
    print("Shell started successfully")

# Fork a specific program with arguments
var result = pty.fork("python3", ["-i"], "/home/user")

# Fork with custom terminal size
var result = pty.fork("bash", [], ".", 120, 40)

String get_pts_name() const 🔗

Returns the pseudoterminal device name. On Unix-like systems, this is typically a path like /dev/pts/1. Returns an empty string if no PTY is open or on platforms that don’t use traditional PTY device files (such as Windows).

var pts_name = pty.get_pts_name()
if pts_name != "":
    print("PTY device: ", pts_name)

void kill(signal: int) 🔗

Sends a signal to the PTY’s child process. signal is the signal number to send. You can use the IPCSignal constants for common signals, or any valid signal number.

Note: This method has no effect if no child process is running.

# Send SIGTERM to gracefully terminate the process
pty.kill(PTY.IPCSIGNAL_SIGTERM)

# Send SIGKILL to forcefully terminate the process
pty.kill(PTY.IPCSIGNAL_SIGKILL)

# Send SIGINT (equivalent to Ctrl + C)
pty.kill(PTY.IPCSIGNAL_SIGINT)

Error open(cols: int = 80, rows: int = 24) 🔗

Opens a pseudoterminal without starting a process. This creates the PTY device files for manual interaction. cols and rows set the initial terminal dimensions.

Returns @GlobalScope.OK on success, or an Error code on failure.

Useful for setting up a PTY for later use or direct terminal device interaction.


void resize(cols: int, rows: int) 🔗

Resizes the pseudoterminal to cols columns and rows rows. Call this when the connected Terminal node changes size to keep them synchronized. The child process will receive a SIGWINCH signal on Unix platforms to notify it of the size change.


void resizev(size: Vector2i) 🔗

Same as resize(), but accepts a Vector2i where x is columns and y is rows. Convenience method for when you have the terminal size as a vector.


void write(data: Variant) const 🔗

Writes data to the pseudoterminal. Accepts either a String or PackedByteArray. This data is sent to the child process’s stdin. For interactive shells, this typically represents user input such as typed commands.

# Send a command to a shell
pty.write("ls -la\n")
# Send raw bytes (e.g. Ctrl + C)
pty.write(PackedByteArray([0x03]))