Index: src/OFExceptions.h ================================================================== --- src/OFExceptions.h +++ src/OFExceptions.h @@ -400,5 +400,62 @@ /** * \return The port on the host to which the connection failed */ - (uint16_t)port; @end + +/** + * An OFException indicating that binding the socket failed. + */ +@interface OFBindFailedException: OFException +{ + char *host; + uint16_t port; + int family; +} + +/** + * \param h The host on which binding failed + * \param p The port on which binding failed + * \param f The family for which binnding failed + * \return A new bind failed exception + */ ++ newWithObject: (id)obj + andHost: (const char*)h + andPort: (uint16_t)p + andFamily: (int)f; + +/** + * Initializes an already allocated bind failed exception. + * + * \param h The host on which binding failed + * \param p The port on which binding failed + * \param f The family for which binnding failed + * \return An initialized bind failed exception + */ +- initWithObject: (id)obj + andHost: (const char*)h + andPort: (uint16_t)p + andFamily: (int)f; + +- free; + +/** + * \return An error message for the exception as a C string. + */ +- (const char*)cString; + +/** + * \return The host on which binding failed + */ +- (const char*)host; + +/** + * \return The port on which binding failed + */ +- (uint16_t)port; + +/** + * \return The family for which binding failed + */ +- (int)family; +@end Index: src/OFExceptions.m ================================================================== --- src/OFExceptions.m +++ src/OFExceptions.m @@ -456,5 +456,66 @@ - (uint16_t)port { return port; } @end + +@implementation OFBindFailedException ++ newWithObject: (id)obj + andHost: (const char*)h + andPort: (uint16_t)p + andFamily: (int)f +{ + return [self newWithObject: obj + andHost: h + andPort: p + andFamily: f]; +} + +- initWithObject: (id)obj + andHost: (const char*)h + andPort: (uint16_t)p + andFamily: (int)f +{ + if ((self = [super initWithObject: obj])) { + host = (h != NULL ? strdup(h) : NULL); + port = p; + family = f; + } + + return self; +} + +- free +{ + if (host != NULL) + free(host); + + return [super free]; +} + +- (const char*)cString +{ + if (string != NULL) + return string; + + asprintf(&string, "Binding to port %d on %s using family %d failed in " + "object of type %s!", port, host, family, [object name]); + + return string; +} + +- (const char*)host +{ + return host; +} + +- (uint16_t)port +{ + return port; +} + +- (int)family +{ + return family; +} +@end Index: src/OFTCPSocket.m ================================================================== --- src/OFTCPSocket.m +++ src/OFTCPSocket.m @@ -115,14 +115,15 @@ @throw [OFInvalidPortException newWithObject: self]; if (sock >= 0) @throw [OFAlreadyConnectedException newWithObject: self]; - if ((sock = socket(family, SOCK_STREAM, 0)) < 0) { - /* FIXME: Throw exception */ - return nil; - } + if ((sock = socket(family, SOCK_STREAM, 0)) < 0) + @throw [OFBindFailedException newWithObject: self + andHost: host + andPort: port + andFamily: family]; memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = family; hints.ai_socktype = SOCK_STREAM; @@ -133,13 +134,15 @@ newWithObject: self andNode: host andService: portstr]; if (bind(sock, res->ai_addr, res->ai_addrlen) < 0) { - /* FIXME: Throw exception */ freeaddrinfo(res); - return nil; + @throw [OFBindFailedException newWithObject: self + andHost: host + andPort: port + andFamily: family]; } freeaddrinfo(res); return self;