是否可以使用 Go 通过 Unix 域套接字发送和接收文件描述符?

Omn*_*ous 1 unix go unix-socket

unix(7)Unix 域套接字的手册页中,它说sendmsg可以与标志一起使用SCM_RIGHTS通过这些套接字发送文件描述符。Go 支持吗?有没有好的示例代码展示它是如何完成的?

包中似乎声明了一个Msghdr结构syscall。但没有函数接受它。也许我必须使用原始系统调用接口?

Mat*_*son 5

这里有一个包可以做到这一点: https: //github.com/ftrvxmtrx/fd/blob/master/fd.go。然而,这是使用 Syscall 包来实现的。我不确定是否有办法使用 Go 标准库 API 来做到这一点。

包装中syscall,需要注意的是UnixRightsParseUnixRights、 和ParseSocketControlMessage。这些可以与 AF_UNIX 套接字结合使用ReadmsgSendmsg通过 AF_UNIX 套接字发送文件描述符。

接收的基本结构如下:

buf := make([]byte, syscall.CmsgSpace(<number of file descriptors expected> * 4))
_, _, _, _, err = syscall.Recvmsg(socket, nil, buf, 0)
if err != nil {
    panic(err)
}
var msgs []syscall.SocketControlMessage
msgs, err = syscall.ParseSocketControlMessage(buf)
var allfds []int
for i := 0, i < len(msgs) && err == null; i++ {
    var msgfds []int
    msgfds, err = syscall.ParseUnixRights(&msgs[i])
    append(allfds, msgfds...)
}
Run Code Online (Sandbox Code Playgroud)

对于发送来说,就简单多了(var fds []int):

rights := syscall.UnixRights(fds...)
err := syscall.Sendmsg(socket, nil, rights, nil, 0)
Run Code Online (Sandbox Code Playgroud)