News for hackers. Stuff that matters.
Re:Poll on macOS 10.12 is broken by kazinator on Tuesday October 11, 2016 @12:55PM (#12686155)
Look at what's actually in there:

  /* Apple's socket address. */

  struct sockaddr_in {
    __uint8_t      sin_len;
    sa_family_t    sin_family;
    in_port_t      sin_port;
    struct in_addr sin_addr;
    char           sin_zero[8];
  }
Why is sin_len that necessary? The socket functions have a length parameter, including bind:

  int bind(int sockfd, const struct sockaddr *addr,
           socklen_t addrlen);
If this redundant length is necessary, why is it okay to lie and set it to zero? The length of the address sure isn't zero.

If sin_zero must be zero, why doesn't the bind function make it so?

Don't add a member to the end of a struct just so that padding has a name, and then make me initialize it.

POSIX defines a type called struct sockaddr_storage which is at least as large as the largest sockaddr_* type. There is no need to pad the various sockaddr-s up to that size; the sockaddr_storage can be used to declare storage large enough to receive any address.

Re:Poll on macOS 10.12 is broken by raimue on Tuesday October 11, 2016 @01:40PM (#12686595)
Depending on your architecture, access to data of different size needs different alignment. You may never have heard of it, as it mostly does not exist on x86 except for special instruction set extensions such as SSE. However, by using structs of different size, you could violate these alignment requirements on ARM, SPARC, MIPS, etc.

For example, struct sockaddr only contains 1-byte members. Therefore it does not have special requirements on alignment. struct sockaddr_in contains at least one member of 4 bytes (struct in_addr), therefore it also has a alignment requirement of 4 bytes to avoid splitting the 4 byte member between memory words.

In order to support casting pointers to any of these struct types, implementations pad all of these structs to make them all the same size and therefore having sane alignment requirements.

You will not read anything about these kind of problems in POSIX, since these are limititations implied by the hardware architecture.

Re:Poll on macOS 10.12 is broken by kazinator on Tuesday October 11, 2016 @06:02PM (#12688882)
Yes, you will read about these kinds of problems in POSIX, where it defines sockaddr_storage:

http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys...

Quote: "The sockaddr_storage structure solves the problem of declaring storage for automatic variables which is both large enough and aligned enough for storing the socket address data structure of any family."

You're never going to define the storage for an object of `struct sockaddr`; that's just the "abstract base" so to speak: pointers are cast to that type when calling the API. The API switches to the right department in the code, which converts the pointer back to the right concrete type again, like "struct sockaddr_in". So all that is needed is the property that the "struct sockaddr " type can store and recover any other "struct sockaddr_whatever " pointer.

You're also never going to be doing completely silly things like converting a "struct sockaddr_in " to "struct sockaddr_ax25 " or whatever.