summaryrefslogtreecommitdiff
path: root/src/xcb_conn.c
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2013-01-14 11:23:00 -0800
committerKeith Packard <keithp@keithp.com>2013-11-07 14:02:35 -0800
commit7b53fb0f9bddae77b3ab8823743db57faee4e99b (patch)
tree48cd3517a30bd2905a3a13aae941831e7b36fb1e /src/xcb_conn.c
parent98c227a2222fb5c7ca7e8101b1ed2bc096a33048 (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.c31
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)