ObjFW  Diff

Differences From Artifact [65cb318889]:

To Artifact [32d271bf6a]:

  • File src/resolver.m — part of check-in [62e2de30b9] at 2015-02-16 08:39:17 on branch trunk — Explicitly pass errno to exceptions

    The old behaviour where the exception would access errno directly on
    creation of the exception was very fragile. The two main problems with
    it were that sometimes it would pick up an errno even though none had
    been set and in other cases that when the exception was created errno
    had already been overridden.

    This also greatly increases errno handling on Win32, especially in
    conjunction with sockets. It can still be improved further, though. (user: js, size: 8618) [annotate] [blame] [check-ins using]


23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <string.h>
#include <inttypes.h>

#import "macros.h"
#import "resolver.h"

#if !defined(HAVE_THREADSAFE_GETADDRINFO) && defined(OF_HAVE_THREADS)
# include "OFMutex.h"
#endif

#import "OFAddressTranslationFailedException.h"
#import "OFInitializationFailedException.h"
#import "OFInvalidArgumentException.h"
#import "OFOutOfMemoryException.h"
#import "OFOutOfRangeException.h"







|







23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <string.h>
#include <inttypes.h>

#import "macros.h"
#import "resolver.h"

#if !defined(HAVE_THREADSAFE_GETADDRINFO) && defined(OF_HAVE_THREADS)
# include "threading.h"
#endif

#import "OFAddressTranslationFailedException.h"
#import "OFInitializationFailedException.h"
#import "OFInvalidArgumentException.h"
#import "OFOutOfMemoryException.h"
#import "OFOutOfRangeException.h"
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

# if !defined(HAVE_THREADSAFE_GETADDRINFO) && defined(OF_HAVE_THREADS)
	if (!of_mutex_lock(&mutex))
		@throw [OFLockFailedException exception];

	@try {
# endif


		if (getaddrinfo([host UTF8String], portCString, &hints, &res0))

			@throw [OFAddressTranslationFailedException
			    exceptionWithHost: host];


		count = 0;
		for (res = res0; res != NULL; res = res->ai_next)
			count++;

		if (count == 0) {
			freeaddrinfo(res0);
			@throw [OFAddressTranslationFailedException
			    exceptionWithHost: host];
		}

		if ((ret = calloc(count + 1, sizeof(*ret))) == NULL) {
			freeaddrinfo(res0);
			@throw [OFOutOfMemoryException
			    exceptionWithRequestedSize:
			    (count + 1) * sizeof(*ret)];
		}

		if ((results = malloc(count * sizeof(*results))) == NULL) {
			freeaddrinfo(res0);
			free(ret);
			@throw [OFOutOfMemoryException
			    exceptionWithRequestedSize:
			    count * sizeof(*results)];
		}

		for (retIter = ret, resultsIter = results, res = res0;
		    res != NULL; retIter++, resultsIter++, res = res->ai_next) {
			resultsIter->family = res->ai_family;
			resultsIter->type = res->ai_socktype;
			resultsIter->protocol = res->ai_protocol;







>
>
|
>

|
>














|
|






|
|







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

# if !defined(HAVE_THREADSAFE_GETADDRINFO) && defined(OF_HAVE_THREADS)
	if (!of_mutex_lock(&mutex))
		@throw [OFLockFailedException exception];

	@try {
# endif
		int error;

		if ((error = getaddrinfo([host UTF8String], portCString, &hints,
		    &res0)) != 0)
			@throw [OFAddressTranslationFailedException
			    exceptionWithHost: host
					error: error];

		count = 0;
		for (res = res0; res != NULL; res = res->ai_next)
			count++;

		if (count == 0) {
			freeaddrinfo(res0);
			@throw [OFAddressTranslationFailedException
			    exceptionWithHost: host];
		}

		if ((ret = calloc(count + 1, sizeof(*ret))) == NULL) {
			freeaddrinfo(res0);
			@throw [OFOutOfMemoryException
			    exceptionWithRequestedSize: (count + 1) *
							sizeof(*ret)];
		}

		if ((results = malloc(count * sizeof(*results))) == NULL) {
			freeaddrinfo(res0);
			free(ret);
			@throw [OFOutOfMemoryException
			    exceptionWithRequestedSize: count *
							sizeof(*results)];
		}

		for (retIter = ret, resultsIter = results, res = res0;
		    res != NULL; retIter++, resultsIter++, res = res->ai_next) {
			resultsIter->family = res->ai_family;
			resultsIter->type = res->ai_socktype;
			resultsIter->protocol = res->ai_protocol;
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

			return ret;
		}

		if ((he = gethostbyname([host UTF8String])) == NULL ||
		    he->h_addrtype != AF_INET)
			@throw [OFAddressTranslationFailedException
			    exceptionWithHost: host];


		count = 0;
		for (ip = he->h_addr_list; *ip != NULL; ip++)
			count++;

		if (count == 0)
			@throw [OFAddressTranslationFailedException
			    exceptionWithHost: host];

		if ((ret = calloc(count + 1, sizeof(*ret))) == NULL)
			@throw [OFOutOfMemoryException
			    exceptionWithRequestedSize:
			    (count + 1) * sizeof(*ret)];

		if ((results = malloc(count * sizeof(*results))) == NULL) {
			free(ret);
			@throw [OFOutOfMemoryException
			    exceptionWithRequestedSize:
			    count * sizeof(*results)];
		}

		if ((addrs = calloc(count, sizeof(*addrs))) == NULL) {
			free(ret);
			free(results);
			@throw [OFOutOfMemoryException
			    exceptionWithRequestedSize: count * sizeof(*addrs)];







|
>











|
|




|
|







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
211
212
213
214

			return ret;
		}

		if ((he = gethostbyname([host UTF8String])) == NULL ||
		    he->h_addrtype != AF_INET)
			@throw [OFAddressTranslationFailedException
			    exceptionWithHost: host
					error: h_errno];

		count = 0;
		for (ip = he->h_addr_list; *ip != NULL; ip++)
			count++;

		if (count == 0)
			@throw [OFAddressTranslationFailedException
			    exceptionWithHost: host];

		if ((ret = calloc(count + 1, sizeof(*ret))) == NULL)
			@throw [OFOutOfMemoryException
			    exceptionWithRequestedSize: (count + 1) *
							sizeof(*ret)];

		if ((results = malloc(count * sizeof(*results))) == NULL) {
			free(ret);
			@throw [OFOutOfMemoryException
			    exceptionWithRequestedSize: count *
							sizeof(*results)];
		}

		if ((addrs = calloc(count, sizeof(*addrs))) == NULL) {
			free(ret);
			free(results);
			@throw [OFOutOfMemoryException
			    exceptionWithRequestedSize: count * sizeof(*addrs)];
249
250
251
252
253
254
255


256
257

258
259

260
261
262
263
264
265
266

# if !defined(HAVE_THREADSAFE_GETADDRINFO) && defined(OF_HAVE_THREADS)
	if (!of_mutex_lock(&mutex))
		@throw [OFLockFailedException exception];

	@try {
# endif


		/* FIXME: Add NI_DGRAM for UDP? */
		if (getnameinfo(address, addressLength, hostCString, NI_MAXHOST,

		    portCString, NI_MAXSERV, NI_NUMERICHOST | NI_NUMERICSERV))
			@throw [OFAddressTranslationFailedException exception];


		if (host != NULL)
			*host = [OFString stringWithUTF8String: hostCString];

		if (port != NULL) {
			char *endptr;
			long tmp;







>
>

|
>
|
|
>







254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275

# if !defined(HAVE_THREADSAFE_GETADDRINFO) && defined(OF_HAVE_THREADS)
	if (!of_mutex_lock(&mutex))
		@throw [OFLockFailedException exception];

	@try {
# endif
		int error;

		/* FIXME: Add NI_DGRAM for UDP? */
		if ((error = getnameinfo(address, addressLength, hostCString,
		    NI_MAXHOST, portCString, NI_MAXSERV,
		    NI_NUMERICHOST | NI_NUMERICSERV)) != 0)
			@throw [OFAddressTranslationFailedException
			    exceptionWithError: error];

		if (host != NULL)
			*host = [OFString stringWithUTF8String: hostCString];

		if (port != NULL) {
			char *endptr;
			long tmp;
291
292
293
294
295
296
297
298

299
300
301
302
303
304
305
	if (!of_mutex_lock(&mutex))
		@throw [OFLockFailedException exception];

	@try {
# endif
		if ((hostCString = inet_ntoa(
		    ((struct sockaddr_in*)(void*)address)->sin_addr)) == NULL)
			@throw [OFAddressTranslationFailedException exception];


		if (host != NULL)
			*host = [OFString stringWithUTF8String: hostCString];

		if (port != NULL)
			*port = OF_BSWAP16_IF_LE(
			    ((struct sockaddr_in*)(void*)address)->sin_port);







|
>







300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
	if (!of_mutex_lock(&mutex))
		@throw [OFLockFailedException exception];

	@try {
# endif
		if ((hostCString = inet_ntoa(
		    ((struct sockaddr_in*)(void*)address)->sin_addr)) == NULL)
			@throw [OFAddressTranslationFailedException
			    exceptionWithError: h_errno];

		if (host != NULL)
			*host = [OFString stringWithUTF8String: hostCString];

		if (port != NULL)
			*port = OF_BSWAP16_IF_LE(
			    ((struct sockaddr_in*)(void*)address)->sin_port);