This is the mail archive of the
cygwin-patches
mailing list for the Cygwin project.
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)