Ted Unangst wrote [2011-11-14 22:35+0100]:
> On Mon, Nov 14, 2011, Steffen Daode Nurpmeso wrote:
> > Is there a reason not to use CTASSERT (and some kind of
> > member_sizeof())? I couldn't find just any discussion on that in
> > marc and gmane.
>
> Seems like a good idea, but your patch is wrong.
> Off by one because strlen != sizeof.
The patch adds a fantastic member_sizeof() which is unique in the
world! Even though needed so often, neither was it invented by
IBM (TM,REG), nor has Coca-Cola (TM,REG) a trademark on it!
It was me, many years ago! (AFAIK)
Hah!! (AFAIK)
Feel free to use it!!!
--steffen
Index: sys/sys/cdefs.h
===================================================================
RCS file: /cvs/src/sys/sys/cdefs.h,v
retrieving revision 1.31
diff -a -p -u -r1.31 cdefs.h
--- sys/sys/cdefs.h 1 Oct 2010 04:51:49 -0000 1.31
+++ sys/sys/cdefs.h 15 Nov 2011 19:50:34 -0000
@@ -86,6 +86,18 @@
#define __CONCAT(x,y) x/**/y
#define __STRING(x) "x"
+/*
+ * Compile time assertion
+ */
+#define __CTASSERT(X) __CTASSERT1((X), __LINE__)
+#define __CTASSERT1(X,L) __CTASSERT2((X), L)
+#define __CTASSERT2(X,L) typedef char __CTASSERT_bail_ ## L[(X) ? 1 : -1]
+
+/*
+ * __member_sizeof(T,M) - uses 0x8 to avoid cc warnings and aggr. optimization
+ */
+#define __member_sizeof(T,M) sizeof(((T *)0x8)->M)
+
#if !defined(__GNUC__) && !defined(lint)
#define __const /* delete pseudo-ANSI C
keywords */
#define __inline
Index: sbin/dhclient/dhclient.c
===================================================================
RCS file: /cvs/src/sbin/dhclient/dhclient.c,v
retrieving revision 1.141
diff -a -p -u -r1.141 dhclient.c
--- sbin/dhclient/dhclient.c 11 May 2011 14:38:36 -0000 1.141
+++ sbin/dhclient/dhclient.c 15 Nov 2011 19:50:34 -0000
@@ -2077,6 +2077,9 @@ get_ifname(char *ifname, char *arg)
struct ifg_req *ifg;
int s, len;
+ __CTASSERT(__member_sizeof(struct interface_info, name) >=
+ __member_sizeof(struct ifg_req, ifgrq_member));
+
if (!strcmp(arg, "egress")) {
s = socket(AF_INET, SOCK_DGRAM, 0);
if (s == -1)
@@ -2103,8 +2106,8 @@ get_ifname(char *ifname, char *arg)
arg = ifg->ifgrq_member;
}
- if (strlcpy(ifi->name, arg, IFNAMSIZ) >= IFNAMSIZ)
- error("Interface name too long: %m");
+ (void)strlcpy(ifi->name, arg,
+ __member_sizeof(struct ifg_req, ifgrq_member));
free(ifgr.ifgr_groups);
close(s);