@@ -36,10 +36,11 @@ #import "OFInitializationFailedException.h" #import "OFInvalidArgumentException.h" #import "OFNotOpenException.h" #import "OFOutOfRangeException.h" #import "OFReadFailedException.h" +#import "OFSetOptionFailedException.h" #import "OFWriteFailedException.h" #import "socket.h" #import "socket_helpers.h" #import "resolver.h" @@ -255,10 +256,11 @@ - (instancetype)init { self = [super init]; _socket = INVALID_SOCKET; + _blocking = true; return self; } - (void)dealloc @@ -271,10 +273,48 @@ - (id)copy { return [self retain]; } + +- (bool)isBlocking +{ + return _blocking; +} + +- (void)setBlocking: (bool)enable +{ +#if defined(HAVE_FCNTL) + int flags = fcntl(_socket, F_GETFL); + + if (flags == -1) + @throw [OFSetOptionFailedException exceptionWithObject: self + errNo: errno]; + + if (enable) + flags &= ~O_NONBLOCK; + else + flags |= O_NONBLOCK; + + if (fcntl(_socket, F_SETFL, flags) == -1) + @throw [OFSetOptionFailedException exceptionWithObject: self + errNo: errno]; + + _blocking = enable; +#elif defined(OF_WINDOWS) + u_long v = enable; + + if (ioctlsocket(_socket, FIONBIO, &v) == SOCKET_ERROR) + @throw [OFSetOptionFailedException + exceptionWithObject: self + errNo: of_socket_errno()]; + + _blocking = enable; +#else + OF_UNRECOGNIZED_SELECTOR +#endif +} - (uint16_t)bindToHost: (OFString *)host port: (uint16_t)port { of_resolver_result_t **results; @@ -301,10 +341,12 @@ @throw [OFBindFailedException exceptionWithHost: host port: port socket: self errNo: of_socket_errno()]; + + _blocking = true; #if SOCK_CLOEXEC == 0 && defined(HAVE_FCNTL) && defined(FD_CLOEXEC) if ((flags = fcntl(_socket, F_GETFD, 0)) != -1) fcntl(_socket, F_SETFD, flags | FD_CLOEXEC); #endif