[patch] fix aliasing warnings

Jindřich Makovička <[email protected]> Sat, 14 Aug 2010 20:17:48 +0200
Newsgroups gmane.comp.gnome.apps.gkrellm
Message-ID <[email protected]>
Hi,

the attached patch fixes a few aliasing violations due to sockaddr_*
typecasting. It changes the typecasts to allowed type-punning via
union.

Regards,
-- 
Jindrich Makovicka
07_aliasing.patch (text/x-patch, 4.7 KB)
--- gkrellm/src/inet.c.orig	2009-12-21 02:11:04.000000000 +0100
+++ gkrellm/src/inet.c	2010-08-14 13:26:33.144979685 +0200
@@ -650,9 +650,12 @@
 	GList					*list;
 	ActiveTCP				*tcp;
 #if defined(INET6)
-	struct sockaddr_storage	ss;
-	struct sockaddr_in		*sin;
-	struct sockaddr_in6		*sin6;
+	union {
+	    struct sockaddr_storage	ss;
+	    struct sockaddr_in		sin;
+	    struct sockaddr_in6	sin6;
+	    struct sockaddr		sa;
+	} ss;
 	gint					salen, flag = 0;
 	gchar					hbuf[NI_MAXHOST];
 	gchar					buf[NI_MAXHOST + 10];
@@ -670,34 +673,32 @@
 		{
 		tcp = (ActiveTCP *) list->data;
 #if defined(INET6)
-		memset(&ss, 0, sizeof(ss));
+		memset(&ss.ss, 0, sizeof(ss.ss));
 		switch (tcp->family)
 			{
 			case AF_INET:
-				sin = (struct sockaddr_in *)&ss;
 				salen = sizeof(struct sockaddr_in);
-				memcpy(&sin->sin_addr, &tcp->remote_addr, salen);
+				memcpy(&ss.sin.sin_addr, &tcp->remote_addr, salen);
 #if defined(SIN6_LEN)
-				sin->sin_len = salen;
+				ss.sin.sin_len = salen;
 #endif
-				sin->sin_family = tcp->family;
+				ss.sin.sin_family = tcp->family;
 				break;
 			case AF_INET6:
-				sin6 = (struct sockaddr_in6 *)&ss;
 				salen = sizeof(struct sockaddr_in6);
-				memcpy(&sin6->sin6_addr, &tcp->remote_addr6, salen);
+				memcpy(&ss.sin6.sin6_addr, &tcp->remote_addr6, salen);
 #if defined(SIN6_LEN)
-				sin6->sin6_len = salen;
+				ss.sin6.sin6_len = salen;
 #endif
-				sin6->sin6_family = tcp->family;
+				ss.sin6.sin6_family = tcp->family;
 				/* XXX: We should mention about
 				|  scope, too. */
 				break;
 			default:
 				continue;
 			}
-		if (getnameinfo((struct sockaddr *)&ss, salen,
-					hbuf, sizeof(hbuf), NULL, 0, flag))
+		if (getnameinfo(&ss.sa, salen,
+				hbuf, sizeof(hbuf), NULL, 0, flag))
 			continue;
 		remote_host = hbuf;
 #else
--- gkrellm/server/main.c.orig	2009-12-21 02:16:45.000000000 +0100
+++ gkrellm/server/main.c	2010-08-14 13:40:41.623544684 +0200
@@ -340,7 +340,12 @@
 {
 #ifdef HAVE_GETADDRINFO
 	struct addrinfo hints, *res;
-	struct sockaddr_storage	ss;
+	union {
+	    struct sockaddr_storage	ss;
+	    struct sockaddr_in		sin;
+	    struct sockaddr_in6	sin6;
+	    struct sockaddr		sa;
+	} ss;
 	char		*buf;
 	char		*p, *ep;
 	guchar		*addr, *pat;
@@ -376,7 +381,7 @@
 	memcpy(&ss, res->ai_addr, res->ai_addrlen);
 	freeaddrinfo(res);
 
-	if (sa->sa_family != ((struct sockaddr *)&ss)->sa_family)
+	if (sa->sa_family != ss.sa.sa_family)
 		return FALSE;
 	switch (sa->sa_family)
 		{
@@ -386,12 +391,12 @@
 				plen = 128;
 			if (plen > 128)
 				return FALSE;
-			if (((struct sockaddr_in6 *)&ss)->sin6_scope_id != 0 &&
-			    ((struct sockaddr_in6 *)&ss)->sin6_scope_id !=
+			if (ss.sin6.sin6_scope_id != 0 &&
+			    ss.sin6.sin6_scope_id !=
 			    ((struct sockaddr_in6 *)sa)->sin6_scope_id)
 				return FALSE;
 			addr = (guchar *)&((struct sockaddr_in6 *)sa)->sin6_addr;
-			pat = (guchar *)&((struct sockaddr_in6 *)&ss)->sin6_addr;
+			pat = (guchar *)&ss.sin6.sin6_addr;
 			i = 0;
 			while (plen > 0)
 				{
@@ -417,7 +422,7 @@
 			if (plen > 32)
 				return FALSE;
 			addr = (guchar *)&((struct sockaddr_in *)sa)->sin_addr;
-			pat = (guchar *)&((struct sockaddr_in *)&ss)->sin_addr;
+			pat = (guchar *)&ss.sin.sin_addr;
 			mask = htonl(~(0xffffffff >> plen));
 			if ((*(uint32_t *)addr & mask) !=
 			    (*(uint32_t *)pat & mask))
@@ -1108,11 +1113,15 @@
 static gint
 gkrellmd_run(gint argc, gchar **argv)
 	{
+    union {
 #ifdef HAVE_GETADDRINFO
-	struct sockaddr_storage client_addr;
+	struct sockaddr_storage ss;
 #else
-	struct sockaddr_in	client_addr;
+	struct sockaddr_in	ss;
 #endif
+	struct sockaddr_in	sin;
+	struct sockaddr	sa;
+    } client_addr;
 	fd_set				read_fds, test_fds;
 	struct timeval		tv;
 	GkrellmdClient		*client;
@@ -1226,11 +1235,7 @@
 #endif
 		{
 		test_fds = read_fds;
-#ifdef HAVE_GETADDRINFO
-		addr_len = sizeof(struct sockaddr_storage);
-#else
-		addr_len = sizeof(struct sockaddr_in);
-#endif
+		addr_len = sizeof(client_addr.ss);
 		tv.tv_usec = interval;
 		tv.tv_sec = 0;
 
@@ -1269,7 +1274,7 @@
 				{
 				gkrellm_debug(DEBUG_SERVER, "Calling accept() for new client connection\n");
 				client_fd = accept(server_fd,
-						(struct sockaddr *) &client_addr,
+						&client_addr.sa,
 						(socklen_t *) (void *)&addr_len);
 				if (client_fd == -1)
 					{
@@ -1281,7 +1286,7 @@
 				if (client_fd > max_fd)
 					max_fd = client_fd;
 				client = accept_client(client_fd,
-							(struct sockaddr *)&client_addr, addr_len);
+							&client_addr.sa, addr_len);
 				if (!client)
 					{
 					close(client_fd);
@@ -1292,7 +1297,7 @@
 
 				g_message(_("Accepted client %s:%u\n"),
 					client->hostname,
-					ntohs(((struct sockaddr_in *)&client_addr)->sin_port));
+					ntohs(client_addr.sin.sin_port));
 				}
 			else
 				{