summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorJeff Quast <contact@jeffquast.com>2015-10-06 10:17:50 -0700
committerJeff Quast <contact@jeffquast.com>2015-10-06 10:17:50 -0700
commitae932d179adc4c602f9a4298076cdc5a82f9351a (patch)
tree389f0a2ee8ba6722e600f5a8235c1e3b6026db5b /tools
parent0b7fee3c974d89b7f7f51fef9a1893e25ed980da (diff)
downloadpexpect-git-ae932d179adc4c602f9a4298076cdc5a82f9351a.tar.gz
2 new tools: display-{fpathconf.maxcanon}.py
tests/test_maxcanon.py has been deleted and turned into an "autodetection" tool of sorts, no longer attempting to assert exacting values, but determine it programmatically.
Diffstat (limited to 'tools')
-rw-r--r--tools/display-fpathconf.py41
-rw-r--r--tools/display-maxcanon.py80
2 files changed, 121 insertions, 0 deletions
diff --git a/tools/display-fpathconf.py b/tools/display-fpathconf.py
new file mode 100644
index 0000000..d40cbae
--- /dev/null
+++ b/tools/display-fpathconf.py
@@ -0,0 +1,41 @@
+#!/usr/bin/env python
+"""Displays os.fpathconf values related to terminals. """
+from __future__ import print_function
+import sys
+import os
+
+
+def display_fpathconf():
+ DISP_VALUES = (
+ ('PC_MAX_CANON', ('Max no. of bytes in a '
+ 'terminal canonical input line.')),
+ ('PC_MAX_INPUT', ('Max no. of bytes for which '
+ 'space is available in a terminal input queue.')),
+ ('PC_PIPE_BUF', ('Max no. of bytes which will '
+ 'be written atomically to a pipe.')),
+ ('PC_VDISABLE', 'Terminal character disabling value.')
+ )
+ FMT = '{name:<13} {value:<5} {description}'
+
+ # column header
+ print(FMT.format(name='name', value='value', description='description'))
+ print(FMT.format(name=('-' * 13), value=('-' * 5), description=('-' * 11)))
+
+ fd = sys.stdin.fileno()
+ for name, description in DISP_VALUES:
+ key = os.pathconf_names.get(name, None)
+ if key is None:
+ value = 'UNDEF'
+ else:
+ try:
+ value = os.fpathconf(fd, name)
+ except OSError as err:
+ value = 'OSErrno {0.errno}'.format(err)
+ if name == 'PC_VDISABLE':
+ value = hex(value)
+ print(FMT.format(name=name, value=value, description=description))
+ print()
+
+
+if __name__ == '__main__':
+ display_fpathconf()
diff --git a/tools/display-maxcanon.py b/tools/display-maxcanon.py
new file mode 100644
index 0000000..cbd664f
--- /dev/null
+++ b/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)