ObjFW  Check-in [6caac0826e]

Overview
Comment:Make it possible to build ObjFW without support for threads.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 6caac0826e4fe3063ba8ca9b5b473c1edf16fa2d8864e2cbb4fcb3d68930b710
User & Date: js on 2009-12-11 12:52:29
Other Links: manifest | tags
Context
2009-12-12
14:19
Remove OBJC_SYNC variable as it is not used anymore. check-in: b7e505ba7f user: js tags: trunk
2009-12-11
12:52
Make it possible to build ObjFW without support for threads. check-in: 6caac0826e user: js tags: trunk
2009-12-09
19:09
Check whether getaddrinfo is thread-safe and use locks if not. check-in: c8398d985d user: js tags: trunk
Changes

Modified configure.ac from [e854e5bdb3] to [3eec75f7eb].

75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
		], [
		AC_MSG_RESULT(yes)
		size_max="SIZE_T_MAX"], [
		AC_MSG_RESULT(no)
		size_max="((size_t)-1)"])
	AC_DEFINE_UNQUOTED(SIZE_MAX, $size_max, [Maximum value for size_t])])

AC_CHECK_FUNC(objc_sync_enter,, [
	AC_SUBST(OBJC_SYNC, "objc_sync")
	AC_SUBST(OBJC_SYNC_M, "objc_sync.m")
	AC_DEFINE(NEED_OBJC_SYNC_INIT, 1,
		[Whether objc_sync_init needs to be called])])

AC_CHECK_FUNC(asprintf, [
	have_asprintf="yes"
	AC_DEFINE(OF_HAVE_ASPRINTF, 1, [Whether we have asprintf])
	AC_SUBST(ASPRINTF_DEF, "-DOF_HAVE_ASPRINTF")
	], [
	have_asprintf="no"
	AC_SUBST(ASPRINTF_M, "asprintf.m")







<
<
<
<
<
<







75
76
77
78
79
80
81






82
83
84
85
86
87
88
		], [
		AC_MSG_RESULT(yes)
		size_max="SIZE_T_MAX"], [
		AC_MSG_RESULT(no)
		size_max="((size_t)-1)"])
	AC_DEFINE_UNQUOTED(SIZE_MAX, $size_max, [Maximum value for size_t])])







AC_CHECK_FUNC(asprintf, [
	have_asprintf="yes"
	AC_DEFINE(OF_HAVE_ASPRINTF, 1, [Whether we have asprintf])
	AC_SUBST(ASPRINTF_DEF, "-DOF_HAVE_ASPRINTF")
	], [
	have_asprintf="no"
	AC_SUBST(ASPRINTF_M, "asprintf.m")
108
109
110
111
112
113
114



115
116
117
118
119
120
121
122
123
124
125
126
127











128
129
130
131
132
133
134
			ac_cv_snprintf_useful_ret="no")])
		AC_MSG_RESULT($ac_cv_snprintf_useful_ret)])
test x"$have_asprintf" != x"yes" -a x"$ac_cv_snprintf_useful_ret" != x"yes" && \
	AC_MSG_ERROR(No asprintf and no snprintf returning required space!)

AC_CHECK_LIB(dl, dlopen, LIBS="$LIBS -ldl")




case "$host" in
	*-*-mingw*)
		AC_MSG_CHECKING(for threads)
		AC_MSG_RESULT(win32)
		;;
	*)
		ACX_PTHREAD([
			CPPLAGS="$CPPFLAGS $PTHREAD_CFLAGS"
			LIBS="$LIBS $PTHREAD_LIBS"
			], [
			AC_MSG_ERROR(No pthreads or other supported threads!)])
		;;
esac












AC_CHECK_LIB(socket, socket, LIBS="$LIBS -lsocket")
AC_CHECK_LIB(ws2_32, main, LIBS="$LIBS -lws2_32")

AC_MSG_CHECKING(for getaddrinfo)
AC_TRY_COMPILE([
	#include <stddef.h>







>
>
>
|
|
|
|
|
|
|
|
|
|
|
|
|
>
>
>
>
>
>
>
>
>
>
>







102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
			ac_cv_snprintf_useful_ret="no")])
		AC_MSG_RESULT($ac_cv_snprintf_useful_ret)])
test x"$have_asprintf" != x"yes" -a x"$ac_cv_snprintf_useful_ret" != x"yes" && \
	AC_MSG_ERROR(No asprintf and no snprintf returning required space!)

AC_CHECK_LIB(dl, dlopen, LIBS="$LIBS -ldl")

