This is the mail archive of the cygwin-patches mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Cygwin: pty: Disable clear screen for ssh sessions with -t option.


On 10/22/19 12:06 PM, Michael Haubenwallner wrote:
> On 10/22/19 10:04 AM, Corinna Vinschen wrote:
>> On Oct 22 09:20, Michael Haubenwallner wrote:
>>> On 10/18/19 1:37 PM, Takashi Yano wrote:
> 
>>>> +      const char *term = getenv ("TERM");
>>>> +      if (term && strcmp (term, "dumb") && !strstr (term, "emacs") &&
>>>> +	  wcsstr (myself->progname, L"\\usr\\sbin\\sshd.exe"))
> 
>>> Again, my real problem does not utilize ssh at all, but is some python script
>>> using multiple pty.openpty() to spawn commands inside, to allow for herding
>>> all the subprocesses started by the commands (Ctrl-C or similar).
> 
>> In terms of clearing the screen at all, what's your opinion, Michael?
> 
> While I do not fully understand TTY handling, clearing the screen because
> just opening a PTY doesn't feel correct.
> 
> To start with, attached is some python script where I do not expect to see
> the initial clear screen code, but the one from /usr/bin/clear only.
> 

> Interesting enough, cygwin-3.0.7 does dump core somewhere in between, so the real
> python program probably does some additional setup I've not extracted yet.

Sorry, the issue with cygwin-3.0.7 probably was because I've built my python3
against cygwin-3.1. Using Cygwin python 2 or 3 it does work with cygwin-3.0.7.

Here's an improved version, with additional initialization found in the real
world program - doesn't make a significant difference.

/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(['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):
  print("set_term_size(lines:",lines,", columns:",columns,", fd:",fd)
  pid = os.fork()
  if pid == 0:
    cmd = ['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","/bin/pwd;/usr/bin/clear"])
  sys.exit(0)

os.close(slavefd)

while True:
  (rlist, wlist, xlist) = select.select([masterfd], [], [masterfd], 100)
  print("select read:",rlist,"except:",xlist)
  if rlist:
    try:
      line = os.read(rlist[0], 1024)
      print("read:", line)
    except OSError as e:
      print("quit:",e)
      break
sys.exit(0)

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]