Linux中跨进程传递文件描述符需通过Unix域套接字的sendmsg/recvmsg发送SCM_RIGHTS控制消息,使接收方获得指向相同内核文件表项的新fd,共享打开状态;仅AF_UNIX套接字支持,须正确设置地址族、路径权限及cmsg结构,并严格验证收发两端fd有效性。
Linux 中跨进程传递文件描述符,核心是利用 Unix Domain Socket 配合 sendmsg/recvmsg 传递 SCM_RIGHTS 类型的控制消息。这不是传一个整数,而是让内核在接收进程中创建一个新的 fd,指向与发送方相同的内核文件表项——真正实现“共享打开状态”,包括偏移量、访问模式、锁等。
只有 AF_UNIX 类型的 socket(流式 SOCK_STREAM 或数据报 SOCK_DGRAM)支持描述符传递。TCP/IP 套接字不支持。常见错误是误用网络 socket 或未正确设置地址族。
/tmp/fdsock),并 listen/accept;客户端 connect 到该路径socketpair(AF_UNIX, SOCK_STREAM, 0, sv) 快速建立双向通道,省去 bind/connect 步骤发送 fd 时,不能用普通 send,必须填充 msghdr 并附带 cmsg 控制数据。重点在 msg_control 字段的组织。
CMSG_SPACE(sizeof(int)) 计算缓冲区大小,包含头部+数据cmsg_level = SOL_SOCKET,cmsg_type = SCM_RIGHTS
CMSG_DATA(cmsg),注意是 int 值,不是指针msg_iov 可只传 1 字节 dummy 数据(如 "x"),因为实际 payload 是控制消息,不是 iovrecvmsg 后需遍历控制消息,确认类型和层级,并检查返回 fd 是否有效。忽略验证可能引发后续读写失败或资源泄漏。
CMSG_FIRSTHDR(&msg) 获取首个 cmsg 指针cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS
CMSG_DATA(cmsg) 取出 int 值,赋给新变量(如 int newfd = *(int*)CMSG_DATA(cmsg))newfd >= 0,若为 -1 表示传递失败(如对方关闭 socket 或权限不足)这套机制看似简单,但几个细节处理不当会导致静默失败或崩溃:
fcntl(fd, F_SETFD, 0) 清除 FD_CLOEXEC)fstat(newfd, &st) 验证是否可读/写,避免误用无效 fdsizeof(int) * n