From 62afef06af914fe0c0584a0cc5ae8c9633549ea0 Mon Sep 17 00:00:00 2001 From: Julien Duponchelle Date: Thu, 26 Feb 2015 15:47:47 +0100 Subject: [PATCH] After an iou reload you can write on the console --- gns3server/modules/iou/ioucon.py | 127 +++++++++++++++++-------------- 1 file changed, 70 insertions(+), 57 deletions(-) diff --git a/gns3server/modules/iou/ioucon.py b/gns3server/modules/iou/ioucon.py index 2b5556ab..764e81e8 100644 --- a/gns3server/modules/iou/ioucon.py +++ b/gns3server/modules/iou/ioucon.py @@ -171,6 +171,9 @@ class TTY(Console): self.epoll = epoll epoll.register(self.fd, select.EPOLLIN | select.EPOLLET) + def unregister(self, epoll): + epoll.unregister(self.fd) + def __enter__(self): try: self.fd = open('/dev/tty', 'r+b', buffering=0) @@ -240,6 +243,9 @@ class TelnetServer(Console): self.epoll = epoll epoll.register(self.sock_fd, select.EPOLLIN) + def unregister(self, epoll): + epoll.unregister(self.sock_fd) + def _read_block(self, bufsize): buf = self._read_cur(bufsize, socket.MSG_WAITALL) # If we don't get everything we were looking for then the @@ -420,6 +426,9 @@ class IOU: self.epoll = epoll epoll.register(self.fd, select.EPOLLIN | select.EPOLLET) + def unregister(self, epoll): + epoll.unregister(self.fd) + def fileno(self): return self.fd.fileno() @@ -468,70 +477,73 @@ def mkdir_netio(netio_dir): raise NetioError("Couldn't create directory {}: {}".format(netio_dir, e)) -def send_recv_loop(console, router, esc_char, stop_event): - - epoll = select.epoll() +def send_recv_loop(epoll, console, router, esc_char, stop_event): router.register(epoll) console.register(epoll) - router_fileno = router.fileno() - esc_quit = bytes(ESC_QUIT.upper(), 'ascii') - esc_state = False + try: + router_fileno = router.fileno() + esc_quit = bytes(ESC_QUIT.upper(), 'ascii') + esc_state = False - while not stop_event.is_set(): - event_list = epoll.poll(timeout=POLL_TIMEOUT) + while not stop_event.is_set(): + event_list = epoll.poll(timeout=POLL_TIMEOUT) - # When/if the poll times out we send an empty datagram. If IOU - # has gone away then this will toss a ConnectionRefusedError - # exception. - if not event_list: - router.write(b'') - continue + # When/if the poll times out we send an empty datagram. If IOU + # has gone away then this will toss a ConnectionRefusedError + # exception. + if not event_list: + router.write(b'') + continue - for fileno, event in event_list: - buf = bytearray() + for fileno, event in event_list: + buf = bytearray() - # IOU --> tty(s) - if fileno == router_fileno: - while not stop_event.is_set(): - data = router.read(BUFFER_SIZE) - if not data: - break - buf.extend(data) - console.write(buf) + # IOU --> tty(s) + if fileno == router_fileno: + while not stop_event.is_set(): + data = router.read(BUFFER_SIZE) + if not data: + break + buf.extend(data) + console.write(buf) - # tty --> IOU - else: - while not stop_event.is_set(): - data = console.read(fileno, BUFFER_SIZE) - if not data: - break - buf.extend(data) - - # If we just received the escape character then - # enter the escape state. - # - # If we are in the escape state then check for a - # quit command. Or if it's the escape character then - # send the escape character. Else, send the escape - # character we ate earlier and whatever character we - # just got. Exit escape state. - # - # If we're not in the escape state and this isn't an - # escape character then just send it to IOU. - if esc_state: - if buf.upper() == esc_quit: - sys.exit(EXIT_SUCCESS) - elif buf == esc_char: - router.write(esc_char) - else: - router.write(esc_char) - router.write(buf) - esc_state = False - elif buf == esc_char: - esc_state = True + # tty --> IOU else: - router.write(buf) + while not stop_event.is_set(): + data = console.read(fileno, BUFFER_SIZE) + if not data: + break + buf.extend(data) + + # If we just received the escape character then + # enter the escape state. + # + # If we are in the escape state then check for a + # quit command. Or if it's the escape character then + # send the escape character. Else, send the escape + # character we ate earlier and whatever character we + # just got. Exit escape state. + # + # If we're not in the escape state and this isn't an + # escape character then just send it to IOU. + if esc_state: + if buf.upper() == esc_quit: + sys.exit(EXIT_SUCCESS) + elif buf == esc_char: + router.write(esc_char) + else: + router.write(esc_char) + router.write(buf) + esc_state = False + elif buf == esc_char: + esc_state = True + else: + router.write(buf) + finally: + log.debug("Finally") + router.unregister(epoll) + console.unregister(epoll) def get_args(): @@ -609,6 +621,7 @@ def start_ioucon(cmdline_args, stop_event): 'ADDR:PORT (like 127.0.0.1:20000)') while not stop_event.is_set(): + epoll = select.epoll() try: if args.telnet_server: with TelnetServer(addr, nport, stop_event) as console: @@ -616,12 +629,12 @@ def start_ioucon(cmdline_args, stop_event): while not stop_event.is_set(): try: with IOU(ttyC, ttyS, stop_event) as router: - send_recv_loop(console, router, b'', stop_event) + send_recv_loop(epoll, console, router, b'', stop_event) except ConnectionRefusedError: pass else: with IOU(ttyC, ttyS, stop_event) as router, TTY() as console: - send_recv_loop(console, router, esc_char, stop_event) + send_recv_loop(epoll, console, router, esc_char, stop_event) except ConnectionRefusedError: pass except KeyboardInterrupt: