[Xcb] [PATCH 1/3 resend] xcb_send_fd(): Always close fds
Uli Schlachter
psychon at znc.in
Wed Apr 22 11:30:07 PDT 2015
The API docs for xcb_send_fd() says "After this function returns, the file
descriptor given is owned by xcb and will be closed eventually".
Let the implementation live up to its documentation.
(This also does sneak in some preparatory functions for follow-up commits and
thus does things in a more complicated way than really necessary.)
Signed-off-by: Uli Schlachter <psychon at znc.in>
---
src/xcb_out.c | 43 +++++++++++++++++++++++++++++++++----------
1 file changed, 33 insertions(+), 10 deletions(-)
diff --git a/src/xcb_out.c b/src/xcb_out.c
index dc42954..3d717e8 100644
--- a/src/xcb_out.c
+++ b/src/xcb_out.c
@@ -177,6 +177,33 @@ uint32_t xcb_get_maximum_request_length(xcb_connection_t *c)
return c->out.maximum_request_length.value;
}
+static void close_fds(unsigned int num_fds, int *fds)
+{
+ for (unsigned int index = 0; index < num_fds; index++)
+ close(fds[index]);
+}
+
+static void send_fds(xcb_connection_t *c, unsigned int num_fds, int *fds)
+{
+#if HAVE_SENDMSG
+ while (num_fds > 0) {
+ /* FIXME: This will busy-loop when XCB_MAX_PASS_FD fds are sent at once */
+ while (c->out.out_fd.nfd == XCB_MAX_PASS_FD) {
+ _xcb_out_flush_to(c, c->out.request);
+ if (c->has_error)
+ break;
+ }
+ if (!c->has_error)
+ c->out.out_fd.fd[c->out.out_fd.nfd++] = fds[0];
+
+ fds++;
+ num_fds--;
+ }
+#else
+ close_fds(num_fds, fds);
+#endif
+}
+
unsigned int xcb_send_request(xcb_connection_t *c, int flags, struct iovec *vector, const xcb_protocol_request_t *req)
{
uint64_t request;
@@ -289,19 +316,15 @@ unsigned int xcb_send_request(xcb_connection_t *c, int flags, struct iovec *vect
void
xcb_send_fd(xcb_connection_t *c, int fd)
{
-#if HAVE_SENDMSG
- if (c->has_error)
+ int fds[1] = { fd };
+
+ if (c->has_error) {
+ close(fd);
return;
- pthread_mutex_lock(&c->iolock);
- while (c->out.out_fd.nfd == XCB_MAX_PASS_FD) {
- _xcb_out_flush_to(c, c->out.request);
- if (c->has_error)
- break;
}
- if (!c->has_error)
- c->out.out_fd.fd[c->out.out_fd.nfd++] = fd;
+ pthread_mutex_lock(&c->iolock);
+ send_fds(c, 1, &fds[0]);
pthread_mutex_unlock(&c->iolock);
-#endif
}
int xcb_take_socket(xcb_connection_t *c, void (*return_socket)(void *closure), void *closure, int flags, uint64_t *sent)
--
2.1.4
More information about the Xcb
mailing list