diff options
Diffstat (limited to 'src/stdiodevice.cc')
-rw-r--r-- | src/stdiodevice.cc | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/src/stdiodevice.cc b/src/stdiodevice.cc new file mode 100644 index 0000000..9eb5f9c --- /dev/null +++ b/src/stdiodevice.cc @@ -0,0 +1,111 @@ +/** -------------------------------------------------------------------- + * @file stdiodevice.cc + * @brief Implementation of the StdIODevice class + * @author Andreas Aardal Hanssen + * @date 2003/2023 + * ---------------------------------------------------------------- **/ +#include "stdiodevice.h" +#include <string> + +#include <sys/types.h> +#include <sys/ioctl.h> +#include <sys/select.h> +#include <sys/time.h> +#include <unistd.h> +#include <errno.h> + +using namespace ::std; +using namespace ::Binc; + +//------------------------------------------------------------------------ +StdIODevice::StdIODevice(int f) : IODevice(f) +{ +} + +//------------------------------------------------------------------------ +StdIODevice::~StdIODevice(void) +{ +} + +//------------------------------------------------------------------------ +string StdIODevice::service(void) const +{ + return "client"; +} + +//------------------------------------------------------------------------ +bool StdIODevice::canRead(void) const +{ + size_t bytes; + return ioctl(fileno(stdin), FIONREAD, (char *) &bytes) > 0; +} + +//------------------------------------------------------------------------ +bool StdIODevice::waitForWrite(void) const +{ + fd_set writeMask; + FD_ZERO(&writeMask); + FD_SET(fileno(stdout), &writeMask); + + struct timeval tv; + tv.tv_sec = timeout; + tv.tv_usec = 0; + + int result = select(fileno(stdout) + 1, 0, &writeMask, 0, timeout ? &tv : 0); + if (result == 0) error = Timeout; + return result > 0; +} + +//------------------------------------------------------------------------ +bool StdIODevice::waitForRead(void) const +{ + fd_set readMask; + FD_ZERO(&readMask); + FD_SET(fileno(stdin), &readMask); + + struct timeval tv; + tv.tv_sec = timeout; + tv.tv_usec = 0; + + int result = select(fileno(stdin) + 1, &readMask, 0, 0, timeout ? &tv : 0); + if (result == 0) error = Timeout; + return result > 0; +} + +//------------------------------------------------------------------------ +IODevice::WriteResult StdIODevice::write(void) +{ + for (;;) { + ssize_t wrote = ::write(fileno(stdout), outputBuffer.str().c_str(), + outputBuffer.getSize()); + + if (wrote == -1) { + if (errno == EINTR) + continue; + else + return WriteError; + } + + outputBuffer.popString(wrote); + + if (wrote == (ssize_t) outputBuffer.getSize()) + return WriteDone; + return WriteWait; + } +} + +//------------------------------------------------------------------------ +bool StdIODevice::fillInputBuffer(void) +{ + if (!waitForRead()) + return false; + + char buf[4096]; + ssize_t red = read(fileno(stdin), buf, sizeof(buf) - 1); + if (red <= 0) + return false; + + buf[red] = '\0'; + inputBuffer << buf; + return true; +} |