WinTer 0.1.1
Windows Terminal Emulator
Loading...
Searching...
No Matches
Pseudo Console Integration

Core structures and routines for terminal shell bridging via Windows ConPTY. More...

Classes

struct  pty_state_t
 Encapsulates the OS-level state of an active Pseudo Console session. More...

Typedefs

typedef struct pty_state_t PTY_State
 Encapsulates the OS-level state of an active Pseudo Console session.

Functions

b32 pty_init (struct pty_state_t *state, u16 columns, u16 rows)
 Initializes a Pseudo Console and establishes bidirectional communication pipes.
b32 pty_spawn (struct pty_state_t *state, LPCWSTR command_line)
 Spawns a shell process and attaches it to an initialized Pseudo Console.
void pty_cleanup (struct pty_state_t *state)
 Terminates the Pseudo Console session and releases all active system handles.
INTERNAL void safe_close_handle (HANDLE *h)
 Safely closes a Win32 HANDLE and sets the pointer to NULL.

Detailed Description

Core structures and routines for terminal shell bridging via Windows ConPTY.

This module encapsulates the full lifecycle of a Windows pseudo-terminal session. It manages anonymous pipe creation, the ConPTY object, and the child shell process that writes output into and reads input from those pipes.

Module Architecture
The module is split into two distinct phases:
  • Initialization (pty_init): Creates the pipes and the ConPTY session.
  • Spawning (pty_spawn): Creates the shell process and attaches it to the ConPTY.

Separating these phases allows the caller to configure the ConPTY (e.g., resize it) before a shell is attached, and makes the code easier to reason about.

Typedef Documentation

◆ PTY_State

typedef struct pty_state_t PTY_State

Encapsulates the OS-level state of an active Pseudo Console session.

This struct owns all Win32 handles needed to communicate with the shell process. All handles are initialized to NULL and must only be used after a successful call to pty_init(). The hProcess and hThread handles are populated after a successful call to pty_spawn().

Warning
Do not copy this struct. Handle ownership is singular only one instance should own and eventually close each handle.

Function Documentation

◆ pty_cleanup()

void pty_cleanup ( struct pty_state_t * state)

Terminates the Pseudo Console session and releases all active system handles.

Closes the ConPTY object, the shell process handle, and the pipe handles owned by our application. All pointers in state are set to NULL after cleanup.

Note
Closing hProcess does not terminate the shell. The shell continues running until it exits naturally or is explicitly terminated. Closing the handle simply releases our kernel object reference.
Parameters
[in,out]statePointer to the PTY state structure to clean up. Safe to call with NULL or a partially initialized state.
See also
pty_init
pty_spawn

Definition at line 260 of file pty.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ pty_init()

b32 pty_init ( struct pty_state_t * state,
u16 columns,
u16 rows )

Initializes a Pseudo Console and establishes bidirectional communication pipes.

This function performs the first phase of PTY setup:

  • Creates two anonymous Win32 pipes (input and output).
  • Sets bInheritHandle = TRUE on the pipe security attributes so the handles can be passed to ConPTY.
  • Calls CreatePseudoConsole with the read end of the input pipe and the write end of the output pipe the two ends that ConPTY owns.
  • Closes the ConPTY-owned pipe ends in our process to prevent deadlocks. A pipe only signals EOF when all write handles are closed; keeping a duplicate would cause ReadFile to block forever after the shell exits.

After this call, state->hInputWrite and state->hOutputRead are valid and ready for I/O. No shell is attached yet call pty_spawn() for that.

Parameters
[out]statePointer to the state structure to populate. Must not be NULL.
[in]columnsInitial terminal grid width in characters (e.g., 80).
[in]rowsInitial terminal grid height in characters (e.g., 24).
Returns
true if the ConPTY and pipes were successfully created, false otherwise. On failure, any partially opened handles are cleaned up before returning.
See also
pty_spawn
pty_cleanup

Definition at line 50 of file pty.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ pty_spawn()

b32 pty_spawn ( struct pty_state_t * state,
LPCWSTR command_line )

Spawns a shell process and attaches it to an initialized Pseudo Console.

This function performs the second phase of PTY setup. It uses the extended process creation API (STARTUPINFOEXW + PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE) to attach the new process to the ConPTY created by pty_init().

The key steps are:

  1. Allocate and initialize a process thread attribute list with one entry.
  2. Call UpdateProcThreadAttribute with PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE to wire state->hPC into the attribute list.
  3. Set si.StartupInfo.cb = sizeof(STARTUPINFOEXW) this is the version tag Windows reads to know it's looking at the extended struct.
  4. Call CreateProcessW with EXTENDED_STARTUPINFO_PRESENT in dwCreationFlags. Both this flag AND the correct cb size are required. One without the other will silently ignore the attribute list.
  5. Close the attribute list memory (DeleteProcThreadAttributeList + HeapFree).
  6. Close pi.hThread immediately we have no use for the thread handle.
  7. Store pi.hProcess in state->hProcess for later lifecycle management.
Note
bInheritHandles is set to FALSE. The pipe handles are attached to the child via the ConPTY attribute, not via inheritance. Enabling inheritance would give the child duplicate handles it doesn't know about, which causes subtle pipe-lifetime bugs and potential deadlocks.
Parameters
[in,out]statePointer to a state structure populated by pty_init(). Must not be NULL. On success, state->hProcess is set.
[in]command_lineThe command to execute as a wide string (e.g., L"cmd.exe"). Windows resolves bare names via the system PATH. Must not be NULL.
Returns
true if the process was created and attached successfully, false otherwise. On failure, the attribute list is cleaned up before returning.
Precondition
pty_init() must have been called successfully on state.
See also
pty_init
pty_cleanup

Definition at line 116 of file pty.c.

Here is the call graph for this function:

◆ safe_close_handle()

INTERNAL void safe_close_handle ( HANDLE * h)

Safely closes a Win32 HANDLE and sets the pointer to NULL.

This is an internal guard wrapper around CloseHandle. It is a no-op if *h is already NULL, making it safe to call on partially initialized state.

Parameters
[in,out]hPointer to the HANDLE to close. Set to NULL on success.

Definition at line 41 of file pty.c.

Here is the caller graph for this function: