[PATCH 2/2] Add APIs to send file descriptors through the network

Mouse mouse at Rodents-Montreal.ORG
Fri Nov 1 21:05:23 CET 2013


> This implementation isn't quite right as it doesn't use the proper
> CMSG_ macros to manipulate the ancillary data object information.

As I read 3542, those are for IPv6.  Using them for SCM_RIGHTS data is
unwarranted and, IMO, inappropriate.  (That OSes do so anyway is IMO a
bug.)

Not to mention that the API is broken; here's scm-rights.h from a
program of mine that wants to pass file descriptors around.  It puts it
better than I'm likely to put it now.

#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

/~\ The ASCII				  Mouse
\ / Ribbon Campaign
 X  Against HTML		mouse at rodents-montreal.org
/ \ Email!	     7D C8 61 52 5D E7 2D 39  4E F1 31 3E E8 B3 27 4B


More information about the xorg-devel mailing list