From 8b2c7d43599236cc01f4c46822c6117fcdfe82ac Mon Sep 17 00:00:00 2001 From: John Harrison Date: Mon, 23 Jan 2012 13:09:14 -0600 Subject: [PATCH] Updating the error handling. --- include/serial/serial.h | 58 +++++++++++++++++++++++++---------------- src/impl/unix.cc | 40 +++++++++++++++++++++++----- src/serial.cc | 3 ++- 3 files changed, 71 insertions(+), 30 deletions(-) diff --git a/include/serial/serial.h b/include/serial/serial.h index fa21c72..e924abc 100644 --- a/include/serial/serial.h +++ b/include/serial/serial.h @@ -83,39 +83,53 @@ typedef enum { FLOWCONTROL_HARDWARE } flowcontrol_t; -class SerialExecption : public std::exception { - const char * e_what; +class SerialExecption : public std::exception +{ + const char* e_what_; public: - SerialExecption(const char *description) {e_what=description;}; - virtual const char* what() const throw() { - std::stringstream ss; - ss << "SerialException " << this->e_what << " failed."; - return ss.str().c_str(); + SerialExecption (const char *description) : e_what_ (description) {} + + virtual const char* what () const throw () + { + std::stringstream ss; + ss << "SerialException " << e_what_ << " failed."; + return ss.str ().c_str (); } }; -class IOException : public std::exception { - const char * e_what; +class IOException : public std::exception +{ + const char* e_what_; + int errno_; public: - IOException(const char * description) {e_what = description;} + explicit IOException (int errnum) : e_what_ (strerror (errnum)), errno_(errnum) {} + explicit IOException (const char * description) : e_what_ (description), errno_(0) {} - virtual const char* what() const throw() { - std::stringstream ss; - ss << "IO Exception " << this->e_what << " failed."; - return ss.str().c_str(); - } + int getErrorNumber () { return errno_; } + + virtual const char* what () const throw () + { + std::stringstream ss; + if (errno_ == 0) + ss << "IO Exception " << e_what_ << " failed."; + else + ss << "IO Exception " << errno_ << ":" << e_what_ << " failed."; + return ss.str ().c_str (); + } }; -class PortNotOpenedException : public std::exception { - const char * e_what; +class PortNotOpenedException : public std::exception +{ + const char * e_what_; public: - PortNotOpenedException(const char * description) {e_what = description;} + PortNotOpenedException (const char * description) : e_what_ (description) {} - virtual const char* what() const throw() { + virtual const char* what () const throw () + { std::stringstream ss; - ss << e_what << " called before port was opened."; - return ss.str().c_str(); - } + ss << e_what_ << " called before port was opened."; + return ss.str ().c_str (); + } }; diff --git a/src/impl/unix.cc b/src/impl/unix.cc index b598024..24ad257 100644 --- a/src/impl/unix.cc +++ b/src/impl/unix.cc @@ -64,7 +64,19 @@ Serial::SerialImpl::open () if (fd_ == -1) { - throw IOException ("invalid file descriptor"); + switch (errno) + { + case EINTR: + // Recurse because this is a recoverable error. + open (); + return; + case ENFILE: + case EMFILE: + throw IOException ("to many file handles open"); + break; + default: + throw IOException (errno); + } } reconfigurePort(); @@ -215,7 +227,7 @@ Serial::SerialImpl::available () } else { - throw IOException ("ioctl"); + throw IOException (errno); } } @@ -244,8 +256,7 @@ Serial::SerialImpl::read (char* buf, size_t size) if (r == -1) { - perror("select()"); - exit(EXIT_FAILURE); + throw IOException (errno); } } @@ -276,12 +287,27 @@ Serial::SerialImpl::read (char* buf, size_t size) size_t Serial::SerialImpl::write (const string &data) { - if (isOpen_ == false) { + if (isOpen_ == false) + { throw PortNotOpenedException ("Serial::write"); } + ssize_t n = ::write (fd_, data.c_str (), data.length ()); - if (n == -1) { - throw IOException ("Write"); + + if (n != static_cast (data.length ())) + { + throw IOException ("Write did not complete"); + } + else if (n == -1) + { + if (errno == EINTR) + { + return write (data); + } + else + { + throw IOException (errno); + } } return static_cast (n); } diff --git a/src/serial.cc b/src/serial.cc index a024538..c8ac752 100644 --- a/src/serial.cc +++ b/src/serial.cc @@ -167,7 +167,7 @@ Serial::readlines(string eol) { if (pimpl_->getTimeout () < 0) { - throw "Error, must be set for readlines"; + throw invalid_argument ("Error, must be set for readlines"); } size_t leneol = eol.length (); vector lines; @@ -339,3 +339,4 @@ bool Serial::getCD () { return pimpl_->getCD (); } +