/** * @file stdiodevice.cc * @brief Implementation of the StdIODevice class * @author Andreas Aardal Hanssen * @date 2003/2023 */ #include "stdiodevice.h" #include #include #include #include #include #include #include using namespace Binc; StdIODevice::StdIODevice(int f) : IODevice(f) {} StdIODevice::~StdIODevice() {} std::string StdIODevice::service() const { return "client"; } bool StdIODevice::canRead() const { size_t bytes; return ioctl(fileno(stdin), FIONREAD, (char *)&bytes) > 0; } bool StdIODevice::waitForWrite() 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, nullptr, &writeMask, nullptr, timeout ? &tv : nullptr); if (result == 0) error = Error::Timeout; return result > 0; } bool StdIODevice::waitForRead() 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, nullptr, nullptr, timeout ? &tv : nullptr); if (result == 0) error = Error::Timeout; return result > 0; } IODevice::WriteResult StdIODevice::write() { 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() { 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; }