ObjFW  Check-in [4cecf82254]

Overview
Comment:Special cases for the Wii's weird network stack

This fixes the tests on Wii.

Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 4cecf8225477979e0b5aa5948838a7b2ae3c0b9c5e33841db9639861ba00a556
User & Date: js on 2015-10-04 11:11:28
Other Links: manifest | tags
Context
2015-10-04
11:30
Better length checks for write / send calls check-in: fc73801932 user: js tags: trunk
11:11
Special cases for the Wii's weird network stack check-in: 4cecf82254 user: js tags: trunk
2015-10-03
14:23
Add missing include for Nintendo DS check-in: a83e398ae4 user: js tags: trunk
Changes

Modified src/OFKernelEventObserver.m from [b099b55bf8] to [b0c771eac2].

58
59
60
61
62
63
64





65
66
67
68
69
70
71
enum {
	QUEUE_ADD = 0,
	QUEUE_REMOVE = 1,
	QUEUE_READ = 0,
	QUEUE_WRITE = 2
};
#define QUEUE_ACTION (QUEUE_ADD | QUEUE_REMOVE)






@implementation OFKernelEventObserver
+ (void)initialize
{
	if (self != [OFKernelEventObserver class])
		return;








>
>
>
>
>







58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
enum {
	QUEUE_ADD = 0,
	QUEUE_REMOVE = 1,
	QUEUE_READ = 0,
	QUEUE_WRITE = 2
};
#define QUEUE_ACTION (QUEUE_ADD | QUEUE_REMOVE)

#ifdef __wii__
/* FIXME: Add a port registry for Wii */
static uint16_t freePort = 65535;
#endif

@implementation OFKernelEventObserver
+ (void)initialize
{
	if (self != [OFKernelEventObserver class])
		return;

124
125
126
127
128
129
130

131
132
133
134
135
136
137
138
139
			    exceptionWithClass: [self class]];

		_cancelAddr.sin_family = AF_INET;
		_cancelAddr.sin_port = 0;
		_cancelAddr.sin_addr.s_addr = inet_addr("127.0.0.1");

# ifdef __wii__

		/* The Wii does not accept port 0 as "choose any free port" */
		_cancelAddr.sin_port = 65535;
# endif

		if (bind(_cancelFD[0], (struct sockaddr*)&_cancelAddr,
		    sizeof(_cancelAddr)))
			@throw [OFInitializationFailedException
			    exceptionWithClass: [self class]];








>

|







129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
			    exceptionWithClass: [self class]];

		_cancelAddr.sin_family = AF_INET;
		_cancelAddr.sin_port = 0;
		_cancelAddr.sin_addr.s_addr = inet_addr("127.0.0.1");

# ifdef __wii__
		_cancelAddr.sin_len = 8;
		/* The Wii does not accept port 0 as "choose any free port" */
		_cancelAddr.sin_port = freePort--;
# endif

		if (bind(_cancelFD[0], (struct sockaddr*)&_cancelAddr,
		    sizeof(_cancelAddr)))
			@throw [OFInitializationFailedException
			    exceptionWithClass: [self class]];

351
352
353
354
355
356
357

358
359




360
361
362
363
364
365
366
}

- (void)cancel
{
#ifdef OF_HAVE_PIPE
	OF_ENSURE(write(_cancelFD[1], "", 1) > 0);
#else

	OF_ENSURE(sendto(_cancelFD[1], "", 1, 0, (struct sockaddr*)&_cancelAddr,
	    sizeof(_cancelAddr)) > 0);




#endif
}

- (void)OF_processReadBuffers
{
	id const *objects = [_readObjects objects];
	size_t i, count = [_readObjects count];







>
|
|
>
>
>
>







357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
}

- (void)cancel
{
#ifdef OF_HAVE_PIPE
	OF_ENSURE(write(_cancelFD[1], "", 1) > 0);
#else
# ifndef __wii__
	OF_ENSURE(sendto(_cancelFD[1], "", 1, 0,
	    (struct sockaddr*)&_cancelAddr, sizeof(_cancelAddr)) > 0);
# else
	OF_ENSURE(sendto(_cancelFD[1], "", 1, 0,
	    (struct sockaddr*)&_cancelAddr, 8) > 0);
# endif
#endif
}

