Mercurial > pidgin
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) { |