0
# Core PTY Management
1
2
The core classes that handle pseudo-terminal allocation, management, and control. These classes provide the foundational layer for all dockerpty operations, managing the complexities of terminal hijacking, signal handling, and resource cleanup.
3
4
## Capabilities
5
6
### PseudoTerminal Class
7
8
The main class that wraps the pseudo-TTY (PTY) allocated to a docker container and manages it via the current process' TTY.
9
10
```python { .api }
11
class PseudoTerminal:
12
def __init__(self, client, operation):
13
"""
14
Initialize the PTY using the docker.Client instance and operation.
15
16
Parameters:
17
- client: Docker client instance
18
- operation: RunOperation or ExecOperation instance
19
"""
20
21
def start(self, sockets=None):
22
"""
23
Start PTY management with terminal hijacking.
24
25
This method takes over the current process' TTY until the container's PTY
26
is closed. Handles stream pumping, signal handlers, and resource cleanup.
27
28
Parameters:
29
- sockets: tuple of (stdin_socket, stdout_socket, stderr_socket), optional
30
31
Returns:
32
None - blocks until PTY is closed
33
"""
34
35
def resize(self, size=None):
36
"""
37
Resize the container's PTY.
38
39
Parameters:
40
- size: tuple of (height, width), optional. If None, determined by current TTY size
41
42
Returns:
43
None
44
"""
45
46
def sockets(self):
47
"""
48
Return the operation sockets.
49
50
Returns:
51
Sockets from the underlying operation
52
"""
53
```
54
55
Usage example:
56
57
```python
58
import docker
59
from dockerpty import PseudoTerminal, RunOperation
60
61
client = docker.Client()
62
container = client.create_container(
63
image='busybox:latest',
64
stdin_open=True,
65
tty=True,
66
command='/bin/sh',
67
)
68
69
# Create operation and start PTY
70
operation = RunOperation(client, container)
71
pty = PseudoTerminal(client, operation)
72
pty.start() # This hijacks the terminal
73
```
74
75
### WINCH Signal Handler
76
77
Handles SIGWINCH signals to keep the PTY correctly sized when the terminal window is resized.
78
79
```python { .api }
80
class WINCHHandler:
81
def __init__(self, pty):
82
"""
83
Initialize a new WINCH handler for the given PTY.
84
85
Initializing a handler has no immediate side-effects. The start()
86
method must be invoked for signals to be trapped.
87
88
Parameters:
89
- pty: PseudoTerminal instance to handle resize signals for
90
"""
91
92
def __enter__(self):
93
"""
94
Context manager entry - starts signal handling.
95
96
Returns:
97
self
98
"""
99
100
def __exit__(self, *_):
101
"""
102
Context manager exit - stops signal handling.
103
104
Parameters:
105
- *_: Exception information (ignored)
106
107
Returns:
108
None
109
"""
110
111
def start(self):
112
"""
113
Start trapping WINCH signals and resizing the PTY.
114
115
This method saves the previous WINCH handler so it can be restored on stop().
116
117
Returns:
118
None
119
"""
120
121
def stop(self):
122
"""
123
Stop trapping WINCH signals and restore the previous WINCH handler.
124
125
Returns:
126
None
127
"""
128
```
129
130
Usage example:
131
132
```python
133
from dockerpty import WINCHHandler, PseudoTerminal
134
135
# Usually used as context manager
136
with WINCHHandler(pty):
137
# PTY will be automatically resized when terminal window changes
138
pty.start()
139
```
140
141
## Implementation Details
142
143
### Terminal Hijacking Process
144
145
1. **Stream Setup**: Creates pumps for stdin, stdout, stderr between host and container
146
2. **Non-blocking I/O**: Configures streams for non-blocking operations
147
3. **Signal Handling**: Installs WINCH handler for window resize events
148
4. **Raw Mode**: Puts terminal in raw mode for direct key forwarding
149
5. **Event Loop**: Runs select loop to pump data between streams
150
6. **Cleanup**: Restores all original terminal attributes and signal handlers
151
152
### Resource Management
153
154
The PseudoTerminal class ensures proper cleanup of:
155
- Terminal attributes (raw mode restoration)
156
- Signal handlers (WINCH handler restoration)
157
- File descriptor blocking modes
158
- Stream resources and sockets
159
160
### Error Handling
161
162
- Handles SSL errors during stream operations
163
- Manages container exit conditions gracefully
164
- Recovers from interrupts and temporary I/O errors
165
- Ensures cleanup even if container crashes or exits unexpectedly