Index: src/OFExceptions.h ================================================================== --- src/OFExceptions.h +++ src/OFExceptions.h @@ -273,10 +273,20 @@ */ @interface OFWriteFailedException: OFReadOrWriteFailedException {} /** * \return An error message for the exception as a C String */ +- (const char*)cString; +@end + +/** + * An OFException indicating that setting an option failed. + */ +@interface OFSetOptionFailedException: OFException {} +/*** + * \return An error message for the exception as a C string. + */ - (const char*)cString; @end /** * An OFException indicating a socket is not connected or bound. Index: src/OFExceptions.m ================================================================== --- src/OFExceptions.m +++ src/OFExceptions.m @@ -293,10 +293,23 @@ "object of class %s!", req_items, req_size, [object name]); else asprintf(&string, "Failed to write %zu bytes in object of " "class %s!", req_size, [object name]); + return string; +} +@end + +@implementation OFSetOptionFailedException +- (const char*)cString +{ + if (string != NULL) + return string; + + asprintf(&string, "Setting an option for an object of type type %s " + "failed!", [object name]); + return string; } @end @implementation OFNotConnectedException Index: src/OFTCPSocket.h ================================================================== --- src/OFTCPSocket.h +++ src/OFTCPSocket.h @@ -91,10 +91,20 @@ /** * Accept an incoming connection. */ - (OFTCPSocket*)accept; +/** + * Enables/disables non-blocking I/O. + */ +- setBlocking: (BOOL)enable; + +/** + * Enable or disable keep alives for the connection. + */ +- enableKeepAlives: (BOOL)enable; + /** * Closes the socket. */ - close; @end Index: src/OFTCPSocket.m ================================================================== --- src/OFTCPSocket.m +++ src/OFTCPSocket.m @@ -13,10 +13,11 @@ #import #import #import #import +#import #import "OFTCPSocket.h" #import "OFExceptions.h" #ifndef _WIN32 /* FIXME */ @@ -259,10 +260,37 @@ @throw [OFNotConnectedException newWithObject: self]; return [self writeNBytes: strlen(str) fromBuffer: (const uint8_t*)str]; } + +- setBlocking: (BOOL)enable +{ + int flags; + + if ((flags = fcntl(sock, F_GETFL)) < 0) + @throw [OFSetOptionFailedException newWithObject: self]; + + if (enable) + flags &= ~O_NONBLOCK; + else + flags |= O_NONBLOCK; + + if (fcntl(sock, F_SETFL, flags) < 0) + @throw [OFSetOptionFailedException newWithObject: self]; + + return self; +} + +- enableKeepAlives: (BOOL)enable +{ + if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &enable, + sizeof(enable)) != 0) + @throw [OFSetOptionFailedException newWithObject: self]; + + return self; +} - close { if (sock < 0) @throw [OFNotConnectedException newWithObject: self];