source: rtems-tools/tester/rt/console.py @ fa81491

5
Last change on this file since fa81491 was b0fa2ae, checked in by Chris Johns <chrisj@…>, on 03/03/16 at 05:46:18

Update rtems-tool to support Python 2 and 3.

Add solaris and netbsd.

Close #2619.

  • Property mode set to 100644
File size: 4.8 KB
Line 
1#
2# RTEMS Tools Project (http://www.rtems.org/)
3# Copyright 2013-2014 Chris Johns (chrisj@rtems.org)
4# All rights reserved.
5#
6# This file is part of the RTEMS Tools package in 'rtems-tools'.
7#
8# Redistribution and use in source and binary forms, with or without
9# modification, are permitted provided that the following conditions are met:
10#
11# 1. Redistributions of source code must retain the above copyright notice,
12# this list of conditions and the following disclaimer.
13#
14# 2. Redistributions in binary form must reproduce the above copyright notice,
15# this list of conditions and the following disclaimer in the documentation
16# and/or other materials provided with the distribution.
17#
18# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28# POSSIBILITY OF SUCH DAMAGE.
29#
30
31#
32# RTEMS Testing Consoles
33#
34
35from __future__ import print_function
36
37import errno
38import os
39import threading
40import time
41
42#
43# Not available on Windows. Not sure what this means.
44#
45if os.name != 'nt':
46    import fcntl
47    from . import stty
48else:
49    fcntl = None
50    stty = None
51
52def save():
53    if stty is not None:
54        return stty.save()
55    return None
56
57def restore(attributes):
58    if attributes is not None and stty is not None:
59        stty.restore(attributes)
60
61class console(object):
62    '''RTEMS Testing console base.'''
63
64    def __init__(self, name, trace):
65        self.name = name
66        self.trace = trace
67
68    def __del__(self):
69        pass
70
71    def _tracing(self):
72        return self.trace
73
74    def open(self):
75        pass
76
77    def close(self):
78        pass
79
80class stdio(console):
81    '''STDIO console.'''
82
83    def __init__(self, trace = False):
84        super(stdio, self).__init__('stdio', trace)
85
86class tty(console):
87    '''TTY console connects to serial ports.'''
88
89    raw = 'B115200,~BRKINT,IGNBRK,IGNCR,~ICANON,~ISIG,~IEXTEN,~ECHO,CLOCAL,~CRTSCTS'
90
91    def __init__(self, dev, output, setup = None, trace = False):
92        self.tty = None
93        self.read_thread = None
94        self.dev = dev
95        self.output = output
96        if setup is None:
97            self.setup = raw
98        else:
99            self.setup = setup
100        super(tty, self).__init__(dev, trace)
101
102    def __del__(self):
103        super(tty, self).__del__()
104        if self._tracing():
105            print(':: tty close', self.dev)
106        if fcntl is not None:
107            fcntl.fcntl(me.tty.fd, fcntl.F_SETFL,
108                        fcntl.fcntl(me.tty.fd, fcntl.F_GETFL) & ~os.O_NONBLOCK)
109        self.close()
110
111    def open(self):
112        def _readthread(me, x):
113            if self._tracing():
114                print(':: tty runner started', self.dev)
115            if fcntl is not None:
116                fcntl.fcntl(me.tty.fd, fcntl.F_SETFL,
117                            fcntl.fcntl(me.tty.fd, fcntl.F_GETFL) | os.O_NONBLOCK)
118            line = ''
119            while me.running:
120                time.sleep(0.05)
121                try:
122                    data = me.tty.fd.read()
123                except IOError as ioe:
124                    if ioe.errno == errno.EAGAIN:
125                        continue
126                    raise
127                except:
128                    raise
129                for c in data:
130                    if len(c) == 0:
131                        continue
132                    if c != chr(0):
133                        line += c
134                    if c == '\n':
135                        me.output(line)
136                        line = ''
137            if self._tracing():
138                print(':: tty runner finished', self.dev)
139        if self._tracing():
140            print(':: tty open', self.dev)
141        self.tty = stty.tty(self.dev)
142        self.tty.set(self.setup)
143        self.tty.on()
144        self.read_thread = threading.Thread(target = _readthread,
145                                            name = 'tty[%s]' % (self.dev),
146                                            args = (self, 0))
147        self.read_thread.daemon = True
148        self.running = True
149        self.read_thread.start()
150
151    def close(self):
152        if self.tty:
153            time.sleep(1)
154            if self.read_thread:
155                self.running = False
156                self.read_thread.join(1)
157            self.tty = None
Note: See TracBrowser for help on using the repository browser.