@@ -15,10 +15,12 @@ */ #define __NO_EXT_QNX #include "config.h" + +#include #import "OFKernelEventObserver.h" #import "OFKernelEventObserver+Private.h" #import "OFArray.h" #import "OFDataArray.h" @@ -99,11 +101,11 @@ - init { self = [super init]; @try { -#if !defined(OF_HAVE_PIPE) && !defined(OF_WII) +#if !defined(OF_HAVE_PIPE) && !defined(OF_WII) && !defined(OF_NINTENDO_3DS) socklen_t cancelAddrLen; #endif _readObjects = [[OFMutableArray alloc] init]; _writeObjects = [[OFMutableArray alloc] init]; @@ -120,28 +122,44 @@ exceptionWithClass: [self class]]; _cancelAddr.sin_family = AF_INET; _cancelAddr.sin_port = 0; _cancelAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); - # ifdef OF_WII _cancelAddr.sin_len = 8; - /* The Wii does not accept port 0 as "choose any free port" */ - _cancelAddr.sin_port = of_socket_port_find(SOCK_DGRAM); # endif +# if !defined(OF_WII) && !defined(OF_NINTENDO_3DS) if (bind(_cancelFD[0], (struct sockaddr*)&_cancelAddr, - sizeof(_cancelAddr))) + sizeof(_cancelAddr)) != 0) @throw [OFInitializationFailedException exceptionWithClass: [self class]]; -# ifndef OF_WII cancelAddrLen = sizeof(_cancelAddr); if (of_getsockname(_cancelFD[0], (struct sockaddr*)&_cancelAddr, &cancelAddrLen) != 0) @throw [OFInitializationFailedException exceptionWithClass: [self class]]; +# else + for (;;) { + uint16_t rnd = 0; + int ret; + + while (rnd < 1024) + rnd = (uint16_t)rand(); + + _cancelAddr.sin_port = OF_BSWAP16_IF_LE(rnd); + ret = bind(_cancelFD[0], (struct sockaddr*)&_cancelAddr, + sizeof(_cancelAddr)); + + if (ret == 0) + break; + + if (of_socket_errno() != EADDRINUSE) + @throw [OFInitializationFailedException + exceptionWithClass: [self class]]; + } # endif #endif #ifdef OF_HAVE_THREADS _mutex = [[OFMutex alloc] init]; @@ -162,14 +180,10 @@ { close(_cancelFD[0]); if (_cancelFD[1] != _cancelFD[0]) close(_cancelFD[1]); -#ifdef OF_WII - of_socket_port_free(_cancelAddr.sin_port, SOCK_DGRAM); -#endif - [_readObjects release]; [_writeObjects release]; #ifdef OF_HAVE_THREADS [_mutex release];