AC_ARG_ENABLE(threads,
	AS_HELP_STRING([--disable-threads], [disable thread support]))
if test x"$enable_threads" != x"no"; then
	case "$host_os" in
		mingw*)
			AC_MSG_CHECKING(for threads)
			AC_MSG_RESULT(win32)
			;;
		*)
			ACX_PTHREAD([
				CPPLAGS="$CPPFLAGS $PTHREAD_CFLAGS"
				LIBS="$LIBS $PTHREAD_LIBS"
				], [
				AC_MSG_ERROR(No supported threads found!)])
			;;
	esac

	AC_DEFINE(OF_THREADS, 1, [Whether we have threads])
	AC_SUBST(OFTHREAD_M, "OFThread.m")
	AC_SUBST(THREADING_H, "threading.h")

	AC_CHECK_FUNC(objc_sync_enter,, [
		AC_SUBST(OBJC_SYNC, "objc_sync")
		AC_SUBST(OBJC_SYNC_M, "objc_sync.m")
		AC_DEFINE(NEED_OBJC_SYNC_INIT, 1,
			[Whether objc_sync_init needs to be called])])
fi

AC_CHECK_LIB(socket, socket, LIBS="$LIBS -lsocket")
AC_CHECK_LIB(ws2_32, main, LIBS="$LIBS -lws2_32")

AC_MSG_CHECKING(for getaddrinfo)
AC_TRY_COMPILE([
	#include <stddef.h>
142
143
144
145
146
147
148

149

150
151
152
153
154
155
156
157
158
159
160
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
191
192

193
194
195
196
197
198
199
	#endif], [
	struct addrinfo ai;
	getaddrinfo(NULL, NULL, NULL, NULL);
	], [
	AC_MSG_RESULT(yes)
	AC_DEFINE(HAVE_GETADDRINFO, 1, [Whether we have getaddrinfo])


	AC_MSG_CHECKING(whether getaddrinfo is thread-safe)

	case "$host_os" in
		darwin[[12345]].*)
			have_threadsafe_getaddrinfo="no"
			;;
		darwin*)
			have_threadsafe_getaddrinfo="yes"
			;;
		freebsd[[1234]].* | freebsd5.[[1234]]*)
			have_threadsafe_getaddrinfo="no"
			;;
		freebsd*)
			have_threadsafe_getaddrinfo="yes"
			;;
		netbsd[[123]].*)
			have_threadsafe_getaddrinfo="no"
			;;
		netbsd*)
			have_threadsafe_getaddrinfo="yes"
			;;
		solaris*)
			have_threadsafe_getaddrinfo="yes"
			;;
		*)
			have_threadsafe_getaddrinfo="unknown"
			;;
		esac

		if test x"$have_threadsafe_getaddrinfo" = x"unknown"; then
			AC_EGREP_CPP(yes, [
				#include <netdb.h>
				#ifdef h_errno
				yes
				#end
				],
				[have_threadsafe_getaddrinfo="yes"],
				[have_threadsafe_getaddrinfo="no"])
		fi

		test x"$have_threadsafe_getaddrinfo" = x"yes" && \
			AC_DEFINE(HAVE_THREADSAFE_GETADDRINFO, 1,
				[Whether getaddrinfo is thread-safe])

		AC_MSG_RESULT($have_threadsafe_getaddrinfo)

	], [
	AC_MSG_RESULT(no)])

AC_CHECK_FUNC(madvise, [AC_DEFINE(HAVE_MADVISE, 1, [Whether we have madvise])])

if test x"$GOBJC" = x"yes"; then
	OBJCFLAGS="$OBJCFLAGS -Werror"







>
|
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|


















>







