From a9cef39021f56b5ff8bbb6e6491c8bc04b583e80 Mon Sep 17 00:00:00 2001 From: Aleksandar Fabijanic Date: Thu, 26 Apr 2012 02:57:16 +0000 Subject: [PATCH] fcntl patch for UNIX platforms; code compiled and tests run on Mac & Win --- Net/include/Poco/Net/SocketDefs.h | 2 ++ Net/include/Poco/Net/SocketImpl.h | 10 +++++-- Net/src/SocketImpl.cpp | 44 ++++++++++++++++++++++++++----- 3 files changed, 47 insertions(+), 9 deletions(-) diff --git a/Net/include/Poco/Net/SocketDefs.h b/Net/include/Poco/Net/SocketDefs.h index 1f0ecda58..c562469ed 100644 --- a/Net/include/Poco/Net/SocketDefs.h +++ b/Net/include/Poco/Net/SocketDefs.h @@ -148,6 +148,7 @@ #include #include #include +#include #if POCO_OS != POCO_OS_HPUX #include #endif @@ -170,6 +171,7 @@ #define POCO_INVALID_SOCKET -1 #define poco_socket_t int #define poco_socklen_t socklen_t +#define poco_fcntl_request_t int #if defined(POCO_OS_FAMILY_BSD) #define poco_ioctl_request_t unsigned long #else diff --git a/Net/include/Poco/Net/SocketImpl.h b/Net/include/Poco/Net/SocketImpl.h index c5aaeda37..7674fa58d 100644 --- a/Net/include/Poco/Net/SocketImpl.h +++ b/Net/include/Poco/Net/SocketImpl.h @@ -352,8 +352,6 @@ public: virtual bool getBlocking() const; /// Returns the blocking mode of the socket. - /// This method will only work if the blocking modes of - /// the socket are changed via the setBlocking method! virtual bool secure() const; /// Returns true iff the socket's connection is secure @@ -372,6 +370,14 @@ public: void ioctl(poco_ioctl_request_t request, void* arg); /// A wrapper for the ioctl system call. +#if defined(POCO_OS_FAMILY_UNIX) + int fcntl(poco_fcntl_request_t request); + /// A wrapper for the fcntl system call. + + int fcntl(poco_fcntl_request_t request, long arg); + /// A wrapper for the fcntl system call. +#endif + bool initialized() const; /// Returns true iff the underlying socket is initialized. diff --git a/Net/src/SocketImpl.cpp b/Net/src/SocketImpl.cpp index bab0703c4..800a4cac2 100644 --- a/Net/src/SocketImpl.cpp +++ b/Net/src/SocketImpl.cpp @@ -293,7 +293,7 @@ int SocketImpl::sendBytes(const void* buffer, int length, int flags) if (_sockfd == POCO_INVALID_SOCKET) throw InvalidSocketException(); rc = ::send(_sockfd, reinterpret_cast(buffer), length, flags); } - while (rc < 0 && lastError() == POCO_EINTR); + while (_blocking && rc < 0 && lastError() == POCO_EINTR); if (rc < 0) error(); return rc; } @@ -315,11 +315,13 @@ int SocketImpl::receiveBytes(void* buffer, int length, int flags) if (_sockfd == POCO_INVALID_SOCKET) throw InvalidSocketException(); rc = ::recv(_sockfd, reinterpret_cast(buffer), length, flags); } - while (rc < 0 && lastError() == POCO_EINTR); + while (_blocking && rc < 0 && lastError() == POCO_EINTR); if (rc < 0) { int err = lastError(); - if (err == POCO_EAGAIN || err == POCO_ETIMEDOUT) + if (err == POCO_EAGAIN && !_blocking) + ; + else if (err == POCO_EAGAIN || err == POCO_ETIMEDOUT) throw TimeoutException(); else error(err); @@ -340,7 +342,7 @@ int SocketImpl::sendTo(const void* buffer, int length, const SocketAddress& addr rc = ::sendto(_sockfd, reinterpret_cast(buffer), length, flags, address.addr(), address.length()); #endif } - while (rc < 0 && lastError() == POCO_EINTR); + while (_blocking && rc < 0 && lastError() == POCO_EINTR); if (rc < 0) error(); return rc; } @@ -365,7 +367,7 @@ int SocketImpl::receiveFrom(void* buffer, int length, SocketAddress& address, in if (_sockfd == POCO_INVALID_SOCKET) throw InvalidSocketException(); rc = ::recvfrom(_sockfd, reinterpret_cast(buffer), length, flags, pSA, &saLen); } - while (rc < 0 && lastError() == POCO_EINTR); + while (_blocking && rc < 0 && lastError() == POCO_EINTR); if (rc >= 0) { address = SocketAddress(pSA, saLen); @@ -373,7 +375,9 @@ int SocketImpl::receiveFrom(void* buffer, int length, SocketAddress& address, in else { int err = lastError(); - if (err == POCO_EAGAIN || err == POCO_ETIMEDOUT) + if (err == POCO_EAGAIN && !_blocking) + ; + else if (err == POCO_EAGAIN || err == POCO_ETIMEDOUT) throw TimeoutException(); else error(err); @@ -851,9 +855,17 @@ bool SocketImpl::getBroadcast() void SocketImpl::setBlocking(bool flag) { +#if !defined(POCO_OS_FAMILY_UNIX) int arg = flag ? 0 : 1; ioctl(FIONBIO, arg); - _blocking = flag; +#else + int arg = fcntl(F_GETFL); + long flags = arg & ~O_NONBLOCK; + if (!flag) + flags |= O_NONBLOCK; + (void) fcntl(F_SETFL, flags); +#endif + _blocking = flag; } @@ -907,6 +919,24 @@ void SocketImpl::ioctl(poco_ioctl_request_t request, void* arg) } +#if defined(POCO_OS_FAMILY_UNIX) +int SocketImpl::fcntl(poco_fcntl_request_t request) +{ + int rc = ::fcntl(_sockfd, request); + if (rc == -1) error(); + return rc; +} + + +int SocketImpl::fcntl(poco_fcntl_request_t request, long arg) +{ + int rc = ::fcntl(_sockfd, request, arg); + if (rc == -1) error(); + return rc; +} +#endif + + void SocketImpl::reset(poco_socket_t aSocket) { _sockfd = aSocket;