diff options
author | zsquareplusc <cliechti@gmx.net> | 2020-11-19 03:07:52 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-11-19 03:07:52 +0100 |
commit | 54a6b00a7ce200755e0cde0fc3f2ae0dbc2e723a (patch) | |
tree | 1f378eff7001aed581d3cb148f2b62b15d32707f | |
parent | fecd9310535db64f93f410c0d73a977bf7a14e9e (diff) | |
parent | f28543bee0b132b2977848159b4690bca86b05f0 (diff) | |
download | pyserial-git-54a6b00a7ce200755e0cde0fc3f2ae0dbc2e723a.tar.gz |
Merge pull request #540 from henzef/patch-1
serialposix: Fix inconstent state after exception in open()
-rw-r--r-- | serial/serialposix.py | 64 |
1 files changed, 43 insertions, 21 deletions
diff --git a/serial/serialposix.py b/serial/serialposix.py index 51e6a10..7aceb76 100644 --- a/serial/serialposix.py +++ b/serial/serialposix.py @@ -325,35 +325,53 @@ class Serial(SerialBase, PlatformSpecific): raise SerialException(msg.errno, "could not open port {}: {}".format(self._port, msg)) #~ fcntl.fcntl(self.fd, fcntl.F_SETFL, 0) # set blocking + self.pipe_abort_read_r, self.pipe_abort_read_w = None, None + self.pipe_abort_write_r, self.pipe_abort_write_w = None, None + try: self._reconfigure_port(force_update=True) - except: + + try: + if not self._dsrdtr: + self._update_dtr_state() + if not self._rtscts: + self._update_rts_state() + except IOError as e: + # ignore Invalid argument and Inappropriate ioctl + if e.errno not in (errno.EINVAL, errno.ENOTTY): + raise + + self._reset_input_buffer() + + self.pipe_abort_read_r, self.pipe_abort_read_w = os.pipe() + self.pipe_abort_write_r, self.pipe_abort_write_w = os.pipe() + fcntl.fcntl(self.pipe_abort_read_r, fcntl.F_SETFL, os.O_NONBLOCK) + fcntl.fcntl(self.pipe_abort_write_r, fcntl.F_SETFL, os.O_NONBLOCK) + except BaseException: try: os.close(self.fd) - except: + except Exception: # ignore any exception when closing the port # also to keep original exception that happened when setting up pass self.fd = None + + if self.pipe_abort_read_w is not None: + os.close(self.pipe_abort_read_w) + self.pipe_abort_read_w = None + if self.pipe_abort_read_r is not None: + os.close(self.pipe_abort_read_r) + self.pipe_abort_read_r = None + if self.pipe_abort_write_w is not None: + os.close(self.pipe_abort_write_w) + self.pipe_abort_write_w = None + if self.pipe_abort_write_r is not None: + os.close(self.pipe_abort_write_r) + self.pipe_abort_write_r = None + raise - else: - self.is_open = True - try: - if not self._dsrdtr: - self._update_dtr_state() - if not self._rtscts: - self._update_rts_state() - except IOError as e: - if e.errno in (errno.EINVAL, errno.ENOTTY): - # ignore Invalid argument and Inappropriate ioctl - pass - else: - raise - self.reset_input_buffer() - self.pipe_abort_read_r, self.pipe_abort_read_w = os.pipe() - self.pipe_abort_write_r, self.pipe_abort_write_w = os.pipe() - fcntl.fcntl(self.pipe_abort_read_r, fcntl.F_SETFL, os.O_NONBLOCK) - fcntl.fcntl(self.pipe_abort_write_r, fcntl.F_SETFL, os.O_NONBLOCK) + + self.is_open = True def _reconfigure_port(self, force_update=False): """Set communication parameters on opened port.""" @@ -654,11 +672,15 @@ class Serial(SerialBase, PlatformSpecific): raise PortNotOpenError() termios.tcdrain(self.fd) + def _reset_input_buffer(self): + """Clear input buffer, discarding all that is in the buffer.""" + termios.tcflush(self.fd, termios.TCIFLUSH) + def reset_input_buffer(self): """Clear input buffer, discarding all that is in the buffer.""" if not self.is_open: raise PortNotOpenError() - termios.tcflush(self.fd, termios.TCIFLUSH) + self._reset_input_buffer() def reset_output_buffer(self): """\ |