在Unix域套接字上传递文件描述符时,使用类型SOL_SOCKET
的级别SCM_RIGHTS
的控制消息。
使用宏CMSG_FIRSTHDR
,CMSG_NXTHDR
和CMSG_DATA
读取和写入控制消息。他们考虑到对齐问题。取决于操作系统和libc实现,它们在相同或不同的转换单元中强制转换指针并取消引用结果。它们还会返回此类指针,并且调用代码通常会取消引用它们。
结果,使用简单的堆栈分配的char buf[CMSG_SPACE(sizeof(int))]
作为控制消息缓冲区将违反严格的别名,因为只能使用char
,signed char
类型的左值来访问该缓冲区,unsigned char
或其中的限定版本。 (在某些平台上,缓冲区也可能未适当对齐,但是amd64调用约定似乎可以保证这一点,因为缓冲区足够大。)
一个明显正确的解决方法是使用calloc()
分配控制消息缓冲区,该缓冲区提供适当对齐的内存而没有有效的类型。但是,我想避免使程序效率降低。
在https://svnweb.freebsd.org/base/head/lib/libopenbsd/imsg.c?revision=292023&view=markup中,我找到了另一种方法,其中堆栈缓冲区的类型为union { struct cmsghdr hdr; char buf[CMSG_SPACE(sizeof(int))]; }
,但是我不知道这是否正确。我认为struct cmsghdr
的字段类型为int
会有所帮助。
额外的问题:鉴于C ++在(除其他事项外)关于联合的规则不同于C,如何在C ++中做到这一点?