@@ -18,14 +18,19 @@ #include "config.h" #include #include + +#ifdef HAVE_FCNTL_H +# include +#endif #import "OFStreamSocket.h" #import "OFInitializationFailedException.h" +#import "OFNotImplementedException.h" #import "OFNotOpenException.h" #import "OFOutOfRangeException.h" #import "OFReadFailedException.h" #import "OFSetOptionFailedException.h" #import "OFWriteFailedException.h" @@ -120,22 +125,83 @@ #endif return (size_t)bytesWritten; } -#ifdef OF_WINDOWS - (void)setBlocking: (bool)enable { - u_long v = enable; +#if defined(HAVE_FCNTL) + bool readImplemented = false, writeImplemented = false; + + @try { + int readFlags; + + readFlags = fcntl([self fileDescriptorForReading], F_GETFL); + + readImplemented = true; + + if (readFlags == -1) + @throw [OFSetOptionFailedException + exceptionWithStream: self + errNo: errno]; + + if (enable) + readFlags &= ~O_NONBLOCK; + else + readFlags |= O_NONBLOCK; + + if (fcntl([self fileDescriptorForReading], F_SETFL, + readFlags) == -1) + @throw [OFSetOptionFailedException + exceptionWithStream: self + errNo: errno]; + } @catch (OFNotImplementedException *e) { + } + + @try { + int writeFlags; + + writeFlags = fcntl([self fileDescriptorForWriting], F_GETFL); + + writeImplemented = true; + + if (writeFlags == -1) + @throw [OFSetOptionFailedException + exceptionWithStream: self + errNo: errno]; + + if (enable) + writeFlags &= ~O_NONBLOCK; + else + writeFlags |= O_NONBLOCK; + + if (fcntl([self fileDescriptorForWriting], F_SETFL, + writeFlags) == -1) + @throw [OFSetOptionFailedException + exceptionWithStream: self + errNo: errno]; + } @catch (OFNotImplementedException *e) { + } + + if (!readImplemented && !writeImplemented) + @throw [OFNotImplementedException exceptionWithSelector: _cmd + object: self]; + _blocking = enable; +#elif defined(OF_WINDOWS) + u_long v = enable; if (ioctlsocket(_socket, FIONBIO, &v) == SOCKET_ERROR) @throw [OFSetOptionFailedException exceptionWithStream: self errNo: of_socket_errno()]; -} + + _blocking = enable; +#else + OF_UNRECOGNIZED_SELECTOR #endif +} - (int)fileDescriptorForReading { #ifndef OF_WINDOWS return _socket;