The padding fields are necessary due to memory layout, however they are also private, which in conjunction with the lack of constructor means it is impossible to construct a msghdr without resorting to unsafe code. On the other hand the padding guarantees that [0; size_of::<msghdr>()] is a valid representation, which is why I resorted to MaybeUninit::zeroed as unsafe constructor.
In addition struct update syntax (msghdr {..MaybeUninit::zeroed()}) sadly does not work with private fields, so I had to resort to first constructing a zeroed msghdr and then updating the individual fields.
An explanation of the unsafe block:
Musl has a different msghdr structure than glibc. It looks as follows:
The padding fields are necessary due to memory layout, however they are also private, which in conjunction with the lack of constructor means it is impossible to construct a msghdr without resorting to unsafe code. On the other hand the padding guarantees that
[0; size_of::<msghdr>()]
is a valid representation, which is why I resorted to MaybeUninit::zeroed as unsafe constructor.In addition struct update syntax (
msghdr {..MaybeUninit::zeroed()}
) sadly does not work with private fields, so I had to resort to first constructing a zeroed msghdr and then updating the individual fields.