150
151
152
153
154
155
156
157
158
159
160
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
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
	#endif], [
	struct addrinfo ai;
	getaddrinfo(NULL, NULL, NULL, NULL);
	], [
	AC_MSG_RESULT(yes)
	AC_DEFINE(HAVE_GETADDRINFO, 1, [Whether we have getaddrinfo])

	if test x"$enable_threads" != x"no"; then
		AC_MSG_CHECKING(whether getaddrinfo is thread-safe)

		case "$host_os" in
			darwin[[12345]].*)
				have_threadsafe_getaddrinfo="no"
				;;
			darwin*)
				have_threadsafe_getaddrinfo="yes"
				;;
			freebsd[[1234]].* | freebsd5.[[1234]]*)
				have_threadsafe_getaddrinfo="no"
				;;
			freebsd*)
				have_threadsafe_getaddrinfo="yes"
				;;
			netbsd[[123]].*)
				have_threadsafe_getaddrinfo="no"
				;;
			netbsd*)
				have_threadsafe_getaddrinfo="yes"
				;;
			solaris*)
				have_threadsafe_getaddrinfo="yes"
				;;
			*)
				have_threadsafe_getaddrinfo="unknown"
				;;
		esac

		if test x"$have_threadsafe_getaddrinfo" = x"unknown"; then
			AC_EGREP_CPP(yes, [
				#include <netdb.h>
				#ifdef h_errno
				yes
				#end
				],
				[have_threadsafe_getaddrinfo="yes"],
				[have_threadsafe_getaddrinfo="no"])
		fi

		test x"$have_threadsafe_getaddrinfo" = x"yes" && \
			AC_DEFINE(HAVE_THREADSAFE_GETADDRINFO, 1,
				[Whether getaddrinfo is thread-safe])

		AC_MSG_RESULT($have_threadsafe_getaddrinfo)
	fi
	], [
	AC_MSG_RESULT(no)])

AC_CHECK_FUNC(madvise, [AC_DEFINE(HAVE_MADVISE, 1, [Whether we have madvise])])

if test x"$GOBJC" = x"yes"; then
	OBJCFLAGS="$OBJCFLAGS -Werror"

Modified extra.mk.in from [f5c4908cf0] to [6f868ad29d].

1
2
3
4

5
6
7
8

ASPRINTF_M = @ASPRINTF_M@
OBJC_SYNC = @OBJC_SYNC@
OBJC_SYNC_M = @OBJC_SYNC_M@
OFPLUGIN_M = @OFPLUGIN_M@

TESTPLUGIN = @TESTPLUGIN@
WS2_LIBS = @WS2_LIBS@
TESTS = @TESTS@
TEST_LAUNCHER = @TEST_LAUNCHER@





>




>
1
2
3
4
5
6
7
8
9
10
ASPRINTF_M = @ASPRINTF_M@
OBJC_SYNC = @OBJC_SYNC@
OBJC_SYNC_M = @OBJC_SYNC_M@
OFPLUGIN_M = @OFPLUGIN_M@
OFTHREAD_M = @OFTHREAD_M@
TESTPLUGIN = @TESTPLUGIN@
WS2_LIBS = @WS2_LIBS@
TESTS = @TESTS@
TEST_LAUNCHER = @TEST_LAUNCHER@
THREADING_H = @THREADING_H@

Modified src/Makefile from [a627df95af] to [4c19f6132f].

20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

39
40
41
42
43
44
45
       OFNumber.m		\
       OFObject.m		\
       ${OFPLUGIN_M}		\
       OFSocket.m		\
       OFStream.m		\
       OFString.m		\
       OFTCPSocket.m		\
       OFThread.m		\
       OFURLEncoding.m		\
       OFXMLElement.m		\
       OFXMLParser.m		\
       unicode.m

INCLUDES := ${SRCS:.m=.h}	\
	    OFMacros.h		\
	    ObjFW.h		\
	    asprintf.h		\
	    objfw-defs.h	\
	    threading.h


SRCS += ${OBJC_SYNC_M}	\
	${ASPRINTF_M}	\
	iso_8859_15.m	\
	windows_1252.m

include ../buildsys.mk







|










<
>







20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

38
39
40
41
42
43
44
45
       OFNumber.m		\
       OFObject.m		\
       ${OFPLUGIN_M}		\
       OFSocket.m		\
       OFStream.m		\
       OFString.m		\
       OFTCPSocket.m		\
       ${OFTHREAD_M}		\
       OFURLEncoding.m		\
       OFXMLElement.m		\
       OFXMLParser.m		\
       unicode.m

INCLUDES := ${SRCS:.m=.h}	\
	    OFMacros.h		\
	    ObjFW.h		\
	    asprintf.h		\
	    objfw-defs.h	\

	    ${THREADING_H}

SRCS += ${OBJC_SYNC_M}	\
	${ASPRINTF_M}	\
	iso_8859_15.m	\
	windows_1252.m

include ../buildsys.mk

Modified src/OFAutoreleasePool.m from [3ea4e1ab45] to [929d90108c].

11
12
13
14
15
16
17
18
19
20

21
22
23



24
25

26
27
28
29
30
31
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
83

84
85
86
87
88
89
90
91
92



93
94
95
96
97
98
99

#include "config.h"

#include <stdlib.h>

