Skip to content

Commit a9cef39

Browse files
committed
fcntl patch for UNIX platforms; code compiled and tests run on Mac & Win
1 parent 15d960b commit a9cef39

3 files changed

Lines changed: 47 additions & 9 deletions

File tree

‎Net/include/Poco/Net/SocketDefs.h‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@
148148
#include <errno.h>
149149
#include <sys/types.h>
150150
#include <sys/socket.h>
151+
#include <fcntl.h>
151152
#if POCO_OS != POCO_OS_HPUX
152153
#include <sys/select.h>
153154
#endif
@@ -170,6 +171,7 @@
170171
#define POCO_INVALID_SOCKET -1
171172
#define poco_socket_t int
172173
#define poco_socklen_t socklen_t
174+
#define poco_fcntl_request_t int
173175
#if defined(POCO_OS_FAMILY_BSD)
174176
#define poco_ioctl_request_t unsigned long
175177
#else

‎Net/include/Poco/Net/SocketImpl.h‎

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -352,8 +352,6 @@ class Net_API SocketImpl: public Poco::RefCountedObject
352352

353353
virtual bool getBlocking() const;
354354
/// Returns the blocking mode of the socket.
355-
/// This method will only work if the blocking modes of
356-
/// the socket are changed via the setBlocking method!
357355

358356
virtual bool secure() const;
359357
/// Returns true iff the socket's connection is secure
@@ -372,6 +370,14 @@ class Net_API SocketImpl: public Poco::RefCountedObject
372370
void ioctl(poco_ioctl_request_t request, void* arg);
373371
/// A wrapper for the ioctl system call.
374372

373+
#if defined(POCO_OS_FAMILY_UNIX)
374+
int fcntl(poco_fcntl_request_t request);
375+
/// A wrapper for the fcntl system call.
376+
377+
int fcntl(poco_fcntl_request_t request, long arg);
378+
/// A wrapper for the fcntl system call.
379+
#endif
380+
375381
bool initialized() const;
376382
/// Returns true iff the underlying socket is initialized.
377383

‎Net/src/SocketImpl.cpp‎

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ int SocketImpl::sendBytes(const void* buffer, int length, int flags)
293293
if (_sockfd == POCO_INVALID_SOCKET) throw InvalidSocketException();
294294
rc = ::send(_sockfd, reinterpret_cast<const char*>(buffer), length, flags);
295295
}
296-
while (rc < 0 && lastError() == POCO_EINTR);
296+
while (_blocking && rc < 0 && lastError() == POCO_EINTR);
297297
if (rc < 0) error();
298298
return rc;
299299
}
@@ -315,11 +315,13 @@ int SocketImpl::receiveBytes(void* buffer, int length, int flags)
315315
if (_sockfd == POCO_INVALID_SOCKET) throw InvalidSocketException();
316316
rc = ::recv(_sockfd, reinterpret_cast<char*>(buffer), length, flags);
317317
}
318-
while (rc < 0 && lastError() == POCO_EINTR);
318+
while (_blocking && rc < 0 && lastError() == POCO_EINTR);
319319
if (rc < 0)
320320
{
321321
int err = lastError();
322-
if (err == POCO_EAGAIN || err == POCO_ETIMEDOUT)
322+
if (err == POCO_EAGAIN && !_blocking)
323+
;
324+
else if (err == POCO_EAGAIN || err == POCO_ETIMEDOUT)
323325
throw TimeoutException();
324326
else
325327
error(err);
@@ -340,7 +342,7 @@ int SocketImpl::sendTo(const void* buffer, int length, const SocketAddress& addr
340342
rc = ::sendto(_sockfd, reinterpret_cast<const char*>(buffer), length, flags, address.addr(), address.length());
341343
#endif
342344
}
343-
while (rc < 0 && lastError() == POCO_EINTR);
345+
while (_blocking && rc < 0 && lastError() == POCO_EINTR);
344346
if (rc < 0) error();
345347
return rc;
346348
}
@@ -365,15 +367,17 @@ int SocketImpl::receiveFrom(void* buffer, int length, SocketAddress& address, in
365367
if (_sockfd == POCO_INVALID_SOCKET) throw InvalidSocketException();
366368
rc = ::recvfrom(_sockfd, reinterpret_cast<char*>(buffer), length, flags, pSA, &saLen);
367369
}
368-
while (rc < 0 && lastError() == POCO_EINTR);
370+
while (_blocking && rc < 0 && lastError() == POCO_EINTR);
369371
if (rc >= 0)
370372
{
371373
address = SocketAddress(pSA, saLen);
372374
}
373375
else
374376
{
375377
int err = lastError();
376-
if (err == POCO_EAGAIN || err == POCO_ETIMEDOUT)
378+
if (err == POCO_EAGAIN && !_blocking)
379+
;
380+
else if (err == POCO_EAGAIN || err == POCO_ETIMEDOUT)
377381
throw TimeoutException();
378382
else
379383
error(err);
@@ -851,9 +855,17 @@ bool SocketImpl::getBroadcast()
851855

852856
void SocketImpl::setBlocking(bool flag)
853857
{
858+
#if !defined(POCO_OS_FAMILY_UNIX)
854859
int arg = flag ? 0 : 1;
855860
ioctl(FIONBIO, arg);
856-
_blocking = flag;
861+
#else
862+
int arg = fcntl(F_GETFL);
863+
long flags = arg & ~O_NONBLOCK;
864+
if (!flag)
865+
flags |= O_NONBLOCK;
866+
(void) fcntl(F_SETFL, flags);
867+
#endif
868+
_blocking = flag;
857869
}
858870

859871

@@ -907,6 +919,24 @@ void SocketImpl::ioctl(poco_ioctl_request_t request, void* arg)
907919
}
908920

909921

922+
#if defined(POCO_OS_FAMILY_UNIX)
923+
int SocketImpl::fcntl(poco_fcntl_request_t request)
924+
{
925+
int rc = ::fcntl(_sockfd, request);
926+
if (rc == -1) error();
927+
return rc;
928+
}
929+
930+
931+
int SocketImpl::fcntl(poco_fcntl_request_t request, long arg)
932+
{
933+
int rc = ::fcntl(_sockfd, request, arg);
934+
if (rc == -1) error();
935+
return rc;
936+
}
937+
#endif
938+
939+
910940
void SocketImpl::reset(poco_socket_t aSocket)
911941
{
912942
_sockfd = aSocket;

0 commit comments

Comments
 (0)