comparison libpurple/util.c @ 29745:37be7bc87ab2

util: Fix some strict-aliasing issues. gcc on my desktop complained about these, though luckily I'm not the only one who's encountered this issue. Thanks, stackoverflow! http://stackoverflow.com/questions/1429645/how-to-cast-sockaddr-storage-and-avoid-breaking-strict-aliasing-rules
author Paul Aurich <paul@darkrain42.org>
date Sat, 17 Apr 2010 21:13:50 +0000
parents 933c8251e036
children 5bac51b394e6
comparison
equal deleted inserted replaced
29744:4aa17d7c4e0a 29745:37be7bc87ab2
2967 #else 2967 #else
2968 return FALSE; 2968 return FALSE;
2969 #endif 2969 #endif
2970 } 2970 }
2971 2971
2972 typedef union purple_sockaddr {
2973 struct sockaddr sa;
2974 struct sockaddr_in sa_in;
2975 #if defined(AF_INET6)
2976 struct sockaddr_in6 sa_in6;
2977 #endif
2978 struct sockaddr_storage sa_stor;
2979 } PurpleSockaddr;
2980
2972 char * 2981 char *
2973 purple_fd_get_ip(int fd) 2982 purple_fd_get_ip(int fd)
2974 { 2983 {
2975 struct sockaddr_storage addr; 2984 PurpleSockaddr addr;
2976 socklen_t namelen = sizeof(addr); 2985 socklen_t namelen = sizeof(addr);
2977 int family; 2986 int family;
2978 2987
2979 g_return_val_if_fail(fd != 0, NULL); 2988 g_return_val_if_fail(fd != 0, NULL);
2980 2989
2981 if (getsockname(fd, (struct sockaddr *)&addr, &namelen)) 2990 if (getsockname(fd, &(addr.sa), &namelen))
2982 return NULL; 2991 return NULL;
2983 2992
2984 family = ((struct sockaddr *)&addr)->sa_family; 2993 family = addr.sa.sa_family;
2985 2994
2986 if (family == AF_INET) { 2995 if (family == AF_INET) {
2987 struct sockaddr_in *ipv4 = (struct sockaddr_in *)&addr; 2996 return g_strdup(inet_ntoa(addr.sa_in.sin_addr));
2988 struct in_addr addr = ipv4->sin_addr;
2989 return g_strdup(inet_ntoa(addr));
2990 } 2997 }
2991 #if defined(AF_INET6) && defined(HAVE_INET_NTOP) 2998 #if defined(AF_INET6) && defined(HAVE_INET_NTOP)
2992 else if (family == AF_INET6) { 2999 else if (family == AF_INET6) {
2993 struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)&addr;
2994 struct in6_addr addr = ipv6->sin6_addr;
2995 char host[INET6_ADDRSTRLEN]; 3000 char host[INET6_ADDRSTRLEN];
2996 const char *tmp; 3001 const char *tmp;
2997 3002
2998 tmp = inet_ntop(family, &addr, host, sizeof(host)); 3003 tmp = inet_ntop(family, &(addr.sa_in6.sin6_addr), host, sizeof(host));
2999 return g_strdup(tmp); 3004 return g_strdup(tmp);
3000 } 3005 }
3001 #endif 3006 #endif
3002 3007
3003 return NULL; 3008 return NULL;
3004 } 3009 }
3005 3010
3006 int 3011 int
3007 purple_socket_get_family(int fd) 3012 purple_socket_get_family(int fd)
3008 { 3013 {
3009 struct sockaddr_storage addr; 3014 PurpleSockaddr addr;
3010 socklen_t len = sizeof(addr); 3015 socklen_t len = sizeof(addr);
3011 3016
3012 g_return_val_if_fail(fd >= 0, -1); 3017 g_return_val_if_fail(fd >= 0, -1);
3013 3018
3014 if (getsockname(fd, (struct sockaddr *)&addr, &len)) 3019 if (getsockname(fd, &(addr.sa), &len))
3015 return -1; 3020 return -1;
3016 3021
3017 return ((struct sockaddr *)&addr)->sa_family; 3022 return addr.sa.sa_family;
3018 } 3023 }
3019 3024
3020 gboolean 3025 gboolean
3021 purple_socket_speaks_ipv4(int fd) 3026 purple_socket_speaks_ipv4(int fd)
3022 { 3027 {
3023 int family; 3028 int family;
3024 3029
3025 g_return_val_if_fail(fd >= 0, FALSE); 3030 g_return_val_if_fail(fd >= 0, FALSE);
3026 3031
3027 family = purple_socket_get_family(fd); 3032 family = purple_socket_get_family(fd);
3028 3033
3029 switch (family) { 3034 switch (family) {