#import "OFAutoreleasePool.h"
#import "OFList.h"
#import "OFThread.h"
#import "OFExceptions.h"


#import "threading.h"

static of_tlskey_t first_key, last_key;




@implementation OFAutoreleasePool

+ (void)initialize
{
	if (self != [OFAutoreleasePool class])
		return;

	if (!of_tlskey_new(&first_key) || !of_tlskey_new(&last_key))
		@throw [OFInitializationFailedException newWithClass: self];
}


+ (void)addObjectToTopmostPool: (OFObject*)obj
{

	id last = of_tlskey_get(last_key);


	if (last == nil) {
		@try {
			[[self alloc] init];
		} @catch (OFException *e) {
			[obj release];
			@throw e;
		}


		last = of_tlskey_get(last_key);

	}

	if (last == nil) {
		[obj release];
		@throw [OFInitializationFailedException newWithClass: self];
	}

	@try {
		[last addObject: obj];
	} @catch (OFException *e) {
		[obj release];
		@throw e;
	}
}

+ (void)releaseAll
{

	[of_tlskey_get(first_key) release];



}

- init
{

	id first;


	self = [super init];


	first = of_tlskey_get(first_key);
	prev = of_tlskey_get(last_key);

	if (!of_tlskey_set(last_key, self)) {
		Class c = isa;
		[super dealloc];
		@throw [OFInitializationFailedException newWithClass: c];
	}





	if (first == nil) {

		if (!of_tlskey_set(first_key, self)) {
			Class c = isa;

			of_tlskey_set(last_key, prev);

			[super dealloc];
			@throw [OFInitializationFailedException
			    newWithClass: c];
		}



	}

	if (prev != nil)
		prev->next = self;

	return self;
}







<


>



>
>
>


>








>



>

>









>

>

















>

>
>
>




>

>



>








>
>
>
>


>









>
>
>







11
12
13
14
15
16
17

18
19
20
21
22
23
24
25
26
27
28
29
30
31
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
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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123

#include "config.h"

#include <stdlib.h>

#import "OFAutoreleasePool.h"
#import "OFList.h"

#import "OFExceptions.h"

#ifdef OF_THREADS
#import "threading.h"

static of_tlskey_t first_key, last_key;
#else
static OFAutoreleasePool *first = nil, *last = nil;
#endif

@implementation OFAutoreleasePool
#ifdef OF_THREADS
+ (void)initialize
{
	if (self != [OFAutoreleasePool class])
		return;

	if (!of_tlskey_new(&first_key) || !of_tlskey_new(&last_key))
		@throw [OFInitializationFailedException newWithClass: self];
}
#endif

+ (void)addObjectToTopmostPool: (OFObject*)obj
{
#ifdef OF_THREADS
	id last = of_tlskey_get(last_key);
#endif

	if (last == nil) {
		@try {
			[[self alloc] init];
		} @catch (OFException *e) {
			[obj release];
			@throw e;
		}

#ifdef OF_THREADS
		last = of_tlskey_get(last_key);
#endif
	}

	if (last == nil) {
		[obj release];
		@throw [OFInitializationFailedException newWithClass: self];
	}

	@try {
		[last addObject: obj];
	} @catch (OFException *e) {
		[obj release];
		@throw e;
	}
}

+ (void)releaseAll
{
#ifdef OF_THREADS
	[of_tlskey_get(first_key) release];
#else
	[first release];
#endif
}

- init
{
#ifdef OF_THREADS
	id first;
#endif

	self = [super init];

#ifdef OF_THREADS
	first = of_tlskey_get(first_key);
	prev = of_tlskey_get(last_key);

	if (!of_tlskey_set(last_key, self)) {
		Class c = isa;
		[super dealloc];
		@throw [OFInitializationFailedException newWithClass: c];
	}
#else
	prev = last;
	last = self;
#endif

	if (first == nil) {
#ifdef OF_THREADS
		if (!of_tlskey_set(first_key, self)) {
			Class c = isa;

			of_tlskey_set(last_key, prev);

			[super dealloc];
			@throw [OFInitializationFailedException
			    newWithClass: c];
		}
#else
		first = self;
#endif
	}

	if (prev != nil)
		prev->next = self;

	return self;
}
107
108
109
110
111
112
113

114
115



116
117
118
119
120
121
122
123

124
125
126




