55
66import codecs
77import contextlib
8+ import fcntl
89import os
910import re
1011import select
1112import datetime
1213import logging
14+ import pty
1315import shlex
1416import subprocess
1517import threading
2527from moler .connection import Connection
2628from typing import Tuple , List , Optional
2729
30+ # Unix only. Does not work on Windows.
2831
2932class PtyProcessUnicodeNotFork :
3033 """PtyProcessUnicode without forking process."""
3134 def __init__ (self , cmd : str = "/bin/bash" , dimensions : Tuple [int , int ] = (25 , 120 ), buffer_size : int = 4096 ):
32- self .cmd = cmd
33- self .dimensions = dimensions
34- self .buffer_size = buffer_size
35- self .delayafterclose = 0.2
36- encoding = "utf-8"
37- self .decoder = codecs .getincrementaldecoder (encoding )(errors = 'strict' )
35+ self .cmd : str = cmd
36+ self .dimensions : Tuple [ int , int ] = dimensions
37+ self .buffer_size : int = buffer_size
38+ self .delayafterclose : float = 0.2
39+ self . encoding = "utf-8"
40+ self .decoder = codecs .getincrementaldecoder (self . encoding )(errors = 'strict' )
3841 self .fd : int = - 1 # File descriptor for pty master
3942 self .pid : int = - 1 # Process ID of the child process
4043 self .slave_fd : int = - 1 # File descriptor for pty slave
@@ -43,27 +46,22 @@ def __init__(self, cmd: str = "/bin/bash", dimensions: Tuple[int, int] = (25, 12
4346
4447 def create_pty_process (self ):
4548 """Create PtyProcessUnicode without forking process."""
46- import pty
47- import fcntl
4849
4950 # Create a new pty pair
5051 master_fd , slave_fd = pty .openpty ()
51- print (f"Created pty master_fd={ master_fd } , slave_fd={ slave_fd } " )
5252
5353 # Set master fd to non-blocking mode
5454 flags = fcntl .fcntl (master_fd , fcntl .F_GETFL )
5555 fcntl .fcntl (master_fd , fcntl .F_SETFL , flags | os .O_NONBLOCK )
5656
5757 # Start the subprocess with the slave fd
58- process : subprocess . Popen = subprocess .Popen (
58+ process = subprocess .Popen (
5959 shlex .split (self .cmd ),
6060 stdin = slave_fd ,
6161 stdout = slave_fd ,
6262 stderr = slave_fd ,
6363 start_new_session = True
6464 )
65- print (f"Started subprocess with cmd='{ self .cmd } '" )
66- print (f"Subprocess PID: { process .pid } " )
6765
6866 # Store the process information
6967 self .fd = master_fd
@@ -72,11 +70,6 @@ def create_pty_process(self):
7270 self .process = process
7371 self ._closed = False
7472
75- # Close slave fd in parent process (child process still has it)
76- # We keep it open initially to prevent early closure
77- # os.close(slave_fd) # Commented out to keep it open
78-
79- # Give the shell time to initialize
8073 time .sleep (0.1 )
8174
8275 def write (self , data : str ):
@@ -87,7 +80,7 @@ def write(self, data: str):
8780 try :
8881 # Convert string to bytes if necessary
8982 if isinstance (data , str ):
90- data_bytes = data .encode ('utf-8' )
83+ data_bytes = data .encode (self . encoding )
9184 else :
9285 data_bytes = data
9386
@@ -129,10 +122,6 @@ def close(self, force: bool = False) -> None:
129122 """Close pty process."""
130123 if self ._closed :
131124 return
132-
133- import signal
134- import subprocess
135-
136125 self ._closed = True
137126
138127 # Try to terminate the process gracefully first
@@ -225,7 +214,7 @@ def __init__(
225214 self .dimensions = dimensions
226215 self .first_prompt = first_prompt
227216 self .target_prompt = target_prompt
228- self ._cmd = [ cmd ]
217+ self ._cmd = cmd
229218 self .set_prompt_cmd = set_prompt_cmd
230219 self ._re_set_prompt_cmd = re .sub (
231220 "['\" ].*['\" ]" , "" , self .set_prompt_cmd .strip ()
@@ -238,10 +227,8 @@ def open(self) -> contextlib.closing:
238227
239228 if not self ._terminal :
240229 self .moler_connection .open ()
241- # self._terminal = PtyProcessUnicode.spawn(
242- # self._cmd, dimensions=self.dimensions
243- # )
244- self ._terminal = PtyProcessUnicodeNotFork ()
230+ self ._terminal = PtyProcessUnicodeNotFork (cmd = self ._cmd , dimensions = self .dimensions ,
231+ buffer_size = self ._read_buffer_size )
245232 assert self ._terminal is not None
246233 self ._terminal .create_pty_process ()
247234 self ._terminal .delayafterclose = self ._terminal_delayafterclose
0 commit comments