On 2025-11-16, Pokemon Chw via Python-list <[email protected]> wrote:

> On Linux AF_UNIX + SOCK_STREAM sockets, there is a quirk in how the
> kernel handles control messages with SCM_RIGHTS:
>
> To successfully pass file descriptors via SCM_RIGHTS, you must send
> at least one byte of normal data in the same sendmsg()
> call. Otherwise, the control message (i.e., the file descriptors)
> will not actually be transmitted.

Very interesting! If I ever knew that I had completely forgotten it.
Apparently that's not true on Mac OS-X where there must be at least
one iovec entry, but that entry can contain zero bytes.

FWIW, here is the relevent portion of the Linux man page Unix(7):

  Ancillary messages
  
    Ancillary data is sent and received using sendmsg(2) and
    recvmsg(2).  For historical reasons, the ancillary message types
    listed below are specified with a SOL_SOCKET type even though they
    are AF_UNIX specific.  To send them, set the cmsg_level field of
    the struct cmsghdr to SOL_SOCKET and the cmsg_type field to the
    type.  For more information, see cmsg(3).

    SCM_RIGHTS

      Send or receive a set of open file descriptors from another
      process.  The data portion contains an integer array of the file
      descriptors.

      Commonly, this operation is referred to as "passing a file
      descriptor" to another process.  However, more accurately, what
      is being passed is a reference to an open file description (see
      open(2)), and in the receiving process it is likely that a
      different file descriptor number will be used.  Semantically,
      this operation is equivalent to duplicating (dup(2)) a file
      descriptor into the file descriptor table of another process.

      If the buffer used to receive the ancillary data containing file
      de‐ scriptors is too small (or is absent), then the ancillary
      data is truncated (or discarded) and the excess file descriptors
      are automati‐ cally closed in the receiving process.

      If the number of file descriptors received in the ancillary data
      would cause the process to exceed its RLIMIT_NOFILE resource
      limit (see getrlimit(2)), the excess file descriptors are
      automatically closed in the receiving process.

      The kernel constant SCM_MAX_FD defines a limit on the number of
      file descriptors in the array.  Attempting to send an array
      larger than this limit causes sendmsg(2) to fail with the error
      EINVAL.  SCM_MAX_FD has the value 253 (or 255 before Linux
      2.6.38).

   [...]

   At least one byte of real data should be sent when sending
   ancillary data.  On Linux, this is required to successfully send
   ancillary data over a UNIX domain stream socket.  When sending
   ancillary data over a UNIX domain datagram socket, it is not
   necessary on Linux to send any accompanying real data.  However,
   portable applications should also include at least one byte of real
   data when sending ancillary data over a datagram socket.
-- 
https://mail.python.org/mailman3//lists/python-list.python.org

Reply via email to