[CFR] correct type of addrinfo.ai_addrlen and netent.n_net
Hajimu UMEMOTO
ume at FreeBSD.ORG
Mon May 9 08:55:20 PDT 2005
Hi,
>>>>> On Tue, 3 May 2005 18:44:09 -0400
>>>>> David Schultz <das at FreeBSD.ORG> said:
das> - You should use socklen_t instead of uint32_t, as appropriate.
Are you mean netent.n_net? If so, it is because of POSIX.
das> - It's probably better to use the machine/endian.h macros to test
das> endianness instead of hard-coding every architecture.
Yes. How about this patch?
--- include/netdb.h.orig Thu Apr 28 04:12:56 2005
+++ include/netdb.h Mon May 9 15:45:55 2005
@@ -63,6 +63,8 @@
#include <sys/cdefs.h>
#include <sys/_types.h>
+#include <machine/_limits.h>
+#include <machine/endian.h>
#ifndef _SIZE_T_DECLARED
typedef __size_t size_t;
@@ -74,6 +76,11 @@
#define _SOCKLEN_T_DECLARED
#endif
+#ifndef _UINT32_T_DECLARED
+typedef __uint32_t uint32_t;
+#define _UINT32_T_DECLARED
+#endif
+
#ifndef _PATH_HEQUIV
# define _PATH_HEQUIV "/etc/hosts.equiv"
#endif
@@ -99,14 +106,27 @@
};
/*
- * Assumption here is that a network number
- * fits in an unsigned long -- probably a poor one.
+ * Note: n_net used to be an unsigned long integer.
+ * In XNS5, and subsequently in POSIX-2001 it was changed to an
+ * uint32_t.
+ * To accomodate for this while preserving binary compatibility with
+ * the old interface, we prepend or append 32 bits of padding,
+ * depending on the (LP64) architecture's endianness.
+ *
+ * This should be deleted the next time the libc major number is
+ * incremented.
*/
struct netent {
char *n_name; /* official name of net */
char **n_aliases; /* alias list */
int n_addrtype; /* net address type */
- unsigned long n_net; /* network # */
+#if __LONG_BIT == 64 && _BYTE_ORDER == _BIG_ENDIAN
+ uint32_t __n_pad0; /* ABI compatibility */
+#endif
+ uint32_t n_net; /* network # */
+#if __LONG_BIT == 64 && _BYTE_ORDER == _LITTLE_ENDIAN
+ uint32_t __n_pad0; /* ABI compatibility */
+#endif
};
struct servent {
@@ -122,12 +142,29 @@
int p_proto; /* protocol # */
};
+/*
+ * Note: ai_addrlen used to be a size_t, per RFC 2553.
+ * In XNS5.2, and subsequently in POSIX-2001 and RFC 3493 it was
+ * changed to a socklen_t.
+ * To accomodate for this while preserving binary compatibility with the
+ * old interface, we prepend or append 32 bits of padding, depending on
+ * the (LP64) architecture's endianness.
+ *
+ * This should be deleted the next time the libc major number is
+ * incremented.
+ */
struct addrinfo {
int ai_flags; /* AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST */
int ai_family; /* PF_xxx */
int ai_socktype; /* SOCK_xxx */
int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
- size_t ai_addrlen; /* length of ai_addr */
+#if __LONG_BIT == 64 && _BYTE_ORDER == _BIG_ENDIAN
+ uint32_t __ai_pad0; /* ABI compatibility */
+#endif
+ socklen_t ai_addrlen; /* length of ai_addr */
+#if __LONG_BIT == 64 && _BYTE_ORDER == _LITTLE_ENDIAN
+ uint32_t __ai_pad0; /* ABI compatibility */
+#endif
char *ai_canonname; /* canonical name for hostname */
struct sockaddr *ai_addr; /* binary address */
struct addrinfo *ai_next; /* next structure in linked list */
@@ -225,7 +262,7 @@
struct hostent *gethostent(void);
struct hostent *getipnodebyaddr(const void *, size_t, int, int *);
struct hostent *getipnodebyname(const char *, int, int, int *);
-struct netent *getnetbyaddr(unsigned long, int);
+struct netent *getnetbyaddr(uint32_t, int);
struct netent *getnetbyname(const char *);
struct netent *getnetent(void);
int getnetgrent(char **, char **, char **);
das> -#if 1 /* obsolete */
das> +#if __BSD_VISIBLE /* obsolete */
das> #define NI_WITHSCOPEID 0x00000020
das> #endif
It reminds me one more issue. I wish to nuke NI_WITHSCOPEID before
6.0-RELEASE. NetBSD and OpenBSD did so already.
das> +int getaddrinfo(const char * __restrict, const char * __restrict,
das> + const struct addrinfo * __restrict,
das> + struct addrinfo ** __restrict);
das> +int getnameinfo(const struct sockaddr * __restrict, socklen_t,
das> + char * __restrict, __size_t, char * __restrict,
das> + __size_t, int);
The 4th and 6th arguments are buffer length for return value, and they
are size_t in spec. So, they should not be mixuped with others.
das> -struct hostent *getipnodebyaddr(const void *, size_t, int, int *);
das> +struct hostent *getipnodebyaddr(const void *, __size_t, int, int *);
It is thorny issue. I think it is a bug, and it should be int.
However, getipnodebyaddr() was defined in RFC 2553, then was
deprecated in RFC 3493. So, I think it will never be revised.
Sincerely,
--
Hajimu UMEMOTO @ Internet Mutual Aid Society Yokohama, Japan
ume at mahoroba.org ume@{,jp.}FreeBSD.org
http://www.imasy.org/~ume/
More information about the freebsd-arch
mailing list