127
128
129
130
131
132
133
	 * If of_tlskey_set fails, this is a real problem. The best we can do
	 * is to not change the pool below the current pool and stop
	 * deallocation. This way, new objects will be added to the current
	 * pool, but released when the pool below gets released - and maybe
	 * the pool itself will be released as well then, because maybe
	 * of_tlskey_set will work this time.
	 */

	if (!of_tlskey_set(last_key, prev))
		return;




	if (prev != nil)
		prev->next = nil;

	/*
	 * If of_tlskey_set fails here, this is even worse, as this will
	 * definitely be a memory leak. But this should never happen anyway.
	 */

	if (of_tlskey_get(first_key) == self)
		if (!of_tlskey_set(first_key, nil))
			return;





	[super dealloc];
}

- addObject: (OFObject*)obj
{
	if (objects == nil)







>


>
>
>








>



>
>
>
>







131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
	 * If of_tlskey_set fails, this is a real problem. The best we can do
	 * is to not change the pool below the current pool and stop
	 * deallocation. This way, new objects will be added to the current
	 * pool, but released when the pool below gets released - and maybe
	 * the pool itself will be released as well then, because maybe
	 * of_tlskey_set will work this time.
	 */
#ifdef OF_THREADS
	if (!of_tlskey_set(last_key, prev))
		return;
#else
	last = prev;
#endif

	if (prev != nil)
		prev->next = nil;

	/*
	 * If of_tlskey_set fails here, this is even worse, as this will
	 * definitely be a memory leak. But this should never happen anyway.
	 */
#ifdef OF_THREADS
	if (of_tlskey_get(first_key) == self)
		if (!of_tlskey_set(first_key, nil))
			return;
#else
	if (first == self)
		first = nil;
#endif

	[super dealloc];
}

- addObject: (OFObject*)obj
{
	if (objects == nil)

Modified src/OFTCPSocket.m from [f13b976cd7] to [a4d491ccd6].

20
21
22
23
24
25
26

27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# ifndef _WIN32
#  include <arpa/inet.h>
# endif
#endif

#import "OFTCPSocket.h"
#import "OFExceptions.h"


#ifndef INVALID_SOCKET
#define INVALID_SOCKET -1
#endif

#if !defined(HAVE_GETADDRINFO) || !defined(HAVE_THREADSAFE_GETADDRINFO)
#import "OFThread.h"

static OFMutex *mutex = nil;
#endif

@implementation OFTCPSocket
#if !defined(HAVE_GETADDRINFO) || !defined(HAVE_THREADSAFE_GETADDRINFO)
+ (void)initialize
{
	if (self == [OFTCPSocket class])
		mutex = [[OFMutex alloc] init];
}
#endif








>





|






|







20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# ifndef _WIN32
#  include <arpa/inet.h>
# endif
#endif

#import "OFTCPSocket.h"
#import "OFExceptions.h"
#import "OFMacros.h"

#ifndef INVALID_SOCKET
#define INVALID_SOCKET -1
#endif

#if defined(OF_THREADS) && !defined(HAVE_THREADSAFE_GETADDRINFO)
#import "OFThread.h"

static OFMutex *mutex = nil;
#endif

@implementation OFTCPSocket
#if defined(OF_THREADS) && !defined(HAVE_THREADSAFE_GETADDRINFO)
+ (void)initialize
{
	if (self == [OFTCPSocket class])
		mutex = [[OFMutex alloc] init];
}
#endif

65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#ifdef HAVE_GETADDRINFO
	struct addrinfo hints, *res, *res0;

	memset(&hints, 0, sizeof(struct addrinfo));
	hints.ai_family = AF_UNSPEC;
	hints.ai_socktype = SOCK_STREAM;

#ifndef HAVE_THREADSAFE_GETADDRINFO
	[mutex lock];
#endif

	if (getaddrinfo([node cString], [service cString], &hints, &res0)) {
#ifndef HAVE_THREADSAFE_GETADDRINFO
		[mutex unlock];
#endif
		@throw [OFAddressTranslationFailedException
		    newWithClass: isa
			    node: node
			 service: service];
	}







|




|







66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#ifdef HAVE_GETADDRINFO
	struct addrinfo hints, *res, *res0;

	memset(&hints, 0, sizeof(struct addrinfo));
	hints.ai_family = AF_UNSPEC;
	hints.ai_socktype = SOCK_STREAM;

#if defined(OF_THREADS) && !defined(HAVE_THREADSAFE_GETADDRINFO)
	[mutex lock];
#endif

	if (getaddrinfo([node cString], [service cString], &hints, &res0)) {
#if defined(OF_THREADS) && !defined(HAVE_THREADSAFE_GETADDRINFO)
		[mutex unlock];
#endif
		@throw [OFAddressTranslationFailedException
		    newWithClass: isa
			    node: node
			 service: service];
	}
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112

113

114
115

116

117
118
119
120
121
122
123
124
125

126

127
128
129
130
131
132
133
134
135
136
137
138

139

140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155

156

157
158
159
160
161
162
163
		}

		break;
	}

	freeaddrinfo(res0);

