only support sending one fd

This commit is contained in:
Christian Ulrich 2020-06-10 22:55:18 +02:00
parent 8a5b3d41b6
commit 742c047480
No known key found for this signature in database
GPG Key ID: 8241BE099775A097
1 changed files with 10 additions and 8 deletions

View File

@ -1,4 +1,4 @@
import asyncdispatch, threadpool, osproc import asyncdispatch, threadpool, osproc, options
from os import from os import
osLastError, osLastError,
newOsError newOsError
@ -47,32 +47,34 @@ proc asyncExecCmd*(command: string): Future[int] =
proc asyncSendMsg*(fd: AsyncFD, proc asyncSendMsg*(fd: AsyncFD,
data: string, data: string,
fds: openArray[AsyncFD] = []): Future[void] = ancillaryData: Option[AsyncFD] = none(AsyncFD)): Future[void] =
var retFuture = newFuture[void]("asyncSendMsg") var retFuture = newFuture[void]("asyncSendMsg")
proc cb(sock: AsyncFD): bool = proc cb(sock: AsyncFD): bool =
# FIXME: if file descriptors are given in fds, check if sock is a unix socket # FIXME: if file descriptor is given in ancillaryData, check if sock is a
# unix socket
result = true result = true
# sendmsg needs an array of iovec structs as described in the writev(2) man # sendmsg needs an array of iovec structs as described in the writev(2) man
# page. The message is passed as a msghdr struct which may contain ancillary # page. The message is passed as a msghdr struct which may contain ancillary
# data, see sendmsg(2) man page. We use ancillary data exclusively for # data, see sendmsg(2) man page. We use ancillary data exclusively for
# passing file descriptors if any are given in fds. # passing a file descriptor if one is given in ancillaryData.
var iovec = IOVec(iov_base: data.cstring, var iovec = IOVec(iov_base: data.cstring,
iov_len: data.len.csize_t) iov_len: data.len.csize_t)
var msg = Tmsghdr(msg_iov: addr iovec, var msg = Tmsghdr(msg_iov: addr iovec,
msg_iovlen: 1) msg_iovlen: 1)
if fds.len > 0: if ancillaryData.isSome:
# assemble ancillary data, see cmsg(3) man page # assemble ancillary data, see cmsg(3) man page
let cmsgBufferLen = CMSG_SPACE(sizeof(AsyncFD).csize_t * fds.len.csize_t) let cmsgBufferLen = CMSG_SPACE(sizeof(AsyncFD).csize_t)
let cmsgBuffer = newString(cmsgBufferLen) let cmsgBuffer = newString(cmsgBufferLen)
msg.msg_control = cmsgBuffer.cstring msg.msg_control = cmsgBuffer.cstring
msg.msg_controllen = cmsgBufferLen msg.msg_controllen = cmsgBufferLen
let cmsg: ptr Tcmsghdr = CMSG_FIRSTHDR(addr msg) let cmsg: ptr Tcmsghdr = CMSG_FIRSTHDR(addr msg)
cmsg.cmsg_len = CMSG_LEN(sizeof(AsyncFD).csize_t * fds.len.csize_t) cmsg.cmsg_len = CMSG_LEN(sizeof(AsyncFD).csize_t)
cmsg.cmsg_level = SOL_SOCKET cmsg.cmsg_level = SOL_SOCKET
cmsg.cmsg_type = SCM_RIGHTS cmsg.cmsg_type = SCM_RIGHTS
copyMem(CMSG_DATA(cmsg), unsafeAddr fds[0], sizeof(AsyncFD) * fds.len) var ancillaryFd = ancillaryData.get
copyMem(CMSG_DATA(cmsg), addr ancillaryFd, sizeof(AsyncFD))
let res = sendmsg(sock.SocketHandle, addr msg, 0) let res = sendmsg(sock.SocketHandle, addr msg, 0)
if res < 0: if res < 0: