only support sending one fd
This commit is contained in:
parent
8a5b3d41b6
commit
742c047480
|
@ -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:
|
||||||
|
|
Loading…
Reference in New Issue