fix logic
[personal-kdelibs.git] / kdecore / network / k3socketaddress.cpp
blobf7d9e1866d94e887a7c731de193c5b433ed4344d
1 /* -*- C++ -*-
2 * Copyright (C) 2003 Thiago Macieira <thiago@kde.org>
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 #include "k3socketaddress.h"
27 #include <config.h>
28 #include <config-network.h>
30 #include <sys/types.h>
31 #include <sys/socket.h>
32 #include <sys/un.h>
33 #include <arpa/inet.h>
34 #include <netinet/in.h>
35 #include <string.h>
36 #include <stdlib.h>
37 #include <unistd.h>
39 #include <QFile>
40 #include <QObject>
42 #include "klocale.h"
44 #ifndef Q_CC_MSVC
45 #include "netsupp.h"
46 #endif
48 using namespace KNetwork;
50 #if 0
51 class KIpAddress_localhostV4 : public KIpAddress
53 public:
54 KIpAddress_localhostV4()
56 *m_data = htonl(0x7f000001);
57 m_version = 4;
61 class KIpAddress_localhostV6 : public KIpAddress
63 public:
64 KIpAddress_localhostV6()
65 : KIpAddress(0L, 6)
67 m_data[3] = htonl(1);
70 #endif
72 static const char localhostV4_data[] = { 127, 0, 0, 1 };
73 static const char localhostV6_data[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,1 };
75 const KIpAddress KIpAddress::localhostV4(&localhostV4_data, 4);
76 const KIpAddress KIpAddress::localhostV6(&localhostV6_data, 6);
77 const KIpAddress KIpAddress::anyhostV4(0L, 4);
78 const KIpAddress KIpAddress::anyhostV6(0L, 6);
80 // helper function to test if an IPv6 v4-mapped address is equal to its IPv4 counterpart
81 static bool check_v4mapped(const quint32* v6addr, quint32 v4addr)
83 // check that the v6 is a v4-mapped address
84 if (!(v6addr[0] == 0 && v6addr[1] == 0 && v6addr[2] == htonl(0x0000ffff)))
85 return false; // not a v4-mapped address
87 return v6addr[3] == v4addr;
90 // copy operator
91 KIpAddress& KIpAddress::operator =(const KIpAddress& other)
93 m_version = other.m_version;
94 if (m_version == 4 || m_version == 6)
95 memcpy(m_data, other.m_data, sizeof(m_data));
96 return *this;
99 // comparison
100 bool KIpAddress::compare(const KIpAddress& other, bool checkMapped) const
102 if (m_version == other.m_version)
103 switch (m_version)
105 case 0:
106 // both objects are empty
107 return true;
109 case 4:
110 // IPv4 address
111 return *m_data == *other.m_data;
113 case 6:
114 // IPv6 address
115 // they are 128-bit long, that is, 16 bytes
116 return memcmp(m_data, other.m_data, 16) == 0;
119 if (checkMapped)
121 // check the possibility of a v4-mapped address being compared to an IPv4 one
122 if (m_version == 6 && other.m_version == 4 && check_v4mapped(m_data, *other.m_data))
123 return true;
125 if (other.m_version == 6 && m_version == 4 && check_v4mapped(other.m_data, *m_data))
126 return true;
129 return false;
132 // sets the address to the given address
133 bool KIpAddress::setAddress(const QString& address)
135 m_version = 0;
137 // try to guess the address version
138 if (address.indexOf(':') != -1)
140 #ifdef AF_INET6
141 // guessing IPv6
143 quint32 buf[4];
144 if (inet_pton(AF_INET6, address.toLatin1(), buf))
146 memcpy(m_data, buf, sizeof(m_data));
147 m_version = 6;
148 return true;
150 #endif
152 return false;
154 else
156 quint32 buf;
157 if (inet_pton(AF_INET, address.toLatin1(), &buf))
159 *m_data = buf;
160 m_version = 4;
161 return true;
164 return false;
167 return false; // can never happen!
170 bool KIpAddress::setAddress(const char* address)
172 return setAddress(QLatin1String(address));
175 // set from binary data
176 bool KIpAddress::setAddress(const void* raw, int version)
178 // this always succeeds
179 // except if version is invalid
180 if (version != 4 && version != 6)
181 return false;
183 m_version = version;
184 if (raw != 0L)
185 memcpy(m_data, raw, version == 4 ? 4 : 16);
186 else
187 memset(m_data, 0, 16);
189 return true;
192 // presentation form
193 QString KIpAddress::toString() const
195 char buf[sizeof "1111:2222:3333:4444:5555:6666:255.255.255.255" + 2];
196 buf[0] = '\0';
197 switch (m_version)
199 case 4:
200 inet_ntop(AF_INET, (void*)m_data, buf, sizeof(buf) - 1);
201 return QLatin1String(buf);
203 case 6:
204 #ifdef AF_INET6
205 inet_ntop(AF_INET6, (void*)m_data, buf, sizeof(buf) - 1);
206 #endif
207 return QLatin1String(buf);
210 return QString();
214 * An IPv6 socket address
215 * This is taken from RFC 2553.
217 struct our_sockaddr_in6
219 # ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
220 quint8 sin6_len;
221 quint8 sin6_family;
222 # else //!HAVE_STRUCT_SOCKADDR_SA_LEN
223 quint16 sin6_family;
224 # endif
225 quint16 sin6_port; /* RFC says in_port_t */
226 quint32 sin6_flowinfo;
227 quint8 sin6_addr[16]; // 24 bytes up to here
228 quint32 sin6_scope_id; // 28 bytes total
231 // useful definitions
232 #define MIN_SOCKADDR_LEN sizeof(quint16)
233 #define SOCKADDR_IN_LEN sizeof(sockaddr_in)
234 #define MIN_SOCKADDR_IN6_LEN ((unsigned long) &(((our_sockaddr_in6*)0)->sin6_scope_id))
235 #define SOCKADDR_IN6_LEN sizeof(our_sockaddr_in6)
236 #define MIN_SOCKADDR_UN_LEN (sizeof(quint16) + sizeof(char))
239 class KNetwork::KSocketAddressData
241 public:
243 * Note: maybe this should be virtual
244 * But since the data is shared via the d pointer, it doesn't really matter
245 * what one class sees, so will the other
247 class QMixSocketAddressRef : public KInetSocketAddress, public KUnixSocketAddress
249 public:
250 QMixSocketAddressRef(KSocketAddressData* d)
251 : KInetSocketAddress(d), KUnixSocketAddress(d)
255 QMixSocketAddressRef ref;
257 union
259 struct sockaddr *generic;
260 struct sockaddr_in *in;
261 struct our_sockaddr_in6 *in6;
262 struct sockaddr_un *un;
263 } addr;
264 quint16 curlen, reallen;
266 KSocketAddressData()
267 : ref(this)
269 addr.generic = 0L;
270 curlen = 0;
271 invalidate();
274 ~KSocketAddressData()
276 if (addr.generic != 0L)
277 free(addr.generic);
280 inline bool invalid() const
281 { return reallen == 0; }
283 inline void invalidate()
284 { reallen = 0; }
286 void dup(const sockaddr* sa, quint16 len, bool clear = true);
288 void makeipv4()
290 short oldport = 0;
291 if (!invalid())
292 switch (addr.generic->sa_family)
294 case AF_INET:
295 return; // nothing to do here
296 #ifdef AF_INET6
297 case AF_INET6:
298 oldport = addr.in6->sin6_port;
299 break;
300 #endif
303 // create new space
304 dup(0L, SOCKADDR_IN_LEN);
306 addr.in->sin_family = AF_INET;
307 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
308 addr.in->sin_len = SOCKADDR_IN_LEN;
309 #endif
310 addr.in->sin_port = oldport;
313 void makeipv6()
315 short oldport = 0;
316 if (!invalid())
317 switch (addr.generic->sa_family)
319 case AF_INET:
320 oldport = addr.in->sin_port;
321 break;
323 #ifdef AF_INET6
324 case AF_INET6:
325 return; // nothing to do here
326 #endif
329 // make room
330 dup(0L, SOCKADDR_IN6_LEN);
331 #ifdef AF_INET6
332 addr.in6->sin6_family = AF_INET6;
333 #endif
334 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
335 addr.in6->sin6_len = SOCKADDR_IN6_LEN;
336 #endif
337 addr.in6->sin6_port = oldport;
338 // sin6_scope_id and sin6_flowid are zero
343 // create duplicates of
344 void KSocketAddressData::dup(const sockaddr* sa, quint16 len, bool clear)
346 if (len < MIN_SOCKADDR_LEN)
348 // certainly invalid
349 invalidate();
350 return;
353 if (sa && ((sa->sa_family == AF_INET && len < SOCKADDR_IN_LEN) ||
354 #ifdef AF_INET6
355 (sa->sa_family == AF_INET6 && len < MIN_SOCKADDR_IN6_LEN) ||
356 #endif
357 (sa->sa_family == AF_UNIX && len < MIN_SOCKADDR_UN_LEN)))
359 // also invalid
360 invalidate();
361 return;
364 // good
365 reallen = len;
366 if (len > curlen)
368 if (len < 32)
369 curlen = 32; // big enough for sockaddr_in and sockaddr_in6
370 else
371 curlen = len;
372 addr.generic = (sockaddr*)realloc(addr.generic, curlen);
375 if (sa != 0L)
377 memcpy(addr.generic, sa, len); // copy
379 // now, normalise the data
380 if (addr.generic->sa_family == AF_INET)
381 reallen = SOCKADDR_IN_LEN; // no need to be larger
382 #ifdef AF_INET6
383 else if (addr.generic->sa_family == AF_INET6)
385 // set the extra field (sin6_scope_id)
387 // the buffer is never smaller than 32 bytes, so this is always
388 // allowed
389 if (reallen < SOCKADDR_IN6_LEN)
390 addr.in6->sin6_scope_id = 0;
392 reallen = SOCKADDR_IN6_LEN;
394 #endif
395 else if (addr.generic->sa_family == AF_UNIX)
396 reallen = MIN_SOCKADDR_UN_LEN + strlen(addr.un->sun_path);
398 else if (clear)
400 memset(addr.generic, 0, len);
401 addr.generic->sa_family = AF_UNSPEC;
405 // default constructor
406 KSocketAddress::KSocketAddress()
407 : d(new KSocketAddressData)
411 // constructor from binary data
412 KSocketAddress::KSocketAddress(const sockaddr *sa, quint16 len)
413 : d(new KSocketAddressData)
415 setAddress(sa, len);
418 KSocketAddress::KSocketAddress(const KSocketAddress& other)
419 : d(new(KSocketAddressData))
421 *this = other;
424 KSocketAddress::KSocketAddress(KSocketAddressData *d2)
425 : d(d2)
429 KSocketAddress::~KSocketAddress()
431 // prevent double-deletion, since we're already being deleted
432 if (d)
434 d->ref.KInetSocketAddress::d = 0L;
435 d->ref.KUnixSocketAddress::d = 0L;
436 delete d;
440 KSocketAddress& KSocketAddress::operator =(const KSocketAddress& other)
442 if (other.d && !other.d->invalid())
443 d->dup(other.d->addr.generic, other.d->reallen);
444 else
445 d->invalidate();
446 return *this;
449 const sockaddr* KSocketAddress::address() const
451 if (d->invalid())
452 return 0L;
453 return d->addr.generic;
456 sockaddr* KSocketAddress::address()
458 if (d->invalid())
459 return 0L;
460 return d->addr.generic;
463 KSocketAddress& KSocketAddress::setAddress(const sockaddr* sa, quint16 len)
465 if (sa != 0L && len >= MIN_SOCKADDR_LEN)
466 d->dup(sa, len);
467 else
468 d->invalidate();
470 return *this;
473 quint16 KSocketAddress::length() const
475 if (d->invalid())
476 return 0;
477 return d->reallen;
480 KSocketAddress& KSocketAddress::setLength(quint16 len)
482 d->dup((sockaddr*)0L, len, false);
484 return *this;
487 int KSocketAddress::family() const
489 if (d->invalid())
490 return AF_UNSPEC;
491 return d->addr.generic->sa_family;
494 KSocketAddress& KSocketAddress::setFamily(int family)
496 if (d->invalid())
497 d->dup((sockaddr*)0L, MIN_SOCKADDR_LEN);
498 d->addr.generic->sa_family = family;
500 return *this;
503 bool KSocketAddress::operator ==(const KSocketAddress& other) const
505 // if this is invalid, it's only equal if the other one is invalid as well
506 if (d->invalid())
507 return other.d->invalid();
509 // check the family to make sure we don't do unnecessary comparison
510 if (d->addr.generic->sa_family != other.d->addr.generic->sa_family)
511 return false; // not the same family, not equal
513 // same family then
514 // check the ones we know already
515 switch (d->addr.generic->sa_family)
517 case AF_INET:
518 Q_ASSERT(d->reallen == SOCKADDR_IN_LEN);
519 Q_ASSERT(other.d->reallen == SOCKADDR_IN_LEN);
520 return memcmp(d->addr.in, other.d->addr.in, SOCKADDR_IN_LEN) == 0;
522 #ifdef AF_INET6
523 case AF_INET6:
524 Q_ASSERT(d->reallen >= MIN_SOCKADDR_IN6_LEN);
525 Q_ASSERT(other.d->reallen >= MIN_SOCKADDR_IN6_LEN);
527 # if !defined(HAVE_STRUCT_SOCKADDR_IN6) || defined(HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID)
528 // check for the case where sin6_scope_id isn't present
529 if (d->reallen != other.d->reallen)
531 if (memcmp(d->addr.in6, other.d->addr.in6, MIN_SOCKADDR_IN6_LEN) != 0)
532 return false; // not equal
533 if (d->reallen > other.d->reallen)
534 return d->addr.in6->sin6_scope_id == 0;
535 else
536 return other.d->addr.in6->sin6_scope_id == 0;
538 # endif
540 return memcmp(d->addr.in6, other.d->addr.in6, d->reallen) == 0;
541 #endif
543 case AF_UNIX:
544 Q_ASSERT(d->reallen >= MIN_SOCKADDR_UN_LEN);
545 Q_ASSERT(other.d->reallen >= MIN_SOCKADDR_UN_LEN);
547 // do a string comparison here
548 return strcmp(d->addr.un->sun_path, other.d->addr.un->sun_path) == 0;
550 default:
551 // something else we don't know about
552 // they are equal if and only if they are exactly equal
553 if (d->reallen == other.d->reallen)
554 return memcmp(d->addr.generic, other.d->addr.generic, d->reallen) == 0;
557 return false; // not equal in any other case
560 QString KSocketAddress::nodeName() const
562 if (d->invalid())
563 return QString();
565 switch (d->addr.generic->sa_family)
567 case AF_INET:
568 #ifdef AF_INET6
569 case AF_INET6:
571 QString scopeid("%");
572 if (d->addr.generic->sa_family == AF_INET6 && d->addr.in6->sin6_scope_id)
573 scopeid += QString::number(d->addr.in6->sin6_scope_id);
574 else
575 scopeid.truncate(0);
576 return d->ref.ipAddress().toString() + scopeid;
577 #else
578 return d->ref.ipAddress().toString();
579 #endif
582 // any other case, including AF_UNIX
583 return QString();
586 QString KSocketAddress::serviceName() const
588 if (d->invalid())
589 return QString();
591 switch (d->addr.generic->sa_family)
593 case AF_INET:
594 #ifdef AF_INET6
595 case AF_INET6:
596 #endif
597 return QString::number(d->ref.port());
599 case AF_UNIX:
600 return d->ref.pathname();
603 return QString();
606 QString KSocketAddress::toString() const
608 if (d->invalid())
609 return QString();
611 QString fmt;
613 if (d->addr.generic->sa_family == AF_INET)
614 fmt = QLatin1String("%1:%2");
615 #ifdef AF_INET6
616 else if (d->addr.generic->sa_family == AF_INET6)
617 fmt = QLatin1String("[%1]:%2");
618 #endif
619 else if (d->addr.generic->sa_family == AF_UNIX)
620 return QString(QLatin1String("unix:%1")).arg(serviceName());
621 else
622 return i18nc("1: the unknown socket address family number",
623 "Unknown family %1", d->addr.generic->sa_family);
625 return fmt.arg(nodeName()).arg(serviceName());
628 KInetSocketAddress& KSocketAddress::asInet()
630 return d->ref;
633 KInetSocketAddress KSocketAddress::asInet() const
635 return d->ref;
638 KUnixSocketAddress& KSocketAddress::asUnix()
640 return d->ref;
643 KUnixSocketAddress KSocketAddress::asUnix() const
645 return d->ref;
648 int KSocketAddress::ianaFamily(int af)
650 switch (af)
652 case AF_INET:
653 return 1;
655 #ifdef AF_INET6
656 case AF_INET6:
657 return 2;
658 #endif
660 default:
661 return 0;
665 int KSocketAddress::fromIanaFamily(int iana)
667 switch (iana)
669 case 1:
670 return AF_INET;
672 #ifdef AF_INET6
673 case 2:
674 return AF_INET6;
675 #endif
677 default:
678 return AF_UNSPEC;
682 // default constructor
683 KInetSocketAddress::KInetSocketAddress()
687 // binary data constructor
688 KInetSocketAddress::KInetSocketAddress(const sockaddr* sa, quint16 len)
689 : KSocketAddress(sa, len)
691 if (!d->invalid())
692 update();
695 // create from IP and port
696 KInetSocketAddress::KInetSocketAddress(const KIpAddress& host, quint16 port)
698 setHost(host);
699 setPort(port);
702 // copy constructor
703 KInetSocketAddress::KInetSocketAddress(const KInetSocketAddress& other)
704 : KSocketAddress(other)
708 // special copy constructor
709 KInetSocketAddress::KInetSocketAddress(const KSocketAddress& other)
710 : KSocketAddress(other)
712 if (!d->invalid())
713 update();
716 // special constructor
717 KInetSocketAddress::KInetSocketAddress(KSocketAddressData *d)
718 : KSocketAddress(d)
722 // destructor
723 KInetSocketAddress::~KInetSocketAddress()
725 /* nothing to do */
728 // copy operator
729 KInetSocketAddress& KInetSocketAddress::operator =(const KInetSocketAddress& other)
731 KSocketAddress::operator =(other);
732 return *this;
735 // IP version
736 int KInetSocketAddress::ipVersion() const
738 if (d->invalid())
739 return 0;
741 switch (d->addr.generic->sa_family)
743 case AF_INET:
744 return 4;
746 #ifdef AF_INET6
747 case AF_INET6:
748 return 6;
749 #endif
752 return 0; // for all other cases
755 KIpAddress KInetSocketAddress::ipAddress() const
757 if (d->invalid())
758 return KIpAddress(); // return an empty address as well
760 switch (d->addr.generic->sa_family)
762 case AF_INET:
763 return KIpAddress(&d->addr.in->sin_addr, 4);
764 #ifdef AF_INET6
765 case AF_INET6:
766 return KIpAddress(&d->addr.in6->sin6_addr, 6);
767 #endif
770 return KIpAddress(); // empty in all other cases
773 KInetSocketAddress& KInetSocketAddress::setHost(const KIpAddress& ip)
775 switch (ip.version())
777 case 4:
778 makeIPv4();
779 memcpy(&d->addr.in->sin_addr, ip.addr(), sizeof(d->addr.in->sin_addr));
780 break;
782 case 6:
783 makeIPv6();
784 memcpy(&d->addr.in6->sin6_addr, ip.addr(), sizeof(d->addr.in6->sin6_addr));
785 break;
787 default:
788 // empty
789 d->invalidate();
792 return *this;
795 // returns the port
796 quint16 KInetSocketAddress::port() const
798 if (d->invalid())
799 return 0;
801 switch (d->addr.generic->sa_family)
803 case AF_INET:
804 return ntohs(d->addr.in->sin_port);
806 #ifdef AF_INET6
807 case AF_INET6:
808 return ntohs(d->addr.in6->sin6_port);
809 #endif
812 return 0;
815 KInetSocketAddress& KInetSocketAddress::setPort(quint16 port)
817 if (d->invalid())
818 makeIPv4();
820 switch (d->addr.generic->sa_family)
822 case AF_INET:
823 d->addr.in->sin_port = htons(port);
824 break;
826 #ifdef AF_INET6
827 case AF_INET6:
828 d->addr.in6->sin6_port = htons(port);
829 break;
830 #endif
832 default:
833 d->invalidate(); // setting the port on something else
836 return *this;
839 KInetSocketAddress& KInetSocketAddress::makeIPv4()
841 d->makeipv4();
842 return *this;
845 KInetSocketAddress& KInetSocketAddress::makeIPv6()
847 d->makeipv6();
848 return *this;
851 quint32 KInetSocketAddress::flowinfo() const
853 #ifndef AF_INET6
854 return 0;
855 #else
857 if (!d->invalid() && d->addr.in6->sin6_family == AF_INET6)
858 return d->addr.in6->sin6_flowinfo;
859 return 0;
860 #endif
863 KInetSocketAddress& KInetSocketAddress::setFlowinfo(quint32 flowinfo)
865 makeIPv6(); // must set here
866 d->addr.in6->sin6_flowinfo = flowinfo;
867 return *this;
870 int KInetSocketAddress::scopeId() const
872 #ifndef AF_INET6
873 return 0;
874 #else
876 if (!d->invalid() && d->addr.in6->sin6_family == AF_INET6)
877 return d->addr.in6->sin6_scope_id;
878 return 0;
879 #endif
882 KInetSocketAddress& KInetSocketAddress::setScopeId(int scopeid)
884 makeIPv6(); // must set here
885 d->addr.in6->sin6_scope_id = scopeid;
886 return *this;
889 void KInetSocketAddress::update()
891 if (d->addr.generic->sa_family == AF_INET)
892 return;
893 #ifdef AF_INET6
894 else if (d->addr.generic->sa_family == AF_INET6)
895 return;
896 #endif
897 else
898 d->invalidate();
901 KUnixSocketAddress::KUnixSocketAddress()
905 KUnixSocketAddress::KUnixSocketAddress(const sockaddr* sa, quint16 len)
906 : KSocketAddress(sa, len)
908 if (!d->invalid() && d->addr.un->sun_family != AF_UNIX)
909 d->invalidate();
912 KUnixSocketAddress::KUnixSocketAddress(const KUnixSocketAddress& other)
913 : KSocketAddress(other)
917 KUnixSocketAddress::KUnixSocketAddress(const QString& pathname)
919 setPathname(pathname);
922 KUnixSocketAddress::KUnixSocketAddress(KSocketAddressData* d)
923 : KSocketAddress(d)
927 KUnixSocketAddress::~KUnixSocketAddress()
931 KUnixSocketAddress& KUnixSocketAddress::operator =(const KUnixSocketAddress& other)
933 KSocketAddress::operator =(other);
934 return *this;
937 QString KUnixSocketAddress::pathname() const
939 if (!d->invalid() && d->addr.un->sun_family == AF_UNIX)
940 return QFile::decodeName(d->addr.un->sun_path);
941 return QString();
944 KUnixSocketAddress& KUnixSocketAddress::setPathname(const QString& path)
946 d->dup(0L, MIN_SOCKADDR_UN_LEN + path.length());
947 d->addr.un->sun_family = AF_UNIX;
948 strcpy(d->addr.un->sun_path, QFile::encodeName(path));
950 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
951 d->addr.un->sun_len = d->reallen;
952 #endif
954 return *this;