This is the mail archive of the libc-alpha@sources.redhat.com mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Linux getdents.c is not aliasing safe


On Wed, Oct 30, 2002 at 10:52:30AM +0100, Wolfram Gloger wrote:
> > > [That is: two pointers to a buffer, of different types; walk through
> > > the buffer, reading one object of the first type and writing out an
> > > object of the second lesser-or-equal sized type.]
> > 
> > No, there's no standard C way to do that.  An object can only have one
> > type at a time.  You have to use another buffer as an intermediate.
> 
> AFAICS, the code already has intermediate buffers:
> 
>           dp = (DIRENT_TYPE *)buf;
>           kdp = (struct kernel_dirent64 *) kbuf;
> 
>               uint64_t d_ino = kdp->d_ino;
>               int64_t d_off = kdp->d_off;
>               unsigned char d_type = kdp->d_type;
> 
>               DIRENT_SET_DP_INO (dp, d_ino);
>               dp->d_off = d_off;
> 
> So, why not just use a char* ptr to write out the data using memcpy(),
> do away with dp and e.g. change the last line into:
> 
> 	memcpy(buf + offsetof(DIRENT_TYPE, d_off), &d_off, sizeof d_off);
> 
> (the DIRENT_SET_DP_INO line of course needs to be handled a little
> differently).  Since char* can alias anything, that would remain
> portable C.

But that intermediate buffer is in registers (on sane arches), while using
memcpy would mean at least with current compilers memory.
glibc requires gcc (even 3.2+) to compile anyway, so IMHO just using the
union as drow posted seems best to me.

	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]