[Linux-ha-dev] Bind/stat Auth Patch

Guochun Shi gshi at ncsa.uiuc.edu
Wed Oct 6 17:13:16 MDT 2004


I remember there is macro in kernel which does this similar 0 thing too. Let me grep it ...

/**
 * list_entry - get the struct for this entry
 * @ptr:        the &struct list_head pointer.
 * @type:       the type of the struct this is embedded in.
 * @member:     the name of the list_struct within the struct.
 */
#define list_entry(ptr, type, member) \
        ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))



-Guochun

At 06:40 PM 10/6/2004 -0400, you wrote:
>On Wed, 2004-10-06 at 18:02, Alan Robertson wrote:
>> Lars Marowsky-Bree wrote:
>> > On 2004-10-06T23:03:46, Andrew Beekhof <lists at beekhof.net> wrote:
>> > 
>> > 
>> >>This SUN_LEN macro looks evil to me, mostly because I dont understand 
>> >>it, particularly the dereferencing 0 bit.
>> >>
>> >>Can anyone (in particular Alan or lmb) verify it is safe?
>> >>
>> >>Alternatively, Matthew also found this variant:
>> >>
>> >> #define SUN_LEN(su) (sizeof(*(su)) - sizeof((su)->sun_path) + 
>> >>strlen((su)->sun_path))
>> 
>> This macro assumes two things:
>>       1) that sun_path is last thing in the structure
>>       2) That sun_path does not require any more stringent
>>               alignment than the thing just in front of it
>> 
>> > Dereferencing NULL doesn't sound safe, but it's an awkward place to
>> > check for NULL - what should the macro do, return 0? Better check the
>> > pointer beforehand...
>> 
>> It isn't dereferencing it BECAUSE sun_path is an array.
>> The meaning of -> when the thing after the operator is an array is more 
>> like &(((struct foo*)0)->sun_path), which keeps it from actually doing the 
>> indirection on 0.
>> 
>> So, what this construct is doing is computing the offset of sun_path in the 
>> structure.
>> 
>> I think the following code for computing structure member offset is much 
>> clearer, and works on every platform, regardless of the data type of 
>> sun_path, or it's position in the array.
>> 
>> 
>>       static ssize_t sunpathoffset = -1;
>>       if (sunpathoffset < 0) {
>>               struct foo x;
>>               sunpathoffset = ((char*)(&(x.sun_path))) - ((char*) &x);
>>       }
>> 
>> This is how to properly compute the offset of a structure element.  It is 
>> perfectly clear, making neither programmers nor program verifiers sick to 
>> their stomachs.
>> 
>> What they've done in the macro is eliminated the variable, and replaced it 
>> with a pointer to zero, which works fine, because they're just computing 
>> relative addresses, and not actually indirecting (though it looks like they 
>> are because of the data type of sun_path).  But, all the discussion here 
>> points out it's big flaw:  it's unclear.
>
>We talked about this on IRC, but just thougth I'd share with the rest of
>the class.  Since this is just finding an offset, and offsetof is a ANSI
>C macro, we can redefine:
>
>        #define SUN_LEN(ptr) ((size_t) (((struct sockaddr_un *)
>                0)->sun_path) + strlen ((ptr)->sun_path))
>
>as
>
>        #define SUN_LEN(ptr) ((size_t) (offsetof (sockaddr_un, sun_path)
>                + strlen ((ptr)->sun_path))
>
>which hides the implementation details, but should be similarly
>portable.
>
>-- 
>Matthew Berg <galt at gothpoodle.com>
>
>_______________________________________________________
>Linux-HA-Dev: Linux-HA-Dev at lists.linux-ha.org
>http://lists.linux-ha.org/mailman/listinfo/linux-ha-dev
>Home Page: http://linux-ha.org/



More information about the Linux-HA-Dev mailing list