| 3311 | self.subtype = 'cmd' |
| 3312 | |
| 3313 | def detach(self): |
| 3314 | if self and self.OS == 'Unix' and self.agent: |
| 3315 | threading.Thread(target=self.sync_cwd).start() |
| 3316 | |
| 3317 | if self and self.OS == 'Windows' and self.type != 'PTY': |
| 3318 | threading.Thread(target=self.get_subtype).start() |
| 3319 | |
| 3320 | if threading.current_thread().name != 'Core': |
| 3321 | core.control << (lambda: core.sessions[self.id].detach()) |
| 3322 | return |
| 3323 | |
| 3324 | if core.attached_session is None: |
| 3325 | return False |
| 3326 | |
| 3327 | core.wait_input = False |
| 3328 | core.attached_session = None |
| 3329 | core.rlist.remove(sys.stdin) |
| 3330 | |
| 3331 | if self.type == 'Readline': |
| 3332 | try: |
| 3333 | os.write(sys.stdin.fileno(), b'\n') |
| 3334 | except OSError: |
| 3335 | pass |
| 3336 | if hasattr(self, '_readline_thread') and self._readline_thread.is_alive(): |
| 3337 | self._readline_thread.join(timeout=2) |
| 3338 | |
| 3339 | if self.type == 'PTY': |
| 3340 | termios.tcsetattr(sys.stdin, termios.TCSADRAIN, TTY_NORMAL) |
| 3341 | |
| 3342 | if self.id in core.sessions: |
| 3343 | print() |
| 3344 | logger.warning("Session detached ⇲") |
| 3345 | menu.set_id(self.id) |
| 3346 | else: |
| 3347 | if options.single_session and not core.sessions: |
| 3348 | core.stop() |
| 3349 | logger.info("Penelope exited due to Single Session mode") |
| 3350 | return |
| 3351 | menu.set_id(None) |
| 3352 | menu.show() |
| 3353 | |
| 3354 | return True |
| 3355 | |
| 3356 | def download(self, remote_items): |
| 3357 | # Initialization |