ObjFW  Check-in [ffb91daffe]

Overview
Comment:Initial sockets support for the Wii.

Not functional yet due to bugs in the SDK.
Bugs found so far:

* Binding to port 0 fails instead of choosing a free port.
* gethostbyname() does not work for IPs.
* getsockname() is missing.
* struct sockaddr_storage is missing.

I have not decided yet whether I fix those bugs in the SDK (I already
implemented getsockname() and added struct sockaddr_stroage and it seems
to work) or if I work around them in ObjFW. This will mainly depend on
how cooperative the developers of the Wii SDK are.

Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: ffb91daffe96f4784a60da77c2bad3b8ab007b0d611e134fb804ed9ad55db86d
User & Date: js on 2013-06-11 23:33:16
Other Links: manifest | tags
Context
2013-06-12
20:12
OFException.m: Define _GNU_SOURCE. check-in: e4cb03d080 user: js tags: trunk
2013-06-11
23:33
Initial sockets support for the Wii. check-in: ffb91daffe user: js tags: trunk
22:55
Use _Unwind_Backtrace() to get a backtrace. check-in: 259f593244 user: js tags: trunk
Changes

Modified .gitignore from [7fbc43bc98] to [3a8df09a67].

6
7
8
9
10
11
12

13
14
15
16
17
18
19
*.o
*.orig
*.so
*~
.deps
aclocal.m4
autom4te.cache

build
buildsys.mk
config.h
config.h.in
config.log
config.status
configure







>







6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
*.o
*.orig
*.so
*~
.deps
aclocal.m4
autom4te.cache
boot.dol
build
buildsys.mk
config.h
config.h.in
config.log
config.status
configure

Modified configure.ac from [538d135f42] to [1fee552aa8].

633
634
635
636
637
638
639




