-
Notifications
You must be signed in to change notification settings - Fork 367
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Pseudo-terminal (pty) devices stay open/allocated after run() finishes #518
Comments
More reports of this from Linux platforms, which see many files created in That report concerns long-running Python processes using the anonymous top level However, without having reread the OP until just now, I came to the same conclusion it does - this is likely an OS level issue where I simply am unaware of how to "close" an in-use pty so it is fully released before the process itself ends. So wondering about Python level garbage collection (the other obvious culprit in such situations) seems moot. Especially given that it's Runner, not Context, that manages all this - and even the single-Context scenario is going to be creating many anonymous internal Runner objects over its lifetime. |
Seems trivially reproducible with the following handy dandy all in one script: import os
from invoke import Local, Context
class PtyReporter(Local):
def start(self, *args, **kwargs):
super().start(*args, **kwargs)
if self.pid != 0:
print(self.parent_fd) # this will be the FD of the allocated pty
for _ in range(10):
PtyReporter(Context()).run('whoami', pty=True, hide=True)
Local(Context()).run("lsof -p {}".format(os.getpid())) Output, on macOS 10.14:
And sure enough, we see the FDs increment, and they're all still held open by the process before it exits. I'd expect identical on Linux except with different device paths and suchlike. So now the question is whether this is as simple as doing |
Yup, the following amend to above script and its output: # Added to the PtyReporter Local subclass
def stop(self):
os.close(self.parent_fd)
No dangling! And ironically the existing implementation of |
This is circumstantial, but I had a funky issue today that seems possibly Invoke's fault:
Device not configured
errors when trying to open new tmux windows or panesinv watch-docs
(frominvocations
, which useswatchdog
to basically run thedocs.build
task - which calls Sphinx, viarun(..., pty=True)
, on any file change) running and perhaps it was not closing out resources correctlyLocal
viapty.fork
disappear once we're done? Ditto the actual pseudo-terminals themselves?The text was updated successfully, but these errors were encountered: