[tls] > The issue involves the way we arranged for binary compatibility > across changes in the unix-domain file descriptor and credentials > passing code. [...]
> I would appreciate others' opinions on this. Here's scm-rights.h from one of my SCM_RIGHTS-using programs. I think the comments say it all. They were written based on, IIRC, the 3.1 interface, but based on this thread it sounds as though it's only gotten worse since then. /~\ The ASCII Mouse \ / Ribbon Campaign X Against HTML mo...@rodents-montreal.org / \ Email! 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B #ifndef _SCM_RIGHTS_H_e8240238_ #define _SCM_RIGHTS_H_e8240238_ /* This file is in the public domain. */ /* * This file exists because the SCM_RIGHTS interface silently changed. * It used to work the traditional way: pack file descriptors tightly * as an array of ints immediately after the struct cmsghdr. It was * changed to use the layout corresponding to the CMSG_* macros, which * don't exist historically; since the resulting layout is different * on architectures for which __cmsg_alignbytes is greater than * sizeof(int)-1, this is rather broken, breaking historically working * code. (The CMSG_* macros were invented for all the control guff * IPv6 wants to shovel around. What I don't understand is why they * were imposed on SCM_RIGHTS messages.) To make things worse, the * CMSG_* macros are a broken API: they don't even try to support * control messages that aren't in buffers aligned suitably for a * struct cmsghdr (in particular, there is no way to find out where * the data for a message falls relative to the message's beginning * except by computing the data pointer as a function of the cmsghdr * pointer). This means you have to either use gcc extensions like * __alignof__ or you have to do something like the CMSKIP macro * below - unless you're willing to malloc the buffer (and, strictly, * even that is not enough, since there is no guarantee that the * required alignment is that of any object type). * * So we actually use macros CMSPACE, CMLEN, and CMSKIP, which are * defined either suitably for the historical way (if * NEW_CMSG_INTERFACE is not defined) or the least ugly way I've found * for the CMSG_* way (if NEW_CMSG_INTERFACE is defined). */ #ifdef NEW_CMSG_INTERFACE #define CMSPACE(x) (CMSG_SPACE((x))) #define CMLEN(x) (CMSG_LEN((x))) /* * It's gross to have to do this, but it's more or less forced upon us * by the botched design of the the CMSG_* interface. The interface * takes first steps towards a completely opaque interface, but * botches it rather badly, resulting in neither an interface that can * be used opaquely nor an interface that can be used transparently. * Since the traditional interface is the transparent style, and the * opaque style cannot be done without alignment issues (see below), * this code goes in the transparent direction. The result is not as * portable as I'd like - it can depend on using a pointer past the * end of an object, depending on the architecture - but I believe * it's the least horrible of the available alternatives. * * The interface seems designed to overlay the structs cmsghdr onto the * control buffer, but that demands the buffer be aligned, without * providing any way to actually achieve that, which more or less * compels its allocation with malloc(), that being the only portable * way to correctly align a buffer whose alignment requirements are * inacessible. (Using gcc extensions like __aligned__ and * __alignof__, this can be worked around, but (a) that's gcc-specific * and rather ugly, (b) it shouldn't be necessary, and (c) it can't be * done without making assumptions for which there is no basis except * knowledge of the implementation, like "the alignment necessary is * the most strict of struct cmsghdr and the types to be stored in the * buffer". */ #define CMSKIP(x) ((char *)CMSG_DATA((x))-(char *)(x)) #else #define CMSPACE(x) (sizeof(struct cmsghdr)+(x)) #define CMLEN(x) (sizeof(struct cmsghdr)+(x)) #define CMSKIP(x) (sizeof(struct cmsghdr)) #endif #endif