diff options
author | Keith Packard <keithp@keithp.com> | 2013-01-14 11:23:00 -0800 |
---|---|---|
committer | Keith Packard <keithp@keithp.com> | 2013-11-07 14:02:35 -0800 |
commit | 7b53fb0f9bddae77b3ab8823743db57faee4e99b (patch) | |
tree | 48cd3517a30bd2905a3a13aae941831e7b36fb1e /src/xcb_conn.c | |
parent | 98c227a2222fb5c7ca7e8101b1ed2bc096a33048 (diff) |
Add xcb_send_fd API
This uses sendmsg to transmit file descriptors from the application to
the X server
Signed-off-by: Keith Packard <keithp@keithp.com>
Reviewed-By: Uli Schlachter <psychon@znc.in>
Diffstat (limited to 'src/xcb_conn.c')
-rw-r--r-- | src/xcb_conn.c | 31 |
1 files changed, 28 insertions, 3 deletions
diff --git a/src/xcb_conn.c b/src/xcb_conn.c index 7dd25d3..c06c7cb 100644 --- a/src/xcb_conn.c +++ b/src/xcb_conn.c @@ -214,9 +214,34 @@ static int write_vec(xcb_connection_t *c, struct iovec **vector, int *count) if (n > IOV_MAX) n = IOV_MAX; - n = writev(c->fd, *vector, n); - if(n < 0 && errno == EAGAIN) - return 1; +#if HAVE_SENDMSG + if (c->out.out_fd.nfd) { + struct msghdr msg = { + .msg_name = NULL, + .msg_namelen = 0, + .msg_iov = *vector, + .msg_iovlen = n, + .msg_control = &c->out.out_fd, + .msg_controllen = sizeof (struct cmsghdr) + c->out.out_fd.nfd * sizeof (int), + }; + int i; + c->out.out_fd.cmsghdr.cmsg_len = msg.msg_controllen; + c->out.out_fd.cmsghdr.cmsg_level = SOL_SOCKET; + c->out.out_fd.cmsghdr.cmsg_type = SCM_RIGHTS; + n = sendmsg(c->fd, &msg, 0); + if(n < 0 && errno == EAGAIN) + return 1; + for (i = 0; i < c->out.out_fd.nfd; i++) + close(c->out.out_fd.fd[i]); + c->out.out_fd.nfd = 0; + } else +#endif + { + n = writev(c->fd, *vector, n); + if(n < 0 && errno == EAGAIN) + return 1; + } + #endif /* _WIN32 */ if(n <= 0) |