OLD | NEW |
(Empty) | |
| 1 #!/usr/bin/env python |
| 2 """ |
| 3 This tool uses pexpect to test expected Canonical mode length. |
| 4 |
| 5 All systems use the value of MAX_CANON which can be found using |
| 6 fpathconf(3) value PC_MAX_CANON -- with the exception of Linux |
| 7 and FreeBSD. |
| 8 |
| 9 Linux, though defining a value of 255, actually honors the value |
| 10 of 4096 from linux kernel include file tty.h definition |
| 11 N_TTY_BUF_SIZE. |
| 12 |
| 13 Linux also does not honor IMAXBEL. termios(3) states, "Linux does not |
| 14 implement this bit, and acts as if it is always set." Although these |
| 15 tests ensure it is enabled, this is a non-op for Linux. |
| 16 |
| 17 FreeBSD supports neither, and instead uses a fraction (1/5) of the tty |
| 18 speed which is always 9600. Therefor, the maximum limited input line |
| 19 length is 9600 / 5 = 1920. |
| 20 |
| 21 These tests only ensure the correctness of the behavior described by |
| 22 the sendline() docstring -- the values listed there, and above should |
| 23 be equal to the output of the given OS described, but no promises! |
| 24 """ |
| 25 # std import |
| 26 from __future__ import print_function |
| 27 import sys |
| 28 import os |
| 29 |
| 30 |
| 31 def detect_maxcanon(): |
| 32 import pexpect |
| 33 bashrc = os.path.join( |
| 34 # re-use pexpect/replwrap.py's bashrc file, |
| 35 os.path.dirname(__file__), os.path.pardir, 'pexpect', 'bashrc.sh') |
| 36 |
| 37 child = pexpect.spawn('bash', ['--rcfile', bashrc], |
| 38 echo=True, encoding='utf8', timeout=3) |
| 39 |
| 40 child.sendline(u'echo -n READY_; echo GO') |
| 41 child.expect_exact(u'READY_GO') |
| 42 |
| 43 child.sendline(u'stty icanon imaxbel erase ^H; echo -n retval: $?') |
| 44 child.expect_exact(u'retval: 0') |
| 45 |
| 46 child.sendline(u'echo -n GO_; echo AGAIN') |
| 47 child.expect_exact(u'GO_AGAIN') |
| 48 child.sendline(u'cat') |
| 49 |
| 50 child.delaybeforesend = 0 |
| 51 |
| 52 column, blocksize = 0, 64 |
| 53 ch_marker = u'_' |
| 54 |
| 55 print('auto-detecting MAX_CANON: ', end='') |
| 56 sys.stdout.flush() |
| 57 |
| 58 while True: |
| 59 child.send(ch_marker * blocksize) |
| 60 result = child.expect([ch_marker * blocksize, u'\a']) |
| 61 if result == 0: |
| 62 # entire block fit without emitting bel |
| 63 column += blocksize |
| 64 elif result == 1: |
| 65 # an '\a' was emitted, count the number of ch_markers |
| 66 # found since last blocksize, determining our MAX_CANON |
| 67 column += child.before.count(ch_marker) |
| 68 break |
| 69 print(column) |
| 70 |
| 71 if __name__ == '__main__': |
| 72 try: |
| 73 detect_maxcanon() |
| 74 except ImportError: |
| 75 # we'd like to use this with CI -- but until we integrate |
| 76 # with tox, we can't determine a period in testing when |
| 77 # the pexpect module has been installed |
| 78 print('warning: pexpect not in module path, MAX_CANON ' |
| 79 'could not be determined by systems test.', |
| 80 file=sys.stderr) |
OLD | NEW |