At Fri, 18 May 2012 07:55:35 +0100, David Laight <david%l8s.co.uk@localhost> wrote: Subject: Re: Problems with packages on a netbsd-6 sparc > > On Thu, May 17, 2012 at 08:48:00PM -0700, Greg A. Woods wrote: > > > * Copy in passwd contents and make strings relative to space > > > * at the end of the buffer. > > > */ > > > + memcpy(cp, pw, sizeof(struct passwd)); > > > newpw = (struct passwd *) cp; > > > - memcpy(newpw, pw, sizeof(struct passwd)); > > > cp += sizeof(struct passwd); > > > FIELD_COPY(pw, newpw, pw_name, nsize); > > > FIELD_COPY(pw, newpw, pw_passwd, psize); > > > > Why not avoid the non-intuitive memcpy() all together all the time and > > just let the compiler do its job???? > > > > *newpw = *pw; > > > > C has allowed structure copies like this since at least C89, and much > > earlier in many good compilers (the data pointed to by the fields which > > are pointers still needs to be copied of course). > > You need to read the entire thread! > C only allows you to take pointers to objects, cast them to certain other > types (including char * and void *), cast them back to the SAME type > and then dereference them. I think that's kind of irrelevant given that I suggested getting rid of the memcpy() entirely, but.... C allows pointers of, say, "void *" to be cast to _ANY_ type, alignment restrictions aside. Also, any function is allowed to return a "void *" pointer which, given such a claim in that function's definition, the programmer can then assume it will be aligned correctly for any use. The standard malloc() function is such a function. (So far as I can recall there is no requirement in C, and certainly not old C or C89, that a "void *" pointer must be cast back to the type it had before it was cast into a "void *" pointer. Pointer aliasing like that is not necessarily going to work in a _portable_ way if alignment restrictions have not been dealt with somehow, but it's still allowed.) If I'm not mistaken the "cp" pointer above, at the line where it is assigned to "newpw" prior to the patch, is unchanged from the value it had when it was most recently assigned from the return value of a malloc() call. In that case it MUST be properly aligned for any type. Turning it into a "struct passwd *" is perfectly valid -- the fact that the storage being pointed at is larger than a "struct passwd" is irrelevant (it's just an example of premature optimisation). -- Greg A. Woods Planix, Inc. <woods%planix.com@localhost> +1 250 762-7675 http://www.planix.com/
Attachment:
pgpW7EAoN3guy.pgp
Description: PGP signature