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].

1
2
3
4
5
6
7
8
9
10
11
12

13
14
15
16
17
18
19
*.a
*.bundle
*.dll
*.dylib
*.map
*.o
*.orig
*.so
*~
.deps
aclocal.m4
autom4te.cache

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












>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
*.a
*.bundle
*.dll
*.dylib
*.map
*.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
51
52
53
54
55
56
57
58











59
60
61
62
63
64
65
# 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
# include <ws2tcpip.h>
#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
};







|















>
>
>
>
>
>
>
>
>
>
>







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
# 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
# include <ws2tcpip.h>
#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
};
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
+ 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];
}







|







86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
+ 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

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;
}








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







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

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;
}

487
488
489
490
491
492
493

494

495
496
497
498
499
500
501
- (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];







>

>







500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
- (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];
616
617
618
619
620
621
622

623
624

625
626
627
628
629
630
631
							  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];







>


>







631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
							  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];