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)

Reply via email to