#ifndef HAVE_THREADSAFE_GETADDRINFO
	[mutex unlock];
#endif
#else
	BOOL connected = NO;
	struct hostent *he;
	struct servent *se;
	struct sockaddr_in addr;
	uint16_t port;
	char **ip;


	[mutex lock];


	if ((he = gethostbyname([node cString])) == NULL) {

		[mutex unlock];

		@throw [OFAddressTranslationFailedException
		    newWithClass: isa
			    node: node
			 service: service];
	}

	if ((se = getservbyname([service cString], "TCP")) != NULL)
		port = se->s_port;
	else if ((port = OF_BSWAP16_IF_LE(atoi([service cString]))) == 0) {

		[mutex unlock];

		@throw [OFAddressTranslationFailedException
		    newWithClass: isa
			    node: node
			 service: service];
	}

	memset(&addr, 0, sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_port = port;

	if (he->h_addrtype != AF_INET ||
	    (sock = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {

		[mutex unlock];

		@throw [OFConnectionFailedException
		    newWithClass: isa
			    node: node
			 service: service];
	}

	for (ip = he->h_addr_list; *ip != NULL; ip++) {
		memcpy(&addr.sin_addr.s_addr, *ip, he->h_length);

		if (connect(sock, (struct sockaddr*)&addr, sizeof(addr)) == -1)
			continue;

		connected = YES;
		break;
	}


	[mutex unlock];


	if (!connected) {
		close(sock);
		sock = INVALID_SOCKET;
	}
#endif








|










>

>


>

>









>

>












>

>
















>

>







96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
		}

		break;
	}

	freeaddrinfo(res0);

#if defined(OF_THREADS) && !defined(HAVE_THREADSAFE_GETADDRINFO)
	[mutex unlock];
#endif
#else
	BOOL connected = NO;
	struct hostent *he;
	struct servent *se;
	struct sockaddr_in addr;
	uint16_t port;
	char **ip;

#ifdef OF_THREADS
	[mutex lock];
#endif

	if ((he = gethostbyname([node cString])) == NULL) {
#ifdef OF_THREADS
		[mutex unlock];
#endif
		@throw [OFAddressTranslationFailedException
		    newWithClass: isa
			    node: node
			 service: service];
	}

	if ((se = getservbyname([service cString], "TCP")) != NULL)
		port = se->s_port;
	else if ((port = OF_BSWAP16_IF_LE(atoi([service cString]))) == 0) {
#ifdef OF_THREADS
		[mutex unlock];
#endif
		@throw [OFAddressTranslationFailedException
		    newWithClass: isa
			    node: node
			 service: service];
	}

	memset(&addr, 0, sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_port = port;

	if (he->h_addrtype != AF_INET ||
	    (sock = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {
#ifdef OF_THREADS
		[mutex unlock];
#endif
		@throw [OFConnectionFailedException
		    newWithClass: isa
			    node: node
			 service: service];
	}

	for (ip = he->h_addr_list; *ip != NULL; ip++) {
		memcpy(&addr.sin_addr.s_addr, *ip, he->h_length);

		if (connect(sock, (struct sockaddr*)&addr, sizeof(addr)) == -1)
			continue;

		connected = YES;
		break;
	}

#ifdef OF_THREADS
	[mutex unlock];
#endif

	if (!connected) {
		close(sock);
		sock = INVALID_SOCKET;
	}
#endif

185
186
187
188
189
190
191




192



193
194
195
196

197
198
199



200
201
202
203
204
205
206




207
208
209
210
211
212
213
214
215
216
217
218

219

220
221

222

223
224
225
226
227
228
229
230
231

232

233
234
235
236
237
238
239
240
241
242
243

244

245
246
247
248
249
250
251
252

253

254
255
256
257
258
259
260
#ifdef HAVE_GETADDRINFO
	struct addrinfo hints, *res;

	memset(&hints, 0, sizeof(struct addrinfo));
	hints.ai_family = family;
	hints.ai_socktype = SOCK_STREAM;





	if (getaddrinfo([node cString], [service cString], &hints, &res))



		@throw [OFAddressTranslationFailedException
		    newWithClass: isa
			    node: node
			 service: service];


	if (bind(sock, res->ai_addr, res->ai_addrlen) == -1) {
		freeaddrinfo(res);



		@throw [OFBindFailedException newWithClass: isa
						      node: node
						   service: service
						    family: family];
	}

	freeaddrinfo(res);




#else
	struct hostent *he;
	struct servent *se;
	struct sockaddr_in addr;
	uint16_t port;

	if (family != AF_INET)
		@throw [OFBindFailedException newWithClass: isa
						      node: node
						   service: service
						    family: family];


	[mutex lock];


	if ((he = gethostbyname([node cString])) == NULL) {

		[mutex unlock];

		@throw [OFAddressTranslationFailedException
		    newWithClass: isa
			    node: node
			 service: service];
	}

	if ((se = getservbyname([service cString], "TCP")) != NULL)
		port = se->s_port;
	else if ((port = OF_BSWAP16_IF_LE(atoi([service cString]))) == 0) {

		[mutex unlock];

		@throw [OFAddressTranslationFailedException
		    newWithClass: isa
			    node: node
			 service: service];
	}

	memset(&addr, 0, sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_port = port;

	if (he->h_addrtype != AF_INET || he->h_addr_list[0] == NULL) {

		[mutex unlock];

		@throw [OFAddressTranslationFailedException
		    newWithClass: isa
			    node: node
			 service: service];
	}

	memcpy(&addr.sin_addr.s_addr, he->h_addr_list[0], he->h_length);


	[mutex unlock];


	if (bind(sock, (struct sockaddr*)&addr, sizeof(addr)) == -1)
		@throw [OFBindFailedException newWithClass: isa
						      node: node
						   service: service
						    family: family];
#endif







>
>
>
>
|
>
>
>




>



>
>
>







>
>
>
>












>

>


>

>









>

>











>

>








>

>







196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
#ifdef HAVE_GETADDRINFO
	struct addrinfo hints, *res;

	memset(&hints, 0, sizeof(struct addrinfo));
	hints.ai_family = family;
	hints.ai_socktype = SOCK_STREAM;

#if defined(OF_THREADS) && !defined(HAVE_THREADSAFE_GETADDRINFO)
	[mutex lock];
#endif

	if (getaddrinfo([node cString], [service cString], &hints, &res)) {
#if defined(OF_THREADS) && !defined(HAVE_THREADSAFE_GETADDRINFO)
		[mutex unlock];
#endif
		@throw [OFAddressTranslationFailedException
		    newWithClass: isa
			    node: node
			 service: service];
	}

	if (bind(sock, res->ai_addr, res->ai_addrlen) == -1) {
		freeaddrinfo(res);
#if defined(OF_THREADS) && !defined(HAVE_THREADSAFE_GETADDRINFO)
		[mutex unlock];
#endif
		@throw [OFBindFailedException newWithClass: isa
						      node: node
						   service: service
						    family: family];
	}

	freeaddrinfo(res);

#if defined(OF_THREADS) && !defined(HAVE_THREADSAFE_GETADDRINFO)
	[mutex unlock];
#endif
#else
	struct hostent *he;
	struct servent *se;
	struct sockaddr_in addr;
	uint16_t port;

	if (family != AF_INET)
		@throw [OFBindFailedException newWithClass: isa
						      node: node
						   service: service
						    family: family];

#ifdef OF_THREADS
	[mutex lock];
#endif

	if ((he = gethostbyname([node cString])) == NULL) {
#ifdef OF_THREADS
		[mutex unlock];
#endif
		@throw [OFAddressTranslationFailedException
		    newWithClass: isa
			    node: node
			 service: service];
	}

	if ((se = getservbyname([service cString], "TCP")) != NULL)
		port = se->s_port;
	else if ((port = OF_BSWAP16_IF_LE(atoi([service cString]))) == 0) {
#ifdef OF_THREADS
		[mutex unlock];
#endif
		@throw [OFAddressTranslationFailedException
		    newWithClass: isa
			    node: node
			 service: service];
	}

	memset(&addr, 0, sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_port = port;

	if (he->h_addrtype != AF_INET || he->h_addr_list[0] == NULL) {
#ifdef OF_THREADS
		[mutex unlock];
#endif
		@throw [OFAddressTranslationFailedException
		    newWithClass: isa
			    node: node
			 service: service];
	}

	memcpy(&addr.sin_addr.s_addr, he->h_addr_list[0], he->h_length);

#ifdef OF_THREADS
	[mutex unlock];
#endif

	if (bind(sock, (struct sockaddr*)&addr, sizeof(addr)) == -1)
		@throw [OFBindFailedException newWithClass: isa
						      node: node
						   service: service
						    family: family];
#endif

Modified src/ObjFW.h from [02c23721b3] to [37f9619c34].

29
30
31
32
33
34
35
36
37
38
39
40
41




42
43
44

#import "OFFile.h"

#import "OFSocket.h"
#import "OFTCPSocket.h"

#import "OFHashes.h"
#import "OFThread.h"
#import "OFXMLElement.h"

#ifdef OF_PLUGINS
#import "OFPlugin.h"
#endif





#import "OFMacros.h"
#import "asprintf.h"







<





>
>
>
>



29
30
31
32
33
34
35

36
37
38
39
40
41
42
43
44
45
46
47

#import "OFFile.h"

#import "OFSocket.h"
#import "OFTCPSocket.h"

#import "OFHashes.h"

#import "OFXMLElement.h"

#ifdef OF_PLUGINS
#import "OFPlugin.h"
#endif

#ifdef OF_THREADS
#import "OFThread.h"
#endif

#import "OFMacros.h"
#import "asprintf.h"

Modified src/objfw-defs.h.in from [b3fd317650] to [42800a53ae].

1
2
3
4
5

6
#undef OF_APPLE_RUNTIME
#undef OF_BIG_ENDIAN
#undef OF_GNU_RUNTIME
#undef OF_HAVE_ASPRINTF
#undef OF_PLUGINS

#undef SIZE_MAX





>

1
2
3
4
5
6
7
#undef OF_APPLE_RUNTIME
#undef OF_BIG_ENDIAN
#undef OF_GNU_RUNTIME
#undef OF_HAVE_ASPRINTF
#undef OF_PLUGINS
#undef OF_THREADS
#undef SIZE_MAX

Modified tests/Makefile from [57486b04f8] to [686ed1967d].

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
       OFDictionary.m	\
       OFHashes.m	\
       OFList.m		\
       OFObject.m	\
       ${OFPLUGIN_M}	\
       OFString.m	\
       OFTCPSocket.m	\
       OFThread.m	\
       OFXMLElement.m	\
       OFXMLParser.m	\
       main.m

IPHONE_USER = mobile
IPHONE_TMP = /tmp/objfw-test








|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
       OFDictionary.m	\
       OFHashes.m	\
       OFList.m		\
       OFObject.m	\
       ${OFPLUGIN_M}	\
       OFString.m	\
       OFTCPSocket.m	\
       ${OFTHREAD_M}	\
       OFXMLElement.m	\
       OFXMLParser.m	\
       main.m

IPHONE_USER = mobile
IPHONE_TMP = /tmp/objfw-test

Modified tests/main.m from [513215acfc] to [7efaf05c3f].

26
27
28
29
30
31
32

33

34
35
36
37
38
39
40
extern void list_tests();
extern void object_tests();
#ifdef OF_PLUGINS
extern void plugin_tests();
#endif
extern void string_tests();
extern void tcpsocket_tests();

extern void thread_tests();

extern void xmlelement_tests();
extern void xmlparser_tests();

static int fails = 0;

static void
output(OFString *str, int color)







>

>







26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
extern void list_tests();
extern void object_tests();
#ifdef OF_PLUGINS
extern void plugin_tests();
#endif
extern void string_tests();
extern void tcpsocket_tests();
#ifdef OF_THREADS
extern void thread_tests();
#endif
extern void xmlelement_tests();
extern void xmlparser_tests();

static int fails = 0;

static void
output(OFString *str, int color)
101
102
103
104
105
106
107

108

109
110
111
112
113
114
115
116
	hashes_tests();
	string_tests();
	dataarray_tests();
	array_tests();
	dictionary_tests();
	list_tests();
	tcpsocket_tests();

	thread_tests();

	xmlelement_tests();
	xmlparser_tests();
#ifdef OF_PLUGINS
	plugin_tests();
#endif

	return fails;
}







>

>








103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
	hashes_tests();
	string_tests();
	dataarray_tests();
	array_tests();
	dictionary_tests();
	list_tests();
	tcpsocket_tests();
#ifdef OF_THREADS
	thread_tests();
#endif
	xmlelement_tests();
	xmlparser_tests();
#ifdef OF_PLUGINS
	plugin_tests();
#endif

	return fails;
}