Browse Source

Merge pull request #209 from ceccopierangiolieugenio/FIX_Terminal_Zombie_Process

use waitpid to avoid zombie terminal processes
pull/223/head
Pier CeccoPierangioliEugenio 2 years ago committed by GitHub
parent
commit
df76dfa64a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 21
      TermTk/TTkWidgets/TTkTerminal/terminalhelper.py
  2. 3
      TermTk/TTkWidgets/TTkTerminal/terminalview.py
  3. 7
      tests/t.pty/test.pty.006.terminal.06.py

21
TermTk/TTkWidgets/TTkTerminal/terminalhelper.py

@ -32,9 +32,10 @@ class TTkTerminalHelper():
__slots__ = ('_shell', '_fd', '_inout', '_pid', __slots__ = ('_shell', '_fd', '_inout', '_pid',
'_quit_pipe', '_size', '_term', '_quit_pipe', '_size', '_term',
#Signals #Signals
'dataOut') 'terminalClosed', 'dataOut')
def __init__(self, term=None) -> None: def __init__(self, term=None) -> None:
self.dataOut = pyTTkSignal(str) self.dataOut = pyTTkSignal(str)
self.terminalClosed = pyTTkSignal()
self._shell = os.environ.get('SHELL', 'sh') self._shell = os.environ.get('SHELL', 'sh')
self._fd = None self._fd = None
self._inout = None self._inout = None
@ -51,6 +52,7 @@ class TTkTerminalHelper():
self.dataOut.connect(term.termWrite) self.dataOut.connect(term.termWrite)
term.termData.connect(self.push) term.termData.connect(self.push)
term.termResized.connect(self.resize) term.termResized.connect(self.resize)
term.closed.connect(self._quit)
def runShell(self, program=None): def runShell(self, program=None):
self._shell = program if program else self._shell self._shell = program if program else self._shell
@ -72,7 +74,9 @@ class TTkTerminalHelper():
self._quit_pipe = os.pipe() self._quit_pipe = os.pipe()
threading.Thread(target=self.loop,args=[self]).start() threading.Thread(target=self.loop).start()
threading.Thread(target=lambda pid=self._pid:os.waitpid(pid,0)).start()
if self._term: if self._term:
self.resize(*self._term.termSize()) self.resize(*self._term.termSize())
self._term = None self._term = None
@ -95,16 +99,20 @@ class TTkTerminalHelper():
@pyTTkSlot() @pyTTkSlot()
def _quit(self): def _quit(self):
if self._pid: if pid := self._pid:
os.kill(self._pid,0) try:
os.kill(self._pid,15) os.kill(pid,0)
os.kill(pid,15)
# os.kill(pid,9)
except:
pass
if self._quit_pipe: if self._quit_pipe:
try: try:
os.write(self._quit_pipe[1], b'quit') os.write(self._quit_pipe[1], b'quit')
except: except:
pass pass
def loop(self, _): def loop(self):
while rs := select( [self._inout,self._quit_pipe[0]], [], [])[0]: while rs := select( [self._inout,self._quit_pipe[0]], [], [])[0]:
if self._quit_pipe[0] in rs: if self._quit_pipe[0] in rs:
# os.close(self._quit_pipe[0]) # os.close(self._quit_pipe[0])
@ -130,6 +138,7 @@ class TTkTerminalHelper():
fcntl.fcntl(self._inout, fcntl.F_SETFL, _fl) fcntl.fcntl(self._inout, fcntl.F_SETFL, _fl)
except Exception as e: except Exception as e:
TTkLog.error(f"Error: {e=}") TTkLog.error(f"Error: {e=}")
self._quit()
self.terminalClosed.emit() self.terminalClosed.emit()
return return

3
TermTk/TTkWidgets/TTkTerminal/terminalview.py

@ -143,9 +143,6 @@ class TTkTerminalView(TTkAbstractScrollView, _TTkTerminal_CSI_DEC):
def viewDisplayedSize(self) -> (int, int): def viewDisplayedSize(self) -> (int, int):
return self.size() return self.size()
def close(self):
self._quit()
def termSize(self): def termSize(self):
return self.size() return self.size()

7
tests/t.pty/test.pty.006.terminal.06.py

@ -76,15 +76,12 @@ def _addTerminal():
win = ttk.TTkWindow(pos=(12,0), size=(100,30), title=f"Terminallo n.{tnum}", border=True, layout=ttk.TTkVBoxLayout(), flags = ttk.TTkK.WindowFlag.WindowMinMaxButtonsHint|ttk.TTkK.WindowFlag.WindowCloseButtonHint) win = ttk.TTkWindow(pos=(12,0), size=(100,30), title=f"Terminallo n.{tnum}", border=True, layout=ttk.TTkVBoxLayout(), flags = ttk.TTkK.WindowFlag.WindowMinMaxButtonsHint|ttk.TTkK.WindowFlag.WindowCloseButtonHint)
term = ttk.TTkTerminal(parent=win) term = ttk.TTkTerminal(parent=win)
th = ttk.TTkTerminalHelper() th = ttk.TTkTerminalHelper(term=term)
th.dataOut.connect(term.termWrite) th.terminalClosed.connect(win.close)
term.termData.connect(th.push)
term.termResized.connect(th.resize)
term.bell.connect(lambda : ttk.TTkLog.debug("BELL!!! 🔔🔔🔔")) term.bell.connect(lambda : ttk.TTkLog.debug("BELL!!! 🔔🔔🔔"))
term.titleChanged.connect(win.setTitle) term.titleChanged.connect(win.setTitle)
term.terminalClosed.connect(win.close)
term.textSelected.connect(clipboard.setText) term.textSelected.connect(clipboard.setText)
term.textSelected.connect(_textSelected) term.textSelected.connect(_textSelected)
win.closed.connect(term.close) win.closed.connect(term.close)

Loading…
Cancel
Save