Passing file descriptors through unix domain socket is well-known. But there still have some tricks in implementation. I spent one day to deal with it in Mac OS X by digging into xnu source.
- How to pass multiple file descriptors in one sendmsg() call>
Simple. Put all file descriptors one by one after struct cmsghdr.
- Can I put multiple struct cmsghdrs with data? I noticed there are CMSG_FIRSTHDR() and CMSG_NXTHDR() defined in <sys/socket.h>
No. In xnu sources it checks msghdr.controllen with cmsghdr.cmsg_len. If they are not equal, a -EINVAL returned in sendmsg() call. That means only one cmsghdr can be put into msghdr.
The limitation is in OS X only. I haven’t check Linux and would do it soon or later.