Hi Takashi, On 11/11/19 10:17 AM, Corinna Vinschen wrote: > On Nov 8 22:42, Takashi Yano wrote:
>> I came up with another alternative. How about the attached >> patch? This forcibly redraws screen when the first native >> program is executed after creating new pty (pseudo console), >> instead of clearing screen. >> >> This does not solve missing screen contents, but can avoid >> cursor position problem in netsh. > > I tested it and I think this is a great step forward. Dropping > $TERM checks and clear screen sequence is the way to go! I second that! Your "when the first native program is executed" does lead me to my next test case with native programs involved, which seems to work as expected with your patch applied on top of commit d14714c69. Thanks a lot! /haubi/
#! /usr/bin/env python import pty import os import select import subprocess import sys import termios if sys.hexversion >= 0x3000000: def _unicode_encode(s, encoding='utf_8', errors='backslashreplace'): if isinstance(s, str): s = s.encode(encoding, errors) return s def _unicode_decode(s, encoding='utf_8', errors='replace'): if isinstance(s, bytes): s = str(s, encoding=encoding, errors=errors) return s _native_string = _unicode_decode else: def _unicode_encode(s, encoding='utf_8', errors='backslashreplace'): if isinstance(s, unicode): s = s.encode(encoding, errors) return s def _unicode_decode(s, encoding='utf_8', errors='replace'): if isinstance(s, bytes): s = unicode(s, encoding=encoding, errors=errors) return s _native_string = _unicode_encode def get_term_size(fd=None): if fd is None: fd = sys.stdout if not hasattr(fd, 'isatty') or not fd.isatty(): return (0, 0) try: import curses try: curses.setupterm(term=os.environ.get("TERM", "unknown"), fd=fd.fileno()) return curses.tigetnum('lines'), curses.tigetnum('cols') except curses.error: pass except ImportError: pass try: proc = subprocess.Popen(['/bin/stty', 'size'], stdout=subprocess.PIPE, stderr=fd) except EnvironmentError as e: if e.errno != errno.ENOENT: raise # stty command not found return (0, 0) out = _unicode_decode(proc.communicate()[0]) if proc.wait() == os.EX_OK: out = out.split() if len(out) == 2: try: val = (int(out[0]), int(out[1])) except ValueError: raise else: if val[0] >= 0 and val[1] >= 0: return val return (0, 0) def set_term_size(lines, columns, fd): pid = os.fork() if pid == 0: cmd = ['/bin/stty', 'rows', str(lines), 'columns', str(columns)] os.dup2(0, fd) os.execvp(cmd[0], cmd) print("set_term_size failed") os.exit(1) ret = os.waitpid(pid, 0) return ret (masterfd, slavefd) = pty.openpty() mode = termios.tcgetattr(slavefd) mode[1] &= ~termios.OPOST termios.tcsetattr(slavefd, termios.TCSANOW, mode) if sys.stdout.isatty(): rows, columns = get_term_size(sys.stdout) set_term_size(rows, columns, slavefd) if os.fork() == 0: os.close(masterfd) os.dup2(slavefd, 0) os.dup2(slavefd, 1) os.dup2(slavefd, 2) os.execv("/bin/sh", ["/bin/sh","-c", ''' { cmd /c "set COLUMNS & set LINES & set TERM" ; "$(/usr/bin/cygpath -F 42)/Microsoft Visual Studio/Installer/vswhere.exe" -nologo -latest -legacy -format text -property installationPath ; } 2>&1 | /bin/tr -d \\\\r ''']) sys.exit(0) os.close(slavefd) while True: (rlist, wlist, xlist) = select.select([masterfd], [], [masterfd], 100) if rlist: try: line = os.read(rlist[0], 1024) print(line,) except OSError as e: if (e.errno != 5): print("quit:",e) break sys.exit(0)