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

时间:2017-12-05 01:28:22

标签: unix go unix-socket

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

syscall包中似乎声明了Msghdr structure。但没有任何功能。也许我必须使用原始系统调用接口?

1 个答案:

答案 0 :(得分:2)

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

syscall包中,要查看的内容包括UnixRightsParseUnixRightsParseSocketControlMessage。这些可以与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...)
}

发送时,它更简单(var fds []int):

rights := syscall.UnixRights(fds...)
err := syscall.Sendmsg(socket, nil, rights, nil, 0)