This patch modifies the following files: demo/serialecho.cpp demo/serialecho.h demo/serialmain.cpp
include/cc++/serial.h src/serial.cpp This patch is committed on "dev-bcb6-arm" branch between revision tags "dev-bcb6-arm-0050" and "dev-bcb6-arm-0051". Index: demo/serialecho.cpp =================================================================== RCS file: /cvsroot/gnutelephony/testing/commoncpp2/demo/serialecho.cpp,v retrieving revision 1.1.1.1 retrieving revision 1.1.1.1.2.1 diff -u -p -r1.1.1.1 -r1.1.1.1.2.1 --- demo/serialecho.cpp 23 Apr 2005 22:08:01 -0000 1.1.1.1 +++ demo/serialecho.cpp 7 Sep 2005 19:01:20 -0000 1.1.1.1.2.1 @@ -28,45 +28,56 @@ using namespace std; SerialEcho::SerialEcho(const char *device, + unsigned long speed, + int char_bits, + Parity parity, + int stop_bits, + Flow flow, int priority, int stacksize) : TTYSession( device, priority, stacksize ) { cout << "Creating SerialEcho" << endl; - if (!(*this)) { + if (!isOpen()) { throw xError(); ::exit(1); } else { cout << "modem ready" << endl; } - interactive(false); + interactive(true); - if (setSpeed(38400)) cout << getErrorString() << endl; - if (setCharBits(8)) cout << getErrorString() << endl; - if (setParity(Serial::parityNone)) cout << getErrorString() << endl; - if (setStopBits(1)) cout << getErrorString() << endl; - if (setFlowControl(Serial::flowHard)) cout << getErrorString() << endl; + if (setSpeed(speed)) cout << getErrorString() << endl; + if (setCharBits(char_bits)) cout << getErrorString() << endl; + if (setParity(parity)) cout << getErrorString() << endl; + if (setStopBits(stop_bits)) cout << getErrorString() << endl; + if (setFlowControl(flow)) cout << getErrorString() << endl; + +// setPacketInput(16,100); cout << "config done" << endl; } void SerialEcho::run() { - char* s = new char[getBufferSize()]; - cout << "start monitor" << endl; - while (s[0] != 'X') { - while (isPending(Serial::pendingInput)) { - cout.put( TTYStream::get() ); - } - sleep(500); +#if 0 +//FILE *fout = fopen("serial.out", "wt"); + FILE *fout = stdout; + while (isPending(pendingInput)) { + fputc( TTYStream::get(), fout ); + if ( ! isPending( pendingInput, 0 ) ) fflush( fout ); } +#else + int data; + while ( ( data = TTYStream::get() ) ) { + cout.put( data ); + if ( ! isPending( pendingInput, 0 ) ) cout.flush(); + } +#endif cout << "end of monitor" << endl; - delete [] s; - exit(); } Index: demo/serialecho.h =================================================================== RCS file: /cvsroot/gnutelephony/testing/commoncpp2/demo/serialecho.h,v retrieving revision 1.1.1.1 retrieving revision 1.1.1.1.2.1 diff -u -p -r1.1.1.1 -r1.1.1.1.2.1 --- demo/serialecho.h 23 Apr 2005 22:08:01 -0000 1.1.1.1 +++ demo/serialecho.h 7 Sep 2005 19:01:20 -0000 1.1.1.1.2.1 @@ -18,7 +18,7 @@ #ifndef SERIALECHO_H #define SERIALECHO_H -#include <cc++/common.h> +#include <cc++/serial.h> #ifdef CCXX_NAMESPACES using namespace std; @@ -28,7 +28,12 @@ using namespace ost; class SerialEcho : public TTYSession { public: - SerialEcho(const char *device, + SerialEcho(const char *device, + unsigned long speed = 38400, + int char_bits = 8, + Parity parity = parityNone, + int stop_bits = 1, + Flow flow = flowHard, int priority = 0, int stacksize = 0); // Exception classes Index: demo/serialmain.cpp =================================================================== RCS file: /cvsroot/gnutelephony/testing/commoncpp2/demo/serialmain.cpp,v retrieving revision 1.1.1.1 retrieving revision 1.1.1.1.2.1 diff -u -p -r1.1.1.1 -r1.1.1.1.2.1 --- demo/serialmain.cpp 23 Apr 2005 22:08:01 -0000 1.1.1.1 +++ demo/serialmain.cpp 7 Sep 2005 19:01:20 -0000 1.1.1.1.2.1 @@ -29,16 +29,60 @@ int main(int argc, char **argv) { + const char *device = "/dev/modem2"; + unsigned long speed = 38400; + int char_bits = 8; + Serial::Parity parity = Serial::parityNone; + int stop_bits = 1; + Serial::Flow flow = Serial::flowHard; + + if ( argc > 1 ) device = argv[ 1 ]; + if ( argc > 2 ) speed = atol( argv[ 2 ] ); + if ( argc > 3 ) char_bits = atoi( argv[ 3 ] ); + if ( argc > 4 ) + switch ( *argv[ 4 ] ) { + case 'e': + case 'E': + parity = Serial::parityEven; + break; + case 'o': + case 'O': + parity = Serial::parityOdd; + break; + default: + parity = Serial::parityNone; + break; + } + if ( argc > 5 ) stop_bits = atoi( argv[ 5 ] ); + if ( argc > 6 ) + switch ( *argv[ 6 ] ) { + case 'b': + case 'B': + flow = Serial::flowBoth; + break; + case 'h': + case 'H': + flow = Serial::flowHard; + break; + case 's': + case 'S': + flow = Serial::flowSoft; + break; + default: + flow = Serial::flowNone; + break; + } + cout << "Serial Echo to TCP Sessions" << endl; SerialEcho *modem; try { - modem = new SerialEcho("/dev/modem2"); + modem = new SerialEcho(device, speed, char_bits, parity, stop_bits, flow); } catch (SerialEcho::xError *e) { cout << "Modem Error; aborting" << endl; ::exit(1); } catch (Serial *e) { cout << "Serial Error: " - << modem->getErrorString() + << e->getErrorString() << "; aborting" << endl; ::exit(1); @@ -46,7 +90,7 @@ int main(int argc, char **argv) char* b = new char[modem->getBufferSize()]; - cout << "Modem code:" << modem->start() << endl; + cout << "Modem start code: " << modem->start() << endl; while (cin >> b, b[0]) { @@ -64,4 +108,3 @@ int main(int argc, char **argv) } /** 2000 by TeleDynamics Communications Inc - [EMAIL PROTECTED]/ - Index: include/cc++/serial.h =================================================================== RCS file: /cvsroot/gnutelephony/testing/commoncpp2/include/cc++/serial.h,v retrieving revision 1.1.1.1 retrieving revision 1.1.1.1.2.1 diff -u -p -r1.1.1.1 -r1.1.1.1.2.1 --- include/cc++/serial.h 23 Apr 2005 22:08:11 -0000 1.1.1.1 +++ include/cc++/serial.h 7 Sep 2005 19:01:20 -0000 1.1.1.1.2.1 @@ -143,7 +143,7 @@ public: private: Error errid; - char *errstr; + const char *errstr; struct { @@ -160,11 +160,10 @@ private: void initSerial(void); protected: + size_t getsize; HANDLE dev; - int bufsize; - /** * Opens the serial device. * @@ -179,6 +178,13 @@ protected: void close(void); /** + * Tests if the serial device is open. + * + */ + inline bool isOpen(void) const + {return dev != INVALID_HANDLE_VALUE;} + + /** * Reads from serial device. * * @param Data Point to character buffer to receive data. Buffers MUST @@ -202,7 +208,7 @@ protected: * @param error defined serial error id. * @param errstr string or message to optionally pass. */ - Error error(Error error, char *errstr = NULL); + Error error(const Error error, const char *errstr = NULL); /** * This service is used to thow application defined serial @@ -210,7 +216,7 @@ protected: * * @param errstr string or message to pass. */ - inline void error(char *err) + inline void error(const char *err) {error(errExtended, err);}; @@ -254,17 +260,17 @@ protected: /** * Used to flush the input waiting queue. */ - void flushInput(void); + virtual void flushInput(void); /** * Used to flush any pending output data. */ - void flushOutput(void); + virtual void flushOutput(void); /** * Used to wait until all output has been sent. */ - void waitOutput(void); + virtual void waitOutput(void); /** * Used as the default destructor for ending serial I/O @@ -378,7 +384,7 @@ public: * * @return string for error message. */ - inline char *getErrorString(void) + inline const char *getErrorString(void) {return errstr;}; /** @@ -388,8 +394,7 @@ public: * * @return number of bytes used for buffering. */ - inline int getBufferSize(void) - {return bufsize;}; + virtual size_t getBufferSize(void); /** * Get the status of pending operations. This can be used to @@ -427,12 +432,12 @@ public: class __EXPORT TTYStream : protected std::streambuf, public Serial, public std::iostream { private: - int doallocate(); - friend TTYStream& crlf(TTYStream&); friend TTYStream& lfcr(TTYStream&); protected: + size_t bufsize; + char *gbuf, *pbuf; timeout_t timeout; @@ -455,6 +460,21 @@ protected: void endStream(void); /** + * Used to flush the input waiting queue. + */ + virtual void flushInput(void); + + /** + * Used to flush any pending output data. + */ + virtual void flushOutput(void); + + /** + * Used to wait until all output has been sent. + */ + virtual void waitOutput(void); + + /** * This streambuf method is used to load the input buffer * through the established tty serial port. * Index: src/serial.cpp =================================================================== RCS file: /cvsroot/gnutelephony/testing/commoncpp2/src/serial.cpp,v retrieving revision 1.1.1.1 retrieving revision 1.1.1.1.2.1 diff -u -p -r1.1.1.1 -r1.1.1.1.2.1 --- src/serial.cpp 23 Apr 2005 22:08:24 -0000 1.1.1.1 +++ src/serial.cpp 7 Sep 2005 19:01:20 -0000 1.1.1.1.2.1 @@ -130,11 +130,7 @@ Serial::Serial(const char *fname) open(fname); -#ifdef WIN32 - if(dev == INVALID_HANDLE_VALUE) -#else - if(dev < 0) -#endif + if(!isOpen()) { error(errOpenFailed); return; @@ -154,9 +150,7 @@ Serial::Serial(const char *fname) CommTimeOuts.WriteTotalTimeoutConstant = 1000; SetCommTimeouts(dev, &CommTimeOuts) ; - #else - if(!isatty(dev)) { Serial::close(); @@ -206,7 +200,6 @@ void Serial::initConfig(void) attr->fParity = true; SetCommState(dev, attr); - #else struct termios *attr = (struct termios *)current; struct termios *orig = (struct termios *)original; @@ -275,34 +268,61 @@ void Serial::initSerial(void) void Serial::endSerial(void) { + if(isOpen()) + { + if(original) #ifdef WIN32 - if(dev == INVALID_HANDLE_VALUE && original) - SetCommState(dev, (DCB *)original); + SetCommState(dev, (DCB *)original); +#else + tcsetattr(dev, TCSANOW, (struct termios *)original); +#endif + Serial::close(); + } if(current) + { +#ifdef WIN32 delete (DCB *)current; +#else + delete (struct termios *)original; +#endif + current = NULL; + } if(original) + { +#ifdef WIN32 delete (DCB *)original; #else - if(dev < 0 && original) - tcsetattr(dev, TCSANOW, (struct termios *)original); - - if(current) - delete (struct termios *)current; - - if(original) delete (struct termios *)original; #endif - Serial::close(); - - current = NULL; - original = NULL; - + original = NULL; + } } -Serial::Error Serial::error(Error err, char *errs) +Serial::Error Serial::error(const Error err, const char *errs) { + static const char * errorStrings[ ] = + { + "errSuccess", + "errOpenNoTty", + "errOpenFailed", + "errSpeedInvalid", + "errFlowInvalid", + "errParityInvalid", + "errCharsizeInvalid", + "errStopbitsInvalid", + "errOptionInvalid", + "errResourceFailure", + "errOutput", + "errInput", + "errTimeout", + "errExtended" + }; + + if(!errs) + errs = errorStrings[ err ]; + errid = err; errstr = errs; if(!err) @@ -336,13 +356,13 @@ int Serial::setPacketInput(int size, uns return 0; #else -#ifdef _PC_MAX_INPUT - int max = fpathconf(dev, _PC_MAX_INPUT); -#else - int max = MAX_INPUT; -#endif + size_t max = getBufferSize(); + struct termios *attr = (struct termios *)current; + if(size < 0) + size = 1; + if(size > max) size = max; @@ -351,7 +371,7 @@ int Serial::setPacketInput(int size, uns attr->c_cc[VTIME] = btimer; attr->c_lflag &= ~ICANON; tcsetattr(dev, TCSANOW, attr); - bufsize = size; + getsize = size; return size; #endif } @@ -362,7 +382,6 @@ int Serial::setLineInput(char newline, c // Still to be done...... return 0; #else - struct termios *attr = (struct termios *)current; attr->c_cc[VMIN] = attr->c_cc[VTIME] = 0; attr->c_cc[VEOL] = newline; @@ -370,13 +389,12 @@ int Serial::setLineInput(char newline, c attr->c_lflag |= ICANON; tcsetattr(dev, TCSANOW, attr); #ifdef _PC_MAX_CANON - bufsize = fpathconf(dev, _PC_MAX_CANON); + getsize = fpathconf(dev, _PC_MAX_CANON); #else - bufsize = MAX_CANON; + getsize = MAX_CANON; #endif - return bufsize; + return getsize; #endif - } void Serial::flushInput(void) @@ -400,7 +418,7 @@ void Serial::flushOutput(void) void Serial::waitOutput(void) { #ifdef WIN32 - + FlushFileBuffers(dev); #else tcdrain(dev); #endif @@ -410,7 +428,7 @@ Serial &Serial::operator=(const Serial & { Serial::close(); - if(ser.dev < 0) + if(!ser.isOpen()) return *this; #ifdef WIN32 @@ -435,12 +453,11 @@ Serial &Serial::operator=(const Serial & void Serial::open(const char * fname) { - #ifndef WIN32 int cflags = O_RDWR | O_NDELAY; dev = ::open(fname, cflags); - if(dev > -1) - initConfig(); + if(dev < 0) + dev = INVALID_HANDLE_VALUE; #else // open COMM device dev = CreateFile(fname, @@ -450,21 +467,20 @@ void Serial::open(const char * fname) OPEN_EXISTING, FILE_FLAG_OVERLAPPED | FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH | FILE_FLAG_NO_BUFFERING, NULL); - if(dev != INVALID_HANDLE_VALUE) - initConfig(); #endif + if(isOpen()) + initConfig(); } #ifdef WIN32 int Serial::aRead(char * Data, const int Length) { - unsigned long dwLength = 0, dwError, dwReadLength; COMSTAT cs; OVERLAPPED ol; // Return zero if handle is invalid - if(dev == INVALID_HANDLE_VALUE) + if(!isOpen()) return 0; // Read max length or only what is available @@ -552,29 +568,6 @@ void Serial::close() dev = INVALID_HANDLE_VALUE; } - - - - - - - - - - - - - - - - - - - - - - - /* const int iAsync::getTimeOuts(unsigned long & readTimeout, unsigned long & writeTimeout) { @@ -687,14 +680,12 @@ Serial::Error Serial::setSpeed(unsigned } #ifdef WIN32 - DCB * dcb = (DCB *)current; dcb->DCBlength = sizeof(DCB); GetCommState(dev, dcb); dcb->BaudRate = rate; SetCommState(dev, dcb) ; - #else struct termios *attr = (struct termios *)current; cfsetispeed(attr, rate); @@ -706,14 +697,23 @@ Serial::Error Serial::setSpeed(unsigned Serial::Error Serial::setFlowControl(Flow flow) { -#ifdef WIN32 + switch(flow) + { + case flowSoft: + case flowBoth: + case flowHard: + case flowNone: + break; + default: + return error(errFlowInvalid); + } +#ifdef WIN32 DCB * attr = (DCB *)current; attr->XonChar = ASCII_XON; attr->XoffChar = ASCII_XOFF; attr->XonLim = 100; attr->XoffLim = 100; - switch(flow) { case flowSoft: @@ -727,18 +727,12 @@ Serial::Error Serial::setFlowControl(Flo break; case flowNone: break; - default: - return error(errFlowInvalid); } - SetCommState(dev, attr); #else - struct termios *attr = (struct termios *)current; - attr->c_cflag &= ~CRTSCTS; attr->c_iflag &= ~(IXON | IXANY | IXOFF); - switch(flow) { case flowSoft: @@ -751,20 +745,24 @@ Serial::Error Serial::setFlowControl(Flo break; case flowNone: break; - default: - return error(errFlowInvalid); } - tcsetattr(dev, TCSANOW, attr); - #endif return errSuccess; } Serial::Error Serial::setStopBits(int bits) { -#ifdef WIN32 + switch(bits) + { + case 1: + case 2: + break; + default: + return error(errStopbitsInvalid); + } +#ifdef WIN32 DCB * attr = (DCB *)current; switch(bits) { @@ -774,15 +772,11 @@ Serial::Error Serial::setStopBits(int bi case 2: attr->StopBits = TWOSTOPBITS; break; - default: - return error(errStopbitsInvalid); } - SetCommState(dev, attr); #else struct termios *attr = (struct termios *)current; attr->c_cflag &= ~CSTOPB; - switch(bits) { case 1: @@ -790,8 +784,6 @@ Serial::Error Serial::setStopBits(int bi case 2: attr->c_cflag |= CSTOPB; break; - default: - return error(errStopbitsInvalid); } tcsetattr(dev, TCSANOW, attr); #endif @@ -800,25 +792,24 @@ Serial::Error Serial::setStopBits(int bi Serial::Error Serial::setCharBits(int bits) { -#ifdef WIN32 - - DCB * attr = (DCB *)current; switch(bits) { case 5: case 6: case 7: case 8: - attr->ByteSize = bits; break; default: return error(errCharsizeInvalid); } + +#ifdef WIN32 + DCB * attr = (DCB *)current; + attr->ByteSize = bits; SetCommState(dev, attr); #else struct termios *attr = (struct termios *)current; attr->c_cflag &= ~CSIZE; - switch(bits) { case 5: @@ -833,8 +824,6 @@ Serial::Error Serial::setCharBits(int bi case 8: attr->c_cflag |= CS8; break; - default: - return error(errCharsizeInvalid); } tcsetattr(dev, TCSANOW, attr); #endif @@ -843,8 +832,17 @@ Serial::Error Serial::setCharBits(int bi Serial::Error Serial::setParity(Parity parity) { -#ifdef WIN32 + switch(parity) + { + case parityEven: + case parityOdd: + case parityNone: + break; + default: + return error(errParityInvalid); + } +#ifdef WIN32 DCB * attr = (DCB *)current; switch(parity) { @@ -857,14 +855,11 @@ Serial::Error Serial::setParity(Parity p case parityNone: attr->Parity = NOPARITY; break; - default: - return error(errParityInvalid); } SetCommState(dev, attr); #else struct termios *attr = (struct termios *)current; attr->c_cflag &= ~(PARENB | PARODD); - switch(parity) { case parityEven: @@ -875,8 +870,6 @@ Serial::Error Serial::setParity(Parity p break; case parityNone: break; - default: - return error(errParityInvalid); } tcsetattr(dev, TCSANOW, attr); #endif @@ -920,6 +913,20 @@ void Serial::toggleDTR(timeout_t millise #endif } +size_t Serial::getBufferSize(void) +{ + size_t maxsize; +#ifdef _PC_MAX_INPUT + if(isOpen()) + maxsize = fpathconf(dev, _PC_MAX_INPUT); + else + maxsize = pathconf("/dev/tty", _PC_MAX_INPUT); +#else + maxsize = MAX_INPUT; +#endif + return maxsize; +} + bool Serial::isPending(Pending pending, timeout_t timeout) { #ifdef WIN32 @@ -992,7 +999,7 @@ bool Serial::isPending(Pending pending, switch(pending) { case pendingInput: - pfd.events = POLLIN; + pfd.events = POLLIN | POLLPRI; break; case pendingOutput: pfd.events = POLLOUT; @@ -1020,7 +1027,6 @@ bool Serial::isPending(Pending pending, if(pfd.revents & pfd.events) return true; - #else struct timeval tv; fd_set grp; @@ -1080,7 +1086,7 @@ TTYStream::TTYStream(const char *filenam gbuf = pbuf = NULL; timeout = to; - if(INVALID_HANDLE_VALUE != dev) + if(isOpen()) allocate(); } @@ -1111,6 +1117,9 @@ void TTYStream::endStream(void) if(bufsize) sync(); + setg(NULL, NULL, NULL); + setp(NULL, NULL); + if(gbuf) { delete[] gbuf; @@ -1127,14 +1136,12 @@ void TTYStream::endStream(void) void TTYStream::allocate(void) { - if(INVALID_HANDLE_VALUE == dev) + if(!isOpen()) return; -#ifdef _PC_MAX_INPUT - bufsize = fpathconf(dev, _PC_MAX_INPUT); -#else - bufsize = MAX_INPUT; -#endif + bufsize = getBufferSize(); + if(!getsize) + getsize = bufsize; gbuf = new char[bufsize]; pbuf = new char[bufsize]; @@ -1155,119 +1162,110 @@ void TTYStream::allocate(void) setp(pbuf, pbuf + bufsize); } -int TTYStream::doallocate() +void TTYStream::flushInput(void) { - if(bufsize) - return 0; - - allocate(); - return 1; + if(gbuf) + setg(gbuf, gbuf + bufsize, gbuf + bufsize); + + Serial::flushInput(); } -void TTYStream::interactive(bool iflag) +void TTYStream::flushOutput(void) { -#ifdef WIN32 - if(dev == INVALID_HANDLE_VALUE) -#else - if(dev < 0) -#endif - return; + if(pbuf) + setp(pbuf, pbuf + bufsize); - if(bufsize >= 1) - endStream(); + Serial::flushOutput(); +} - if(iflag) - { - // setting to unbuffered mode +void TTYStream::waitOutput(void) +{ +// while(overflow(EOF) == EOF); + overflow(EOF); - bufsize = 1; - gbuf = new char[bufsize]; + Serial::waitOutput(); +} -#if !(defined(STLPORT) || defined(__KCC)) -#if defined(__GNUC__) && (__GNUC__ < 3) - setb(0,0); -#endif -#endif - setg(gbuf, gbuf+bufsize, gbuf+bufsize); - setp(pbuf, pbuf); +void TTYStream::interactive(bool iflag) +{ + if(!isOpen()) return; - } - if(bufsize < 2) - allocate(); + // interactive is 1 else standard size + getsize = iflag ? 1 : getBufferSize(); } int TTYStream::uflow(void) { - int rlen; - unsigned char ch; + int ch = underflow(); + + if(ch != EOF && gptr()) + gbump(1); + + return (unsigned char)ch; +} - if(bufsize < 2) +int TTYStream::underflow(void) +{ + ssize_t rlen; + + if(!gptr()) { - if(timeout) + if(timeout && !Serial::isPending(pendingInput, timeout)) { - if(Serial::isPending(pendingInput, timeout)) - rlen = aRead((char *)&ch, 1); - else - rlen = -1; + setstate(failbit); + error(errTimeout); + return EOF; } - else - rlen = aRead((char *)&ch, 1); + + unsigned char ch; + + rlen = aRead((char *)&ch, 1); if(rlen < 1) { if(rlen < 0) - clear(ios::failbit | rdstate()); + { + setstate(failbit); + error(errInput); + } return EOF; } return ch; } - else - { - ch = underflow(); - gbump(1); - return ch; - } -} - -int TTYStream::underflow(void) -{ - ssize_t rlen = 1; - - if(!gptr()) - return EOF; if(gptr() < egptr()) return (unsigned char)*gptr(); - rlen = (ssize_t)((gbuf + bufsize) - eback()); if(timeout && !Serial::isPending(pendingInput, timeout)) - rlen = -1; - else - rlen = aRead((char *)eback(), rlen); + { + setstate(failbit); + error(errTimeout); + return EOF; + } + if(getsize < 1) + return EOF; + + rlen = aRead(gbuf, getsize); if(rlen < 1) { if(rlen < 0) { - clear(ios::failbit | rdstate()); + setstate(failbit); error(errInput); } return EOF; } - setg(eback(), eback(), eback() + rlen); + setg(gbuf, gbuf, gbuf + rlen); return (unsigned char) *gptr(); } int TTYStream::sync(void) { - if(bufsize > 1 && pbase() && ((pptr() - pbase()) > 0)) - { - overflow(0); - waitOutput(); - setp(pbuf, pbuf + bufsize); - } - setg(gbuf, gbuf + bufsize, gbuf + bufsize); + waitOutput(); + flushOutput(); + flushInput(); return 0; } @@ -1276,7 +1274,7 @@ int TTYStream::overflow(int c) unsigned char ch; ssize_t rlen, req; - if(bufsize < 2) + if(!pbase()) { if(c == EOF) return 0; @@ -1286,15 +1284,15 @@ int TTYStream::overflow(int c) if(rlen < 1) { if(rlen < 0) - clear(ios::failbit | rdstate()); + { + setstate(failbit); + error(errOutput); + } return EOF; } - else - return c; - } - if(!pbase()) - return EOF; + return c; + } req = (ssize_t)(pptr() - pbase()); if(req) @@ -1303,31 +1301,41 @@ int TTYStream::overflow(int c) if(rlen < 1) { if(rlen < 0) - clear(ios::failbit | rdstate()); + { + setstate(failbit); + error(errOutput); + } return EOF; } req -= rlen; } - + if(req) // memmove(pptr(), pptr() + rlen, req); memmove(pbuf, pbuf + rlen, req); setp(pbuf + req, pbuf + bufsize); - if(c != EOF) - { - *pptr() = (unsigned char)c; - pbump(1); - } + if(c == EOF) + return 0; + + *pptr() = (unsigned char)c; + pbump(1); + return c; } bool TTYStream::isPending(Pending pending, timeout_t timer) { -// if(pending == pendingInput && in_avail()) -// return true; -// else if(pending == pendingOutput) -// flush(); + switch ( pending ) + { + case pendingInput: + if(in_avail()) + return true; + break; + case pendingOutput: + flush(); + break; + } return Serial::isPending(pending, timer); } @@ -1352,11 +1360,7 @@ TTYStream() void ttystream::close(void) { -#ifdef WIN32 - if (INVALID_HANDLE_VALUE == dev) -#else - if(dev < 0) -#endif + if (!isOpen()) return; endStream(); @@ -1372,7 +1376,7 @@ void ttystream::open(const char *name) size_t namelen; long opt; - if (INVALID_HANDLE_VALUE != dev) + if (isOpen()) { restore(); close(); @@ -1408,7 +1412,7 @@ void ttystream::open(const char *name) Serial::open(pathname); - if(INVALID_HANDLE_VALUE == dev) + if(!isOpen()) { error(errOpenFailed); return; @@ -1492,6 +1496,7 @@ Thread(pri, stack), TTYStream(filename) TTYSession::~TTYSession() { terminate(); + endStream(); endSerial(); } @@ -1508,11 +1513,7 @@ detect_disconnect(true) next = prev = NULL; service = NULL; -#ifdef WIN32 - if(INVALID_HANDLE_VALUE != dev) -#else - if(dev > -1) -#endif + if(isOpen()) { setError(false); service = svc; _______________________________________________ Bug-commoncpp mailing list Bug-commoncpp@gnu.org http://lists.gnu.org/mailman/listinfo/bug-commoncpp