From ae932d179adc4c602f9a4298076cdc5a82f9351a Mon Sep 17 00:00:00 2001 From: Jeff Quast Date: Tue, 6 Oct 2015 10:17:50 -0700 Subject: 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. --- tools/display-maxcanon.py | 80 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 tools/display-maxcanon.py (limited to 'tools/display-maxcanon.py') 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) -- cgit v1.2.1