OLD | NEW |
(Empty) | |
| 1 #!/usr/bin/env python |
| 2 """ Display known information about our terminal. """ |
| 3 from __future__ import print_function |
| 4 import termios |
| 5 import locale |
| 6 import sys |
| 7 import os |
| 8 |
| 9 BITMAP_IFLAG = { |
| 10 'IGNBRK': 'ignore BREAK condition', |
| 11 'BRKINT': 'map BREAK to SIGINTR', |
| 12 'IGNPAR': 'ignore (discard) parity errors', |
| 13 'PARMRK': 'mark parity and framing errors', |
| 14 'INPCK': 'enable checking of parity errors', |
| 15 'ISTRIP': 'strip 8th bit off chars', |
| 16 'INLCR': 'map NL into CR', |
| 17 'IGNCR': 'ignore CR', |
| 18 'ICRNL': 'map CR to NL (ala CRMOD)', |
| 19 'IXON': 'enable output flow control', |
| 20 'IXOFF': 'enable input flow control', |
| 21 'IXANY': 'any char will restart after stop', |
| 22 'IMAXBEL': 'ring bell on input queue full', |
| 23 'IUCLC': 'translate upper case to lower case', |
| 24 } |
| 25 |
| 26 BITMAP_OFLAG = { |
| 27 'OPOST': 'enable following output processing', |
| 28 'ONLCR': 'map NL to CR-NL (ala CRMOD)', |
| 29 'OXTABS': 'expand tabs to spaces', |
| 30 'ONOEOT': 'discard EOT\'s `^D\' on output)', |
| 31 'OCRNL': 'map CR to NL', |
| 32 'OLCUC': 'translate lower case to upper case', |
| 33 'ONOCR': 'No CR output at column 0', |
| 34 'ONLRET': 'NL performs CR function', |
| 35 } |
| 36 |
| 37 BITMAP_CFLAG = { |
| 38 'CSIZE': 'character size mask', |
| 39 'CS5': '5 bits (pseudo)', |
| 40 'CS6': '6 bits', |
| 41 'CS7': '7 bits', |
| 42 'CS8': '8 bits', |
| 43 'CSTOPB': 'send 2 stop bits', |
| 44 'CREAD': 'enable receiver', |
| 45 'PARENB': 'parity enable', |
| 46 'PARODD': 'odd parity, else even', |
| 47 'HUPCL': 'hang up on last close', |
| 48 'CLOCAL': 'ignore modem status lines', |
| 49 'CCTS_OFLOW': 'CTS flow control of output', |
| 50 'CRTSCTS': 'same as CCTS_OFLOW', |
| 51 'CRTS_IFLOW': 'RTS flow control of input', |
| 52 'MDMBUF': 'flow control output via Carrier', |
| 53 } |
| 54 |
| 55 BITMAP_LFLAG = { |
| 56 'ECHOKE': 'visual erase for line kill', |
| 57 'ECHOE': 'visually erase chars', |
| 58 'ECHO': 'enable echoing', |
| 59 'ECHONL': 'echo NL even if ECHO is off', |
| 60 'ECHOPRT': 'visual erase mode for hardcopy', |
| 61 'ECHOCTL': 'echo control chars as ^(Char)', |
| 62 'ISIG': 'enable signals INTR, QUIT, [D]SUSP', |
| 63 'ICANON': 'canonicalize input lines', |
| 64 'ALTWERASE': 'use alternate WERASE algorithm', |
| 65 'IEXTEN': 'enable DISCARD and LNEXT', |
| 66 'EXTPROC': 'external processing', |
| 67 'TOSTOP': 'stop background jobs from output', |
| 68 'FLUSHO': 'output being flushed (state)', |
| 69 'NOKERNINFO': 'no kernel output from VSTATUS', |
| 70 'PENDIN': 'XXX retype pending input (state)', |
| 71 'NOFLSH': 'don\'t flush after interrupt', |
| 72 } |
| 73 |
| 74 CTLCHAR_INDEX = { |
| 75 'VEOF': 'EOF', |
| 76 'VEOL': 'EOL', |
| 77 'VEOL2': 'EOL2', |
| 78 'VERASE': 'ERASE', |
| 79 'VWERASE': 'WERASE', |
| 80 'VKILL': 'KILL', |
| 81 'VREPRINT': 'REPRINT', |
| 82 'VINTR': 'INTR', |
| 83 'VQUIT': 'QUIT', |
| 84 'VSUSP': 'SUSP', |
| 85 'VDSUSP': 'DSUSP', |
| 86 'VSTART': 'START', |
| 87 'VSTOP': 'STOP', |
| 88 'VLNEXT': 'LNEXT', |
| 89 'VDISCARD': 'DISCARD', |
| 90 'VMIN': '---', |
| 91 'VTIME': '---', |
| 92 'VSTATUS': 'STATUS', |
| 93 } |
| 94 |
| 95 |
| 96 def display_bitmask(kind, bitmap, value): |
| 97 """ Display all matching bitmask values for ``value`` given ``bitmap``. """ |
| 98 col1_width = max(map(len, list(bitmap.keys()) + [kind])) |
| 99 col2_width = 7 |
| 100 FMT = '{name:>{col1_width}} {value:>{col2_width}} {description}' |
| 101 print(FMT.format(name=kind, |
| 102 value='Value', |
| 103 description='Description', |
| 104 col1_width=col1_width, |
| 105 col2_width=col2_width)) |
| 106 print('{0} {1} {2}'.format('-' * col1_width, |
| 107 '-' * col2_width, |
| 108 '-' * max(map(len, bitmap.values())))) |
| 109 for flag_name, description in bitmap.items(): |
| 110 try: |
| 111 bitmask = getattr(termios, flag_name) |
| 112 bit_val = 'on' if bool(value & bitmask) else 'off' |
| 113 except AttributeError: |
| 114 bit_val = 'undef' |
| 115 print(FMT.format(name=flag_name, |
| 116 value=bit_val, |
| 117 description=description, |
| 118 col1_width=col1_width, |
| 119 col2_width=col2_width)) |
| 120 print() |
| 121 |
| 122 |
| 123 def display_ctl_chars(index, cc): |
| 124 """ Display all control character indicies, names, and values. """ |
| 125 title = 'Special Character' |
| 126 col1_width = len(title) |
| 127 col2_width = max(map(len, index.values())) |
| 128 FMT = '{idx:<{col1_width}} {name:<{col2_width}} {value}' |
| 129 print('Special line Characters'.center(40).rstrip()) |
| 130 print(FMT.format(idx='Index', |
| 131 name='Name', |
| 132 value='Value', |
| 133 col1_width=col1_width, |
| 134 col2_width=col2_width)) |
| 135 print('{0} {1} {2}'.format('-' * col1_width, |
| 136 '-' * col2_width, |
| 137 '-' * 10)) |
| 138 for index_name, name in index.items(): |
| 139 try: |
| 140 index = getattr(termios, index_name) |
| 141 value = cc[index] |
| 142 if value == b'\xff': |
| 143 value = '_POSIX_VDISABLE' |
| 144 else: |
| 145 value = repr(value) |
| 146 except AttributeError: |
| 147 value = 'undef' |
| 148 print(FMT.format(idx=index_name, |
| 149 name=name, |
| 150 value=value, |
| 151 col1_width=col1_width, |
| 152 col2_width=col2_width)) |
| 153 print() |
| 154 |
| 155 |
| 156 def display_conf(kind, names, getter): |
| 157 col1_width = max(map(len, names)) |
| 158 FMT = '{name:>{col1_width}} {value}' |
| 159 print(FMT.format(name=kind, |
| 160 value='value', |
| 161 col1_width=col1_width)) |
| 162 print('{0} {1}'.format('-' * col1_width, '-' * 27)) |
| 163 for name in names: |
| 164 try: |
| 165 value = getter(name) |
| 166 except OSError as err: |
| 167 value = err |
| 168 print(FMT.format(name=name, value=value, col1_width=col1_width)) |
| 169 print() |
| 170 |
| 171 |
| 172 def main(): |
| 173 fd = sys.stdin.fileno() |
| 174 locale.setlocale(locale.LC_ALL, '') |
| 175 encoding = locale.getpreferredencoding() |
| 176 |
| 177 print('os.isatty({0}) => {1}'.format(fd, os.isatty(fd))) |
| 178 print('locale.getpreferredencoding() => {0}'.format(encoding)) |
| 179 |
| 180 display_conf(kind='pathconf', |
| 181 names=os.pathconf_names, |
| 182 getter=lambda name: os.fpathconf(fd, name)) |
| 183 |
| 184 try: |
| 185 (iflag, oflag, cflag, lflag, ispeed, ospeed, cc |
| 186 ) = termios.tcgetattr(fd) |
| 187 except termios.error as err: |
| 188 print('stdin is not a typewriter: {0}'.format(err)) |
| 189 else: |
| 190 display_bitmask(kind='Input Mode', |
| 191 bitmap=BITMAP_IFLAG, |
| 192 value=iflag) |
| 193 display_bitmask(kind='Output Mode', |
| 194 bitmap=BITMAP_OFLAG, |
| 195 value=oflag) |
| 196 display_bitmask(kind='Control Mode', |
| 197 bitmap=BITMAP_CFLAG, |
| 198 value=cflag) |
| 199 display_bitmask(kind='Local Mode', |
| 200 bitmap=BITMAP_LFLAG, |
| 201 value=lflag) |
| 202 display_ctl_chars(index=CTLCHAR_INDEX, |
| 203 cc=cc) |
| 204 print('os.ttyname({0}) => {1}'.format(fd, os.ttyname(fd))) |
| 205 print('os.ctermid() => {0}'.format(os.ttyname(fd))) |
| 206 |
| 207 |
| 208 if __name__ == '__main__': |
| 209 main() |
OLD | NEW |