ObjFW  Changes On Branch 55aa600e97f7a18c

Changes In Branch unix-sockets Through [55aa600e97] Excluding Merge-Ins

This is equivalent to a diff from 051b264d4a to 55aa600e97

2021-10-24
22:29
Merge support for UNIX sockets check-in: d2f5000bb1 user: js tags: trunk
15:14
Add OFUNIXDatagramSocket check-in: 94110c9553 user: js tags: unix-sockets
13:40
Merge trunk into branch "unix-sockets" check-in: 55aa600e97 user: js tags: unix-sockets
11:15
OFScryptTests: Disable 3rd vector on AmigaOS/m68k check-in: 051b264d4a user: js tags: trunk
11:14
OFSystemInfo: Detect OS version & CPU on AmigaOS 3 check-in: 74d7354d62 user: js tags: trunk
2021-04-25
20:25
Minor style fix check-in: 05dbd482bf user: js tags: unix-sockets

Modified configure.ac from [fc81b7df1d] to [75effab5fc].

1329
1330
1331
1332
1333
1334
1335



1336
1337
1338
1339
1340
1341
1342
			[Whether we have netinet/tcp.h])
	])
	AC_CHECK_HEADERS([arpa/inet.h netdb.h])
	AC_CHECK_HEADER(netipx/ipx.h, [
		AC_DEFINE(OF_HAVE_NETIPX_IPX_H, 1,
			[Whether we have netipx/ipx.h])
	])




	AC_CHECK_MEMBER([struct sockaddr_in6.sin6_addr], [
		AC_EGREP_CPP(egrep_cpp_yes, [
			#ifdef _WIN32
			typedef int BOOL;
			#endif








>
>
>







1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
			[Whether we have netinet/tcp.h])
	])
	AC_CHECK_HEADERS([arpa/inet.h netdb.h])
	AC_CHECK_HEADER(netipx/ipx.h, [
		AC_DEFINE(OF_HAVE_NETIPX_IPX_H, 1,
			[Whether we have netipx/ipx.h])
	])
	AC_CHECK_HEADERS(sys/un.h, [
		AC_DEFINE(OF_HAVE_SYS_UN_H, 1, [Whether we have sys/un.h])
	])

	AC_CHECK_MEMBER([struct sockaddr_in6.sin6_addr], [
		AC_EGREP_CPP(egrep_cpp_yes, [
			#ifdef _WIN32
			typedef int BOOL;
			#endif

1453
1454
1455
1456
1457
1458
1459









1460
1461
1462
1463
1464
1465
1466
			egrep_cpp_yes
			#endif
		], [
			AC_DEFINE(OF_HAVE_IPX, 1, [Whether we have IPX/SPX])
			AC_SUBST(USE_SRCS_IPX, '${SRCS_IPX}')
		])
	])










	AC_CHECK_FUNCS(paccept accept4, break)

	AC_CHECK_FUNCS(kqueue1 kqueue, [
		AC_DEFINE(HAVE_KQUEUE, 1, [Whether we have kqueue])
		AC_SUBST(OF_KQUEUE_KERNEL_EVENT_OBSERVER_M,
			"OFKqueueKernelEventObserver.m")







>
>
>
>
>
>
>
>
>







1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
			egrep_cpp_yes
			#endif
		], [
			AC_DEFINE(OF_HAVE_IPX, 1, [Whether we have IPX/SPX])
			AC_SUBST(USE_SRCS_IPX, '${SRCS_IPX}')
		])
	])

	AC_CHECK_MEMBER(struct sockaddr_un.sun_path, [
		AC_DEFINE(OF_HAVE_UNIX_SOCKETS, 1,
			[Whether we have UNIX sockets])
	], [], [
		#ifdef OF_HAVE_SYS_UN_H
		# include <sys/un.h>
		#endif
	])

	AC_CHECK_FUNCS(paccept accept4, break)

	AC_CHECK_FUNCS(kqueue1 kqueue, [
		AC_DEFINE(HAVE_KQUEUE, 1, [Whether we have kqueue])
		AC_SUBST(OF_KQUEUE_KERNEL_EVENT_OBSERVER_M,
			"OFKqueueKernelEventObserver.m")

Modified src/OFSocket.h from [2b4aae9d25] to [b11ec9bdab].

34
35
36
37
38
39
40



41
42
43
44
45
46
47
#endif
#ifdef OF_HAVE_NETINET_TCP_H
# include <netinet/tcp.h>
#endif
#ifdef OF_HAVE_NETIPX_IPX_H
# include <netipx/ipx.h>
#endif




#ifdef OF_WINDOWS
# include <windows.h>
# include <ws2tcpip.h>
# ifdef OF_HAVE_IPX
#  include <wsipx.h>
# endif







>
>
>







34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#endif
#ifdef OF_HAVE_NETINET_TCP_H
# include <netinet/tcp.h>
#endif
#ifdef OF_HAVE_NETIPX_IPX_H
# include <netipx/ipx.h>
#endif
#ifdef OF_HAVE_SYS_UN_H
# include <sys/un.h>
#endif

#ifdef OF_WINDOWS
# include <windows.h>
# include <ws2tcpip.h>
# ifdef OF_HAVE_IPX
#  include <wsipx.h>
# endif
64
65
66
67
68
69
70




71
72
73
74
75
76
77
#ifndef OF_WINDOWS
typedef int OFSocketHandle;
static const OFSocketHandle OFInvalidSocketHandle = -1;
#else
typedef SOCKET OFSocketHandle;
static const OFSocketHandle OFInvalidSocketHandle = INVALID_SOCKET;
#endif





#ifdef OF_WII
typedef u8 sa_family_t;
#endif

#ifdef OF_MORPHOS
typedef long socklen_t;







>
>
>
>







67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#ifndef OF_WINDOWS
typedef int OFSocketHandle;
static const OFSocketHandle OFInvalidSocketHandle = -1;
#else
typedef SOCKET OFSocketHandle;
static const OFSocketHandle OFInvalidSocketHandle = INVALID_SOCKET;
#endif

#ifdef OF_WINDOWS
typedef short sa_family_t;
#endif

#ifdef OF_WII
typedef u8 sa_family_t;
#endif

#ifdef OF_MORPHOS
typedef long socklen_t;
87
88
89
90
91
92
93


94
95
96
97
98
99
100
	OFSocketAddressFamilyUnknown,
	/** IPv4 */
	OFSocketAddressFamilyIPv4,
	/** IPv6 */
	OFSocketAddressFamilyIPv6,
	/** IPX */
	OFSocketAddressFamilyIPX,


	/** Any address family */
	OFSocketAddressFamilyAny = 255
} OFSocketAddressFamily;

#ifndef OF_HAVE_IPV6
struct sockaddr_in6 {
	sa_family_t sin6_family;







>
>







94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
	OFSocketAddressFamilyUnknown,
	/** IPv4 */
	OFSocketAddressFamilyIPv4,
	/** IPv6 */
	OFSocketAddressFamilyIPv6,
	/** IPX */
	OFSocketAddressFamilyIPX,
	/** UNIX */
	OFSocketAddressFamilyUNIX,
	/** Any address family */
	OFSocketAddressFamilyAny = 255
} OFSocketAddressFamily;

#ifndef OF_HAVE_IPV6
struct sockaddr_in6 {
	sa_family_t sin6_family;
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
# define IPX_NODE_LEN 6
# define sipx_family sa_family
# define sipx_network sa_netnum
# define sipx_node sa_nodenum
# define sipx_port sa_socket
#endif








/**
 * @struct OFSocketAddress OFSocket.h ObjFW/OFSocket.h
 *
 * @brief A struct which represents a host / port pair for a socket.
 */
typedef struct OF_BOXABLE {
	/*
	 * Even though struct sockaddr contains the family, we need to use our
	 * own family, as we need to support storing an IPv6 address on systems
	 * that don't support IPv6. These may not have AF_INET6 defined and we
	 * can't just define it, as the value is system-dependent and might
	 * clash with an existing value.
	 */
	OFSocketAddressFamily family;
	union {
		struct sockaddr sockaddr;
		struct sockaddr_in in;
		struct sockaddr_in6 in6;
		struct sockaddr_ipx ipx;

	} sockaddr;
	socklen_t length;
} OFSocketAddress;

#ifdef __cplusplus
extern "C" {
#endif







>
>
>
>
>
>
>



















>







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
# define IPX_NODE_LEN 6
# define sipx_family sa_family
# define sipx_network sa_netnum
# define sipx_node sa_nodenum
# define sipx_port sa_socket
#endif

#ifndef OF_HAVE_UNIX_SOCKETS
struct sockaddr_un {
	sa_family_t sun_family;
	char sun_path[108];
};
#endif

/**
 * @struct OFSocketAddress OFSocket.h ObjFW/OFSocket.h
 *
 * @brief A struct which represents a host / port pair for a socket.
 */
typedef struct OF_BOXABLE {
	/*
	 * Even though struct sockaddr contains the family, we need to use our
	 * own family, as we need to support storing an IPv6 address on systems
	 * that don't support IPv6. These may not have AF_INET6 defined and we
	 * can't just define it, as the value is system-dependent and might
	 * clash with an existing value.
	 */
	OFSocketAddressFamily family;
	union {
		struct sockaddr sockaddr;
		struct sockaddr_in in;
		struct sockaddr_in6 in6;
		struct sockaddr_ipx ipx;
		struct sockaddr_un un;
	} sockaddr;
	socklen_t length;
} OFSocketAddress;

#ifdef __cplusplus
extern "C" {
#endif
176
177
178
179
180
181
182
183
184
185
186
187

188
189
190
191
192








193
194
195
196
197
198
199
 * @param IP The IPv6 to parse
 * @param port The port to use
 * @return The parsed IPv6 and port as an OFSocketAddress
 */
extern OFSocketAddress OFSocketAddressParseIPv6(OFString *IP, uint16_t port);

/**
 * @brief Creates an IPX address for the specified network, node and port.
 *
 * @param node The node in the IPX network
 * @param network The IPX network
 * @param port The IPX port (sometimes called socket number) on the node

 */
extern OFSocketAddress OFSocketAddressMakeIPX(
    const unsigned char node[_Nonnull IPX_NODE_LEN], uint32_t network,
    uint16_t port);









/**
 * @brief Compares two OFSocketAddress for equality.
 *
 * @param address1 The address to compare with the second address
 * @param address2 The second address
 * @return Whether the two addresses are equal
 */







|




>





>
>
>
>
>
>
>
>







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
 * @param IP The IPv6 to parse
 * @param port The port to use
 * @return The parsed IPv6 and port as an OFSocketAddress
 */
extern OFSocketAddress OFSocketAddressParseIPv6(OFString *IP, uint16_t port);

/**
 * @brief Creates an IPX address for the specified node, network and port.
 *
 * @param node The node in the IPX network
 * @param network The IPX network
 * @param port The IPX port (sometimes called socket number) on the node
 * @return An IPX socket address with the specified node, network and port.
 */
extern OFSocketAddress OFSocketAddressMakeIPX(
    const unsigned char node[_Nonnull IPX_NODE_LEN], uint32_t network,
    uint16_t port);

/**
 * @brief Creates a UNIX socket address from the specified path.
 *
 * @param path The path of the UNIX socket
 * @return A UNIX socket address with the specified path
 */
extern OFSocketAddress OFSocketAddressMakeUNIX(OFString *path);

/**
 * @brief Compares two OFSocketAddress for equality.
 *
 * @param address1 The address to compare with the second address
 * @param address2 The second address
 * @return Whether the two addresses are equal
 */
269
270
271
272
273
274
275









276
277
278
279
280
281
282
 *
 * @param address The address on which to get the IPX node
 * @param node A byte array to store the IPX node of the address
 */
extern void OFSocketAddressIPXNode(const OFSocketAddress *_Nonnull address,
    unsigned char node[_Nonnull IPX_NODE_LEN]);










extern bool OFSocketInit(void);
#if defined(OF_HAVE_THREADS) && defined(OF_AMIGAOS) && !defined(OF_MORPHOS)
extern void OFSocketDeinit(void);
#endif
extern int OFSocketErrNo(void);
#if !defined(OF_WII) && !defined(OF_NINTENDO_3DS)
extern int OFGetSockName(OFSocketHandle sock, struct sockaddr *restrict addr,







>
>
>
>
>
>
>
>
>







295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
 *
 * @param address The address on which to get the IPX node
 * @param node A byte array to store the IPX node of the address
 */
extern void OFSocketAddressIPXNode(const OFSocketAddress *_Nonnull address,
    unsigned char node[_Nonnull IPX_NODE_LEN]);

/**
 * @brief Gets the UNIX socket path of the specified @ref OFSocketAddress.
 *
 * @param address The address on which to get the UNIX socket path
 * @return The UNIX socket path
 */
extern OFString *_Nullable OFSocketAddressUNIXPath(
    const OFSocketAddress *_Nonnull address);

extern bool OFSocketInit(void);
#if defined(OF_HAVE_THREADS) && defined(OF_AMIGAOS) && !defined(OF_MORPHOS)
extern void OFSocketDeinit(void);
#endif
extern int OFSocketErrNo(void);
#if !defined(OF_WII) && !defined(OF_NINTENDO_3DS)
extern int OFGetSockName(OFSocketHandle sock, struct sockaddr *restrict addr,

Modified src/OFSocket.m from [941bbd3cbe] to [25a9151924].

41
42
43
44
45
46
47

48
49
50
51
52
53
54
#endif

#import "OFException.h"  /* For some E* -> WSAE* defines */
#import "OFInitializationFailedException.h"
#import "OFInvalidArgumentException.h"
#import "OFInvalidFormatException.h"
#import "OFLockFailedException.h"

#import "OFUnlockFailedException.h"

#ifdef OF_AMIGAOS
# include <proto/exec.h>
#endif

#ifdef OF_NINTENDO_3DS







>







41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#endif

#import "OFException.h"  /* For some E* -> WSAE* defines */
#import "OFInitializationFailedException.h"
#import "OFInvalidArgumentException.h"
#import "OFInvalidFormatException.h"
#import "OFLockFailedException.h"
#import "OFOutOfRangeException.h"
#import "OFUnlockFailedException.h"

#ifdef OF_AMIGAOS
# include <proto/exec.h>
#endif

#ifdef OF_NINTENDO_3DS
532
533
534
535
536
537
538





























539
540
541
542
543
544
545
546



547
548
549
550
551
552
553
	network = OFToBigEndian32(network);
	memcpy(&ret.sockaddr.ipx.sipx_network, &network,
	    sizeof(ret.sockaddr.ipx.sipx_network));
	ret.sockaddr.ipx.sipx_port = OFToBigEndian16(port);

	return ret;
}






























bool
OFSocketAddressEqual(const OFSocketAddress *address1,
    const OFSocketAddress *address2)
{
	const struct sockaddr_in *addrIn1, *addrIn2;
	const struct sockaddr_in6 *addrIn6_1, *addrIn6_2;
	const struct sockaddr_ipx *addrIPX1, *addrIPX2;




	if (address1->family != address2->family)
		return false;

	switch (address1->family) {
	case OFSocketAddressFamilyIPv4:
#if defined(OF_WII) || defined(OF_NINTENDO_3DS)







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








>
>
>







533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
	network = OFToBigEndian32(network);
	memcpy(&ret.sockaddr.ipx.sipx_network, &network,
	    sizeof(ret.sockaddr.ipx.sipx_network));
	ret.sockaddr.ipx.sipx_port = OFToBigEndian16(port);

	return ret;
}

OFSocketAddress
OFSocketAddressMakeUNIX(OFString *path)
{
	void *pool = objc_autoreleasePoolPush();
	OFStringEncoding encoding = [OFLocale encoding];
	size_t length = [path cStringLengthWithEncoding: encoding];
	OFSocketAddress ret;

	if (length > sizeof(ret.sockaddr.un.sun_path))
		@throw [OFOutOfRangeException exception];

	memset(&ret, '\0', sizeof(ret));
	ret.family = OFSocketAddressFamilyUNIX;
	ret.length = (socklen_t)(sizeof(ret.sockaddr.un) -
	    (sizeof(ret.sockaddr.un.sun_path) - length));

#ifdef AF_UNIX
	ret.sockaddr.un.sun_family = AF_UNIX;
#else
	ret.sockaddr.un.sun_family = AF_UNSPEC;
#endif
	memcpy(ret.sockaddr.un.sun_path,
	    [path cStringWithEncoding: encoding], length);

	objc_autoreleasePoolPop(pool);

	return ret;
}

bool
OFSocketAddressEqual(const OFSocketAddress *address1,
    const OFSocketAddress *address2)
{
	const struct sockaddr_in *addrIn1, *addrIn2;
	const struct sockaddr_in6 *addrIn6_1, *addrIn6_2;
	const struct sockaddr_ipx *addrIPX1, *addrIPX2;
	void *pool;
	OFString *path1, *path2;
	bool ret;

	if (address1->family != address2->family)
		return false;

	switch (address1->family) {
	case OFSocketAddressFamilyIPv4:
#if defined(OF_WII) || defined(OF_NINTENDO_3DS)
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603







604


605

606


607


608











609



610
611
612
613
614
615
616
		addrIn2 = &address2->sockaddr.in;

		if (addrIn1->sin_port != addrIn2->sin_port)
			return false;
		if (addrIn1->sin_addr.s_addr != addrIn2->sin_addr.s_addr)
			return false;

		break;
	case OFSocketAddressFamilyIPv6:
		if (address1->length < (socklen_t)sizeof(struct sockaddr_in6) ||
		    address2->length < (socklen_t)sizeof(struct sockaddr_in6))
			@throw [OFInvalidArgumentException exception];

		addrIn6_1 = &address1->sockaddr.in6;
		addrIn6_2 = &address2->sockaddr.in6;

		if (addrIn6_1->sin6_port != addrIn6_2->sin6_port)
			return false;
		if (memcmp(addrIn6_1->sin6_addr.s6_addr,
		    addrIn6_2->sin6_addr.s6_addr,
		    sizeof(addrIn6_1->sin6_addr.s6_addr)) != 0)
			return false;

		break;
	case OFSocketAddressFamilyIPX:
		if (address1->length < (socklen_t)sizeof(struct sockaddr_ipx) ||
		    address2->length < (socklen_t)sizeof(struct sockaddr_ipx))
			@throw [OFInvalidArgumentException exception];

		addrIPX1 = &address1->sockaddr.ipx;
		addrIPX2 = &address2->sockaddr.ipx;

		if (addrIPX1->sipx_port != addrIPX2->sipx_port)
			return false;
		if (memcmp(&addrIPX1->sipx_network, &addrIPX2->sipx_network,
		    4) != 0)
			return false;
		if (memcmp(addrIPX1->sipx_node, addrIPX2->sipx_node,
		    IPX_NODE_LEN) != 0)
			return false;








		break;


	default:

		@throw [OFInvalidArgumentException exception];


	}














	return true;



}

unsigned long
OFSocketAddressHash(const OFSocketAddress *address)
{
	unsigned long hash;








|















|

















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

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







596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
		addrIn2 = &address2->sockaddr.in;

		if (addrIn1->sin_port != addrIn2->sin_port)
			return false;
		if (addrIn1->sin_addr.s_addr != addrIn2->sin_addr.s_addr)
			return false;

		return true;
	case OFSocketAddressFamilyIPv6:
		if (address1->length < (socklen_t)sizeof(struct sockaddr_in6) ||
		    address2->length < (socklen_t)sizeof(struct sockaddr_in6))
			@throw [OFInvalidArgumentException exception];

		addrIn6_1 = &address1->sockaddr.in6;
		addrIn6_2 = &address2->sockaddr.in6;

		if (addrIn6_1->sin6_port != addrIn6_2->sin6_port)
			return false;
		if (memcmp(addrIn6_1->sin6_addr.s6_addr,
		    addrIn6_2->sin6_addr.s6_addr,
		    sizeof(addrIn6_1->sin6_addr.s6_addr)) != 0)
			return false;

		return true;
	case OFSocketAddressFamilyIPX:
		if (address1->length < (socklen_t)sizeof(struct sockaddr_ipx) ||
		    address2->length < (socklen_t)sizeof(struct sockaddr_ipx))
			@throw [OFInvalidArgumentException exception];

		addrIPX1 = &address1->sockaddr.ipx;
		addrIPX2 = &address2->sockaddr.ipx;

		if (addrIPX1->sipx_port != addrIPX2->sipx_port)
			return false;
		if (memcmp(&addrIPX1->sipx_network, &addrIPX2->sipx_network,
		    4) != 0)
			return false;
		if (memcmp(addrIPX1->sipx_node, addrIPX2->sipx_node,
		    IPX_NODE_LEN) != 0)
			return false;

		return true;
	case OFSocketAddressFamilyUNIX:
		/*
		 * This is a bit tricky. The only thing that is well-defined is
		 * the path. So compare the path, and if both don't have a
		 * path, compare bytes.
		 */

		if (address1->length != address2->length)
			return false;

		pool = objc_autoreleasePoolPush();

		path1 = OFSocketAddressUNIXPath(address1);
		path2 = OFSocketAddressUNIXPath(address2);

		if (path1 == nil && path2 == nil) {
			objc_autoreleasePoolPop(pool);

			return (memcmp(&address1->sockaddr.un,
			    &address2->sockaddr.un, address1->length) == 0);
		}

		if (path1 == nil || path2 == nil)
			ret = false;
		else
			ret = [path1 isEqual: path2];

		objc_autoreleasePoolPop(pool);

		return ret;
	default:
		@throw [OFInvalidArgumentException exception];
	}
}

unsigned long
OFSocketAddressHash(const OFSocketAddress *address)
{
	unsigned long hash;

663
664
665
666
667
668
669






















670
671
672
673
674
675
676

		for (size_t i = 0; i < sizeof(network); i++)
			OFHashAdd(&hash, network[i]);

		for (size_t i = 0; i < IPX_NODE_LEN; i++)
			OFHashAdd(&hash, address->sockaddr.ipx.sipx_node[i]);























		break;
	default:
		@throw [OFInvalidArgumentException exception];
	}

	OFHashFinalize(&hash);








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







724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759

		for (size_t i = 0; i < sizeof(network); i++)
			OFHashAdd(&hash, network[i]);

		for (size_t i = 0; i < IPX_NODE_LEN; i++)
			OFHashAdd(&hash, address->sockaddr.ipx.sipx_node[i]);

		break;
	case OFSocketAddressFamilyUNIX:;
		/*
		 * This is a bit tricky. The only thing that is well-defined is
		 * the path. So hash the path if we have one, otherwise the
		 * bytes.
		 */
		void *pool = objc_autoreleasePoolPush();
		OFString *path = OFSocketAddressUNIXPath(address);

		if (path != nil) {
			hash = path.hash;
			objc_autoreleasePoolPop(pool);
			return hash;
		}

		objc_autoreleasePoolPop(pool);

		for (socklen_t i = 0; i < address->length; i++)
			OFHashAdd(&hash,
			    ((const char *)&address->sockaddr.un)[i]);

		break;
	default:
		@throw [OFInvalidArgumentException exception];
	}

	OFHashFinalize(&hash);

843
844
845
846
847
848
849





















    unsigned char node[IPX_NODE_LEN])
{
	if (address->family != OFSocketAddressFamilyIPX)
		@throw [OFInvalidArgumentException exception];

	memcpy(node, address->sockaddr.ipx.sipx_node, IPX_NODE_LEN);
}




























>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
    unsigned char node[IPX_NODE_LEN])
{
	if (address->family != OFSocketAddressFamilyIPX)
		@throw [OFInvalidArgumentException exception];

	memcpy(node, address->sockaddr.ipx.sipx_node, IPX_NODE_LEN);
}

OFString *
OFSocketAddressUNIXPath(const OFSocketAddress *_Nonnull address)
{
	socklen_t maxLength = (socklen_t)sizeof(address->sockaddr.un);
	size_t length;

	if (address->family != OFSocketAddressFamilyUNIX ||
	    address->length > maxLength)
		@throw [OFInvalidArgumentException exception];

	length = sizeof(address->sockaddr.un.sun_path) -
	    (maxLength - address->length);

	if (length == 0)
		return nil;

	return [OFString stringWithCString: address->sockaddr.un.sun_path
				  encoding: [OFLocale encoding]
				    length: length];
}

Modified src/objfw-defs.h.in from [dc6785c3be] to [b4d2598296].

30
31
32
33
34
35
36

37
38

39
40
41
42
43
44
45
46
#undef OF_HAVE_SCHED_YIELD
#undef OF_HAVE_SOCKETS
#undef OF_HAVE_STDNORETURN
#undef OF_HAVE_SYMLINK
#undef OF_HAVE_SYNC_BUILTINS
#undef OF_HAVE_SYS_SOCKET_H
#undef OF_HAVE_SYS_TYPES_H

#undef OF_HAVE_THREADS
#undef OF_HAVE_UNICODE_TABLES

#undef OF_HAVE__THREAD_LOCAL
#undef OF_HAVE___THREAD
#undef OF_NINTENDO_3DS
#undef OF_NINTENDO_DS
#undef OF_NO_SHARED
#undef OF_OBJFW_RUNTIME
#undef OF_UNIVERSAL
#undef OF_WII







>


>








30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#undef OF_HAVE_SCHED_YIELD
#undef OF_HAVE_SOCKETS
#undef OF_HAVE_STDNORETURN
#undef OF_HAVE_SYMLINK
#undef OF_HAVE_SYNC_BUILTINS
#undef OF_HAVE_SYS_SOCKET_H
#undef OF_HAVE_SYS_TYPES_H
#undef OF_HAVE_SYS_UN_H
#undef OF_HAVE_THREADS
#undef OF_HAVE_UNICODE_TABLES
#undef OF_HAVE_UNIX_SOCKETS
#undef OF_HAVE__THREAD_LOCAL
#undef OF_HAVE___THREAD
#undef OF_NINTENDO_3DS
#undef OF_NINTENDO_DS
#undef OF_NO_SHARED
#undef OF_OBJFW_RUNTIME
#undef OF_UNIVERSAL
#undef OF_WII