Index: third_party/pexpect/tools/display-maxcanon.py |
diff --git a/third_party/pexpect/tools/display-maxcanon.py b/third_party/pexpect/tools/display-maxcanon.py |
new file mode 100644 |
index 0000000000000000000000000000000000000000..cbd664ffec73c261ae58dcd0afe1eec2bcbd0d30 |
--- /dev/null |
+++ b/third_party/pexpect/tools/display-maxcanon.py |
@@ -0,0 +1,80 @@ |
+#!/usr/bin/env python |
+""" |
+This tool uses pexpect to test expected Canonical mode length. |
+ |
+All systems use the value of MAX_CANON which can be found using |
+fpathconf(3) value PC_MAX_CANON -- with the exception of Linux |
+and FreeBSD. |
+ |
+Linux, though defining a value of 255, actually honors the value |
+of 4096 from linux kernel include file tty.h definition |
+N_TTY_BUF_SIZE. |
+ |
+Linux also does not honor IMAXBEL. termios(3) states, "Linux does not |
+implement this bit, and acts as if it is always set." Although these |
+tests ensure it is enabled, this is a non-op for Linux. |
+ |
+FreeBSD supports neither, and instead uses a fraction (1/5) of the tty |
+speed which is always 9600. Therefor, the maximum limited input line |
+length is 9600 / 5 = 1920. |
+ |
+These tests only ensure the correctness of the behavior described by |
+the sendline() docstring -- the values listed there, and above should |
+be equal to the output of the given OS described, but no promises! |
+""" |
+# std import |
+from __future__ import print_function |
+import sys |
+import os |
+ |
+ |
+def detect_maxcanon(): |
+ import pexpect |
+ bashrc = os.path.join( |
+ # re-use pexpect/replwrap.py's bashrc file, |
+ os.path.dirname(__file__), os.path.pardir, 'pexpect', 'bashrc.sh') |
+ |
+ child = pexpect.spawn('bash', ['--rcfile', bashrc], |
+ echo=True, encoding='utf8', timeout=3) |
+ |
+ child.sendline(u'echo -n READY_; echo GO') |
+ child.expect_exact(u'READY_GO') |
+ |
+ child.sendline(u'stty icanon imaxbel erase ^H; echo -n retval: $?') |
+ child.expect_exact(u'retval: 0') |
+ |
+ child.sendline(u'echo -n GO_; echo AGAIN') |
+ child.expect_exact(u'GO_AGAIN') |
+ child.sendline(u'cat') |
+ |
+ child.delaybeforesend = 0 |
+ |
+ column, blocksize = 0, 64 |
+ ch_marker = u'_' |
+ |
+ print('auto-detecting MAX_CANON: ', end='') |
+ sys.stdout.flush() |
+ |
+ while True: |
+ child.send(ch_marker * blocksize) |
+ result = child.expect([ch_marker * blocksize, u'\a']) |
+ if result == 0: |
+ # entire block fit without emitting bel |
+ column += blocksize |
+ elif result == 1: |
+ # an '\a' was emitted, count the number of ch_markers |
+ # found since last blocksize, determining our MAX_CANON |
+ column += child.before.count(ch_marker) |
+ break |
+ print(column) |
+ |
+if __name__ == '__main__': |
+ try: |
+ detect_maxcanon() |
+ except ImportError: |
+ # we'd like to use this with CI -- but until we integrate |
+ # with tox, we can't determine a period in testing when |
+ # the pexpect module has been installed |
+ print('warning: pexpect not in module path, MAX_CANON ' |
+ 'could not be determined by systems test.', |
+ file=sys.stderr) |