From eb74369b24584e12fdd251cbbf2af17f4c543550 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Thu, 28 Jan 2016 21:22:07 +0000 Subject: [PATCH] Fix strict-aliasing warnings in sk_tcp_peer_info. GCC 6 emits strict-aliasing warnings here, so use the existing sockaddr_union arrangements to avoid those. As a prerequisite for being able to express sk_tcp_peer_info in terms of sockaddr_union, I fixed up the union elements to be a bit less odd in the NO_IPV6 case. (cherry picked from commit c026b48c537250ac03573845ff9da6fd9f45776d) --- unix/uxnet.c | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/unix/uxnet.c b/unix/uxnet.c index 5058d8ab..b15031f4 100644 --- a/unix/uxnet.c +++ b/unix/uxnet.c @@ -37,14 +37,12 @@ * Access to sockaddr types without breaking C strict aliasing rules. */ union sockaddr_union { -#ifdef NO_IPV6 - struct sockaddr_in storage; -#else struct sockaddr_storage storage; - struct sockaddr_in6 sin6; -#endif struct sockaddr sa; struct sockaddr_in sin; +#ifndef NO_IPV6 + struct sockaddr_in6 sin6; +#endif struct sockaddr_un su; }; @@ -1426,26 +1424,27 @@ static void sk_tcp_set_frozen(Socket sock, int is_frozen) static char *sk_tcp_peer_info(Socket sock) { Actual_Socket s = (Actual_Socket) sock; - struct sockaddr_storage addr; + union sockaddr_union addr; socklen_t addrlen = sizeof(addr); +#ifndef NO_IPV6 char buf[INET6_ADDRSTRLEN]; +#endif - if (getpeername(s->s, (struct sockaddr *)&addr, &addrlen) < 0) + if (getpeername(s->s, &addr.sa, &addrlen) < 0) return NULL; - if (addr.ss_family == AF_INET) { + if (addr.storage.ss_family == AF_INET) { return dupprintf ("%s:%d", - inet_ntoa(((struct sockaddr_in *)&addr)->sin_addr), - (int)ntohs(((struct sockaddr_in *)&addr)->sin_port)); + inet_ntoa(addr.sin.sin_addr), + (int)ntohs(addr.sin.sin_port)); #ifndef NO_IPV6 - } else if (addr.ss_family == AF_INET6) { + } else if (addr.storage.ss_family == AF_INET6) { return dupprintf ("[%s]:%d", - inet_ntop(AF_INET6, &((struct sockaddr_in6 *)&addr)->sin6_addr, - buf, sizeof(buf)), - (int)ntohs(((struct sockaddr_in6 *)&addr)->sin6_port)); + inet_ntop(AF_INET6, &addr.sin6.sin6_addr, buf, sizeof(buf)), + (int)ntohs(addr.sin6.sin6_port)); #endif - } else if (addr.ss_family == AF_UNIX) { + } else if (addr.storage.ss_family == AF_UNIX) { /* * For Unix sockets, the source address is unlikely to be * helpful. Instead, we try SO_PEERCRED and try to get the