是否可以使用 Go 通过 Unix 域套接字发送和接收文件描述符?
Is it possible to use Go to send and receive file descriptors over Unix domain sockets?
在 Unix 域套接字的 unix(7)
手册页中,它说 sendmsg
可以与 SCM_RIGHTS
标志一起使用以通过这些套接字发送文件描述符。这在 Go 中受支持吗?是否有任何好的示例代码显示它是如何完成的?
似乎在 syscall
包中声明了一个 Msghdr
structure。但是没有功能接受它。也许我必须使用原始系统调用接口?
这里有一个包可以做到这一点:https://github.com/ftrvxmtrx/fd/blob/master/fd.go。然而,这是使用 Syscall 包来实现的。我不确定是否有办法使用 Go 标准库 API.
在syscall
包中,要看的东西是UnixRights
、ParseUnixRights
和ParseSocketControlMessage
。这些可以与 Readmsg
和 Sendmsg
结合使用,通过 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...)
}
而对于发送,它更简单(var fds []int
):
rights := syscall.UnixRights(fds...)
err := syscall.Sendmsg(socket, nil, rights, nil, 0)
在 Unix 域套接字的 unix(7)
手册页中,它说 sendmsg
可以与 SCM_RIGHTS
标志一起使用以通过这些套接字发送文件描述符。这在 Go 中受支持吗?是否有任何好的示例代码显示它是如何完成的?
似乎在 syscall
包中声明了一个 Msghdr
structure。但是没有功能接受它。也许我必须使用原始系统调用接口?
这里有一个包可以做到这一点:https://github.com/ftrvxmtrx/fd/blob/master/fd.go。然而,这是使用 Syscall 包来实现的。我不确定是否有办法使用 Go 标准库 API.
在syscall
包中,要看的东西是UnixRights
、ParseUnixRights
和ParseSocketControlMessage
。这些可以与 Readmsg
和 Sendmsg
结合使用,通过 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...)
}
而对于发送,它更简单(var fds []int
):
rights := syscall.UnixRights(fds...)
err := syscall.Sendmsg(socket, nil, rights, nil, 0)