diff --git a/libretroshare/src/pqi/pqifdbin.cc b/libretroshare/src/pqi/pqifdbin.cc index b413cf87b..20c2451f0 100644 --- a/libretroshare/src/pqi/pqifdbin.cc +++ b/libretroshare/src/pqi/pqifdbin.cc @@ -21,10 +21,11 @@ ******************************************************************************/ #include "util/rsprint.h" +#include "util/rsfile.h" #include "pqi/pqifdbin.h" -RsFdBinInterface::RsFdBinInterface(int file_descriptor) - : mCLintConnt(file_descriptor),mIsActive(false) +RsFdBinInterface::RsFdBinInterface(int file_descriptor, bool is_socket) + : mCLintConnt(file_descriptor),mIsSocket(is_socket),mIsActive(false) { mTotalReadBytes=0; mTotalInBufferBytes=0; @@ -53,8 +54,11 @@ void RsFdBinInterface::setSocket(int s) #else // On windows, there is no way to determine whether a socket is blocking or not, so we set it to non blocking whatsoever. - unsigned long int on = 1; - ioctlsocket(s, FIONBIO, &on); + if (mIsSocket) { + unix_fcntl_nonblock(s); + } else { + RsFileUtil::set_fd_nonblock(s); + } #endif mCLintConnt = s; @@ -82,8 +86,15 @@ int RsFdBinInterface::read_pending() char inBuffer[1025]; memset(inBuffer,0,1025); - ssize_t readbytes = read(mCLintConnt, inBuffer, sizeof(inBuffer)); // Needs read instead of recv which is only for sockets. - // Sockets should be set to non blocking by the client process. + ssize_t readbytes; +#if WINDOWS_SYS + if (mIsSocket) + // Windows needs recv for sockets + readbytes = recv(mCLintConnt, inBuffer, sizeof(inBuffer), 0); + else +#endif + readbytes = read(mCLintConnt, inBuffer, sizeof(inBuffer)); // Needs read instead of recv which is only for sockets. + // Sockets should be set to non blocking by the client process. if(readbytes == 0) { @@ -95,7 +106,11 @@ int RsFdBinInterface::read_pending() } if(readbytes < 0) { - if(errno != EWOULDBLOCK && errno != EAGAIN) + if(errno != 0 && errno != EWOULDBLOCK && errno != EAGAIN) +#ifdef WINDOWS_SYS + // A non blocking read to file descriptor gets ERROR_NO_DATA for empty data + if (mIsSocket == true || GetLastError() != ERROR_NO_DATA) +#endif RsErr() << "read() failed. Errno=" << errno ; return mTotalInBufferBytes; @@ -138,7 +153,14 @@ int RsFdBinInterface::write_pending() return mTotalOutBufferBytes; auto& p = out_buffer.front(); - int written = write(mCLintConnt, p.first, p.second); + int written; +#if WINDOWS_SYS + if (mIsSocket) + // Windows needs send for sockets + written = send(mCLintConnt, (char*) p.first, p.second, 0); + else +#endif + written = write(mCLintConnt, p.first, p.second); if(written < 0) { diff --git a/libretroshare/src/pqi/pqifdbin.h b/libretroshare/src/pqi/pqifdbin.h index df9af39a5..a3709c22e 100644 --- a/libretroshare/src/pqi/pqifdbin.h +++ b/libretroshare/src/pqi/pqifdbin.h @@ -25,7 +25,7 @@ class RsFdBinInterface: public BinInterface { public: - RsFdBinInterface(int file_descriptor); + RsFdBinInterface(int file_descriptor, bool is_socket); ~RsFdBinInterface(); // Implements BinInterface methods @@ -70,6 +70,7 @@ private: int write_pending(); int mCLintConnt; + bool mIsSocket; bool mIsActive; uint32_t mTotalReadBytes; uint32_t mTotalInBufferBytes; diff --git a/libretroshare/src/pqi/rstcpsocket.cc b/libretroshare/src/pqi/rstcpsocket.cc index ac91414b3..f42f100a2 100644 --- a/libretroshare/src/pqi/rstcpsocket.cc +++ b/libretroshare/src/pqi/rstcpsocket.cc @@ -18,12 +18,12 @@ #include "rstcpsocket.h" RsTcpSocket::RsTcpSocket(const std::string& tcp_address,uint16_t tcp_port) - :RsFdBinInterface(0),mState(DISCONNECTED),mConnectAddress(tcp_address),mConnectPort(tcp_port),mSocket(0) + :RsFdBinInterface(0, true),mState(DISCONNECTED),mConnectAddress(tcp_address),mConnectPort(tcp_port),mSocket(0) { } RsTcpSocket::RsTcpSocket() - :RsFdBinInterface(0),mState(DISCONNECTED),mConnectAddress("0.0.0.0"),mConnectPort(0),mSocket(0) + :RsFdBinInterface(0, true),mState(DISCONNECTED),mConnectAddress("0.0.0.0"),mConnectPort(0),mSocket(0) { } diff --git a/libretroshare/src/tor/TorProcess.cpp b/libretroshare/src/tor/TorProcess.cpp index 272ddb985..04f62a12a 100644 --- a/libretroshare/src/tor/TorProcess.cpp +++ b/libretroshare/src/tor/TorProcess.cpp @@ -274,8 +274,8 @@ void TorProcess::start() RsFileUtil::set_fd_nonblock(fd[STDOUT_FILENO]); RsFileUtil::set_fd_nonblock(fd[STDERR_FILENO]); - mStdOutFD = new RsFdBinInterface(fd[STDOUT_FILENO]); - mStdErrFD = new RsFdBinInterface(fd[STDERR_FILENO]); + mStdOutFD = new RsFdBinInterface(fd[STDOUT_FILENO], false); + mStdErrFD = new RsFdBinInterface(fd[STDERR_FILENO], false); } void TorProcess::tick()