640
641
642
643
644
645
646

	case "$host_os" in
		mingw*)
			AC_SUBST(OFSTREAMOBSERVER_SELECT_M,
				"OFStreamObserver_select.m")
			;;
	esac





	AC_MSG_CHECKING(for getaddrinfo)
	AC_TRY_COMPILE([
		#include <stddef.h>
		#ifndef _WIN32
		# include <sys/types.h>
		# include <sys/socket.h>







>
>
>
>







633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650

	case "$host_os" in
		mingw*)
			AC_SUBST(OFSTREAMOBSERVER_SELECT_M,
				"OFStreamObserver_select.m")
			;;
	esac

	AS_IF([test x"$with_wii" = x"yes"], [
	       AC_SUBST(OFSTREAMOBSERVER_POLL_M, "OFStreamObserver_poll.m")
	])

	AC_MSG_CHECKING(for getaddrinfo)
	AC_TRY_COMPILE([
		#include <stddef.h>
		#ifndef _WIN32
		# include <sys/types.h>
		# include <sys/socket.h>

Modified src/OFStreamObserver.h from [9d097b3bbf] to [1ad6295688].

23
24
25
26
27
28
29






30
31
32
33
34
35
36
#ifdef OF_HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif

#ifdef _WIN32
# include <winsock2.h>
#endif







@class OFStream;
@class OFMutableArray;
@class OFMutableDictionary;
@class OFDataArray;
#ifdef OF_HAVE_THREADS
@class OFMutex;







>
>
>
>
>
>







23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#ifdef OF_HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif

#ifdef _WIN32
# include <winsock2.h>
#endif

#ifdef __wii__
# define BOOL OGC_BOOL
# include <network.h>
# undef BOOL
#endif

@class OFStream;
@class OFMutableArray;
@class OFMutableDictionary;
@class OFDataArray;
#ifdef OF_HAVE_THREADS
@class OFMutex;

Modified src/OFStreamObserver.m from [765c53f8f8] to [ec4b8afafc].

36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
..
52
53
54
55
56
57
58











59
60
61
62
63
64
65
..
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# import "OFMutex.h"
#endif
#import "OFDate.h"

#ifdef HAVE_KQUEUE
# import "OFStreamObserver_kqueue.h"
#endif
#ifdef HAVE_POLL_H
# import "OFStreamObserver_poll.h"
#endif
#if defined(HAVE_SYS_SELECT_H) || defined(_WIN32)
# import "OFStreamObserver_select.h"
#endif

#ifdef _WIN32
................................................................................
#endif

#import "OFInitializationFailedException.h"
#import "OFOutOfRangeException.h"

#import "autorelease.h"
#import "macros.h"












enum {
	QUEUE_ADD = 0,
	QUEUE_REMOVE = 1,
	QUEUE_READ = 0,
	QUEUE_WRITE = 2
};
................................................................................
+ alloc
{
	if (self == [OFStreamObserver class])
		return [OFStreamObserver_kqueue alloc];

	return [super alloc];
}
#elif defined(HAVE_POLL_H)
+ alloc
{
	if (self == [OFStreamObserver class])
		return [OFStreamObserver_poll alloc];

	return [super alloc];
}







|







 







>
>
>
>
>
>
>
>
>
>
>







 







|







36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
..
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
..
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# import "OFMutex.h"
#endif
#import "OFDate.h"

#ifdef HAVE_KQUEUE
# import "OFStreamObserver_kqueue.h"
#endif
#if defined(HAVE_POLL_H) || defined(__wii__)
# import "OFStreamObserver_poll.h"
#endif
#if defined(HAVE_SYS_SELECT_H) || defined(_WIN32)
# import "OFStreamObserver_select.h"
#endif

#ifdef _WIN32
................................................................................
#endif

#import "OFInitializationFailedException.h"
#import "OFOutOfRangeException.h"

#import "autorelease.h"
#import "macros.h"

#ifdef __wii__
# define BOOL OGC_BOOL
# include <network.h>
# undef BOOL
# define bind(sock, addr, addrlen) net_bind(sock, addr, addrlen)
# define getsockname(sock, addr, addrlen) net_getsockname(sock, addr, addrlen)
# define sendto(sock, buf, len, flags, addr, addrlen) \
	net_sendto(sock, buf, len, flags, addr, addrlen)
# define socket(domain, type, proto) net_socket(domain, type, proto)
#endif

enum {
	QUEUE_ADD = 0,
	QUEUE_REMOVE = 1,
	QUEUE_READ = 0,
	QUEUE_WRITE = 2
};
................................................................................
+ alloc
{
	if (self == [OFStreamObserver class])
		return [OFStreamObserver_kqueue alloc];

	return [super alloc];
}
#elif defined(HAVE_POLL_H) || defined(__wii__)
+ alloc
{
	if (self == [OFStreamObserver class])
		return [OFStreamObserver_poll alloc];

	return [super alloc];
}

Modified src/OFStreamObserver_poll.m from [047427a85c] to [a45ade6207].

27
28
29
30
31
32
33










34
35
36
37
38
39
40
#import "OFStreamObserver_poll.h"
#import "OFDataArray.h"

#import "OFOutOfRangeException.h"

#import "autorelease.h"
#import "macros.h"











@implementation OFStreamObserver_poll
- init
{
	self = [super init];

	@try {







>
>
>
>
>
>
>
>
>
>







27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#import "OFStreamObserver_poll.h"
#import "OFDataArray.h"

#import "OFOutOfRangeException.h"

#import "autorelease.h"
#import "macros.h"

#ifdef __wii__
# define BOOL OGC_BOOL
# include <network.h>
# undef BOOL
# define poll(fds, nfds, timeout) net_poll(fds, nfds, timeout)
# define pollfd pollsd
# define fd socket
typedef u32 nfds_t;
#endif

@implementation OFStreamObserver_poll
- init
{
	self = [super init];

	@try {

Modified src/OFStreamSocket.m from [05982c597a] to [10e23bfd72].

32
33
34
35
36
37
38








39
40
41
42
43
44
45
46
47
48
49
50
51

52

53
54
55
56

57
58
59
60




61

62
63
64
65
66
67
68
#import "OFStreamSocket.h"

#import "OFInitializationFailedException.h"
#import "OFNotConnectedException.h"
#import "OFReadFailedException.h"
#import "OFSetOptionFailedException.h"
#import "OFWriteFailedException.h"









#ifndef INVALID_SOCKET
# define INVALID_SOCKET -1
#endif

#ifdef _WIN32
# define close(sock) closesocket(sock)
#endif

@implementation OFStreamSocket
#ifdef _WIN32
+ (void)initialize
{

	WSADATA wsa;


	if (self != [OFStreamSocket class])
		return;


	if (WSAStartup(MAKEWORD(2, 0), &wsa))
		@throw [OFInitializationFailedException
		    exceptionWithClass: self];
}




#endif


+ (instancetype)socket
{
	return [[[self alloc] init] autorelease];
}

- (bool)lowlevelIsAtEndOfStream







>
>
>
>
>
>
>
>










<


>

>




>



<
>
>
>
>

>







32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56

57
58
59
60
61
62
63
64
65
66
67
68
69

70
71
72
73
74
75
76
77
78
79
80
81
82
#import "OFStreamSocket.h"

#import "OFInitializationFailedException.h"
#import "OFNotConnectedException.h"
#import "OFReadFailedException.h"
#import "OFSetOptionFailedException.h"
#import "OFWriteFailedException.h"

#ifdef __wii__
# define BOOL OGC_BOOL
# include <network.h>
# undef BOOL
# define recv(sock, buf, len, flags) net_recv(sock, buf, len, flags)
# define send(sock, buf, len, flags) net_send(sock, buf, len, flags)
#endif

#ifndef INVALID_SOCKET
# define INVALID_SOCKET -1
#endif

#ifdef _WIN32
# define close(sock) closesocket(sock)
#endif

@implementation OFStreamSocket

+ (void)initialize
{
#ifdef _WIN32
	WSADATA wsa;
#endif

	if (self != [OFStreamSocket class])
		return;

#if defined(_WIN32)
	if (WSAStartup(MAKEWORD(2, 0), &wsa))
		@throw [OFInitializationFailedException
		    exceptionWithClass: self];

#elif defined(__wii__)
	if (net_init() < 0)
		@throw [OFInitializationFailedException
		    exceptionWithClass: self];
#endif
}

+ (instancetype)socket
{
	return [[[self alloc] init] autorelease];
}

- (bool)lowlevelIsAtEndOfStream

Modified src/OFTCPSocket.h from [4ec65efa11] to [2b3fb6a25a].

28
29
30
31
32
33
34






35
36
37
38
39
40
41
#endif

#import "OFStreamSocket.h"

#ifdef _WIN32
# include <ws2tcpip.h>
#endif







/*! @file */

@class OFTCPSocket;
@class OFString;

#ifdef OF_HAVE_BLOCKS







>
>
>
>
>
>







28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#endif

#import "OFStreamSocket.h"

#ifdef _WIN32
# include <ws2tcpip.h>
#endif

#ifdef __wii__
# define BOOL OGC_BOOL
# include <network.h>
# undef BOOL
#endif

/*! @file */

@class OFTCPSocket;
@class OFString;

#ifdef OF_HAVE_BLOCKS

Modified src/OFTCPSocket.m from [4199e0da2a] to [4800955ec9].

81
82
83
84
85
86
87













88
89
90
91
92
93
94
...
487
488
489
490
491
492
493

494

495
496
497
498
499
500
501
...
616
617
618
619
620
621
622

623
624

625
626
627
628
629
630
631

static OFMutex *mutex = nil;
#endif

#ifdef _WIN32
# define close(sock) closesocket(sock)
#endif














/* References for static linking */
void _references_to_categories_of_OFTCPSocket(void)
{
	_OFTCPSocket_SOCKS5_reference = 1;
}

................................................................................
- (uint16_t)bindToHost: (OFString*)host
		  port: (uint16_t)port
{
	const int one = 1;
	union {
		struct sockaddr_storage storage;
		struct sockaddr_in in;

		struct sockaddr_in6 in6;

	} addr;
	socklen_t addrLen;

	if (_socket != INVALID_SOCKET)
		@throw [OFAlreadyConnectedException
		    exceptionWithClass: [self class]
				socket: self];
................................................................................
							  socket: self
							    host: host
							    port: port];
	}

	if (addr.storage.ss_family == AF_INET)
		return OF_BSWAP16_IF_LE(addr.in.sin_port);

	if (addr.storage.ss_family == AF_INET6)
		return OF_BSWAP16_IF_LE(addr.in6.sin6_port);


	close(_socket);
	_socket = INVALID_SOCKET;
	@throw [OFBindFailedException exceptionWithClass: [self class]
						  socket: self
						    host: host
						    port: port];







>
>
>
>
>
>
>
>
>
>
>
>
>







 







>

>







 







>


>







81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
...
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
...
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648

static OFMutex *mutex = nil;
#endif

#ifdef _WIN32
# define close(sock) closesocket(sock)
#endif

#ifdef __wii__
# define accept(sock, addr, addrlen) net_accept(sock, addr, addrlen)
# define bind(sock, addr, addrlen) net_bind(sock, addr, addrlen)
# define close(sock) net_close(sock)
# define connect(sock, addr, addrlen) net_connect(sock, addr, addrlen)
# define gethostbyname(name) net_gethostbyname(name)
# define getsockname(sock, addr, addrlen) net_getsockname(sock, addr, addrlen)
# define listen(sock, backlog) net_listen(sock, backlog)
# define setsockopt(sock, level, name, value, len) \
	net_setsockopt(sock, level, name, value, len)
# define socket(domain, type, proto) net_socket(domain, type, proto)
#endif

/* References for static linking */
void _references_to_categories_of_OFTCPSocket(void)
{
	_OFTCPSocket_SOCKS5_reference = 1;
}

................................................................................
- (uint16_t)bindToHost: (OFString*)host
		  port: (uint16_t)port
{
	const int one = 1;
	union {
		struct sockaddr_storage storage;
		struct sockaddr_in in;
#ifdef AF_INET6
		struct sockaddr_in6 in6;
#endif
	} addr;
	socklen_t addrLen;

	if (_socket != INVALID_SOCKET)
		@throw [OFAlreadyConnectedException
		    exceptionWithClass: [self class]
				socket: self];
................................................................................
							  socket: self
							    host: host
							    port: port];
	}

	if (addr.storage.ss_family == AF_INET)
		return OF_BSWAP16_IF_LE(addr.in.sin_port);
#ifdef AF_INET6
	if (addr.storage.ss_family == AF_INET6)
		return OF_BSWAP16_IF_LE(addr.in6.sin6_port);
#endif

	close(_socket);
	_socket = INVALID_SOCKET;
	@throw [OFBindFailedException exceptionWithClass: [self class]
						  socket: self
						    host: host
						    port: port];

Modified tests/Makefile from [a5eab7fd1a] to [2ffb33610c].

89
90
91
92
93
94
95



96
97
98
99
100
101

EBOOT.PBP: ${PROG_NOINST}
	psp-fixup-imports ${PROG_NOINST}
	mksfo "ObjFW Tests" PARAM.SFO
	psp-strip ${PROG_NOINST}
	pack-pbp $@ PARAM.SFO NULL NULL NULL NULL NULL ${PROG_NOINST} NULL




include ../buildsys.mk

CPPFLAGS += -I../src -I../src/exceptions -I../src/runtime -I.. -DSTDOUT
LIBS := -L../src -lobjfw ${TESTS_LIBS} ${LIBS}
LDFLAGS += ${MAP_LDFLAGS}
LD = ${OBJC}







>
>
>






89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104

EBOOT.PBP: ${PROG_NOINST}
	psp-fixup-imports ${PROG_NOINST}
	mksfo "ObjFW Tests" PARAM.SFO
	psp-strip ${PROG_NOINST}
	pack-pbp $@ PARAM.SFO NULL NULL NULL NULL NULL ${PROG_NOINST} NULL

boot.dol: ${PROG_NOINST}
	elf2dol ${PROG_NOINST} $@

include ../buildsys.mk

CPPFLAGS += -I../src -I../src/exceptions -I../src/runtime -I.. -DSTDOUT
LIBS := -L../src -lobjfw ${TESTS_LIBS} ${LIBS}
LDFLAGS += ${MAP_LDFLAGS}
LD = ${OBJC}

Modified tests/TestsAppDelegate.m from [3d02f5dcdc] to [612bc88548].

85
86
87
88
89
90
91
92

93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
		return of_application_main(&argc, &argv,
		    [TestsAppDelegate class]);
	} @catch (id e) {
		TestsAppDelegate *delegate =
		    [[OFApplication sharedApplication] delegate];
		OFString *string = [OFString stringWithFormat:
		    @"\nRuntime error: Unhandled exception:\n%@\n", e];
		OFString *backtrace = [[e backtrace]

		    componentsJoinedByString: @"\n  "];

		[delegate outputString: string
			       inColor: RED];
		if (backtrace != nil) {
			backtrace = [OFString stringWithFormat:
			    @"\nBacktrace:\n  %@\n\n", backtrace];
			[delegate outputString: backtrace
				       inColor: RED];
		}
		[delegate outputString: @"Press home button to exit!\n"
			       inColor: NO_COLOR];
		for (;;) {
			WPAD_ScanPads();

			if (WPAD_ButtonsDown(0) & WPAD_BUTTON_HOME)
				[OFApplication terminateWithStatus: 1];







|
>
|



<
<
<
|
|
<







85
86
87
88
89
90
91
92
93
94
95
96
97



98
99

100
101
102
103
104
105
106
		return of_application_main(&argc, &argv,
		    [TestsAppDelegate class]);
	} @catch (id e) {
		TestsAppDelegate *delegate =
		    [[OFApplication sharedApplication] delegate];
		OFString *string = [OFString stringWithFormat:
		    @"\nRuntime error: Unhandled exception:\n%@\n", e];
		OFString *backtrace = [OFString stringWithFormat:
		    @"\nBacktrace:\n  %@\n\n",
		    [[e backtrace] componentsJoinedByString: @"\n  "];

		[delegate outputString: string
			       inColor: RED];



		[delegate outputString: backtrace
			       inColor: RED];

		[delegate outputString: @"Press home button to exit!\n"
			       inColor: NO_COLOR];
		for (;;) {
			WPAD_ScanPads();

			if (WPAD_ButtonsDown(0) & WPAD_BUTTON_HOME)
				[OFApplication terminateWithStatus: 1];