- (void)OF_processReadBuffers
{
	id const *objects = [_readObjects objects];
	size_t i, count = [_readObjects count];

Modified src/OFKernelEventObserver_poll.m from [948bc3a27e] to [85d67fd51b].

183
184
185
186
187
188
189

190




191
192
193
194
195
196
197
	for (i = 0; i < nFDs; i++) {
		assert(FDs[i].fd <= _maxFD);

		if (FDs[i].revents & POLLIN) {
			if (FDs[i].fd == _cancelFD[0]) {
				char buffer;


				OF_ENSURE(read(_cancelFD[0], &buffer, 1) == 1);




				FDs[i].revents = 0;

				continue;
			}

			pool = objc_autoreleasePoolPush();








>

>
>
>
>







183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
	for (i = 0; i < nFDs; i++) {
		assert(FDs[i].fd <= _maxFD);

		if (FDs[i].revents & POLLIN) {
			if (FDs[i].fd == _cancelFD[0]) {
				char buffer;

#ifdef OF_HAVE_PIPE
				OF_ENSURE(read(_cancelFD[0], &buffer, 1) == 1);
#else
				OF_ENSURE(recvfrom(_cancelFD[0], &buffer, 1,
				    0, NULL, NULL) == 1);
#endif
				FDs[i].revents = 0;

				continue;
			}

			pool = objc_autoreleasePoolPush();

Modified src/OFKernelEventObserver_select.m from [3a4bb0d8ec] to [a5041a4d1e].

164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
	if (events < 0)
		@throw [OFObserveFailedException exceptionWithObserver: self
								 errNo: errno];

	if (FD_ISSET(_cancelFD[0], &readFDs)) {
		char buffer;

#ifndef _WIN32
		OF_ENSURE(read(_cancelFD[0], &buffer, 1) == 1);
#else
		OF_ENSURE(recvfrom(_cancelFD[0], &buffer, 1, 0, NULL,
		    NULL) == 1);
#endif
	}








|







164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
	if (events < 0)
		@throw [OFObserveFailedException exceptionWithObserver: self
								 errNo: errno];

	if (FD_ISSET(_cancelFD[0], &readFDs)) {
		char buffer;

#ifdef OF_HAVE_PIPE
		OF_ENSURE(read(_cancelFD[0], &buffer, 1) == 1);
#else
		OF_ENSURE(recvfrom(_cancelFD[0], &buffer, 1, 0, NULL,
		    NULL) == 1);
#endif
	}

Modified src/OFUDPSocket.m from [b3ff5858a7] to [182b0b3dfd].

185
186
187
188
189
190
191

192
193
194




195
196
197
198
199
200
201
#endif

	if (address1->address.ss_family != address2->address.ss_family)
		return false;

	switch (address1->address.ss_family) {
	case AF_INET:

		if (address1->length < sizeof(struct sockaddr_in) ||
		    address2->length < sizeof(struct sockaddr_in))
			@throw [OFInvalidArgumentException exception];





		sin_1 = (struct sockaddr_in*)&address1->address;
		sin_2 = (struct sockaddr_in*)&address2->address;

		if (sin_1->sin_port != sin_2->sin_port)
			return false;
		if (sin_1->sin_addr.s_addr != sin_2->sin_addr.s_addr)







>



>
>
>
>







185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
#endif

	if (address1->address.ss_family != address2->address.ss_family)
		return false;

	switch (address1->address.ss_family) {
	case AF_INET:
#ifndef __wii__
		if (address1->length < sizeof(struct sockaddr_in) ||
		    address2->length < sizeof(struct sockaddr_in))
			@throw [OFInvalidArgumentException exception];
#else
		if (address1->length < 8 || address2->length < 8)
			@throw [OFInvalidArgumentException exception];
#endif

		sin_1 = (struct sockaddr_in*)&address1->address;
		sin_2 = (struct sockaddr_in*)&address2->address;

		if (sin_1->sin_port != sin_2->sin_port)
			return false;
		if (sin_1->sin_addr.s_addr != sin_2->sin_addr.s_addr)
238
239
240
241
242
243
244

245
246




247
248
249
250
251
252
253
	size_t i;
#endif

	hash += address->address.ss_family;

	switch (address->address.ss_family) {
	case AF_INET:

		if (address->length < sizeof(struct sockaddr_in))
			@throw [OFInvalidArgumentException exception];





		sin = (struct sockaddr_in*)&address->address;

		hash += (sin->sin_port << 1);
		hash ^= sin->sin_addr.s_addr;

		break;







>


>
>
>
>







243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
	size_t i;
#endif

	hash += address->address.ss_family;

	switch (address->address.ss_family) {
	case AF_INET:
#ifndef __wii__
		if (address->length < sizeof(struct sockaddr_in))
			@throw [OFInvalidArgumentException exception];
#else
		if (address->length < 8)
			@throw [OFInvalidArgumentException exception];
#endif

		sin = (struct sockaddr_in*)&address->address;

		hash += (sin->sin_port << 1);
		hash ^= sin->sin_addr.s_addr;

		break;

Modified src/resolver.m from [995660e003] to [fe41dbfdaa].

161
162
163
164
165
166
167



168
169
170
171
172
173
174
175

176



177
178
179
180
181
182
183
			if ((addr = calloc(1, sizeof(*addr))) == NULL) {
				free(ret);
				free(tmp);
				@throw [OFOutOfMemoryException
				    exceptionWithRequestedSize: sizeof(*addr)];
			}




			addr->sin_family = AF_INET;
			addr->sin_port = OF_BSWAP16_IF_LE(port);
			addr->sin_addr.s_addr = s_addr;

			tmp->family = AF_INET;
			tmp->type = type;
			tmp->protocol = 0;
			tmp->address = (struct sockaddr*)addr;

			tmp->addressLength = sizeof(*addr);




			ret[0] = tmp;
			ret[1] = NULL;

			return ret;
		}








>
>
>








>

>
>
>







161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
			if ((addr = calloc(1, sizeof(*addr))) == NULL) {
				free(ret);
				free(tmp);
				@throw [OFOutOfMemoryException
				    exceptionWithRequestedSize: sizeof(*addr)];
			}

#ifdef __wii__
			addr->sin_len = 8;
#endif
			addr->sin_family = AF_INET;
			addr->sin_port = OF_BSWAP16_IF_LE(port);
			addr->sin_addr.s_addr = s_addr;

			tmp->family = AF_INET;
			tmp->type = type;
			tmp->protocol = 0;
			tmp->address = (struct sockaddr*)addr;
#ifndef __wii__
			tmp->addressLength = sizeof(*addr);
#else
			tmp->addressLength = 8;
#endif

			ret[0] = tmp;
			ret[1] = NULL;

			return ret;
		}