summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@bitplanet.net>2012-04-21 23:50:09 -0400
committerKristian Høgsberg <krh@bitplanet.net>2012-04-21 23:50:13 -0400
commit0d6dea17b4e25b775dcad44b024137a293fe06bf (patch)
treecd6c3995d17efcbff79391841518b8a1192c56ac
parent9d37682db32f16eb69a76d21569af6cac0d3d08c (diff)
connection: Dont put fds in the connection until we send the closure
-rw-r--r--src/connection.c35
1 files changed, 30 insertions, 5 deletions
diff --git a/src/connection.c b/src/connection.c
index 147dc42..6967262 100644
--- a/src/connection.c
+++ b/src/connection.c
@@ -533,11 +533,6 @@ wl_connection_vmarshal(struct wl_connection *connection,
abort();
}
*fd_ptr = dup_fd;
- if (wl_connection_put_fd(connection, dup_fd)) {
- printf("request could not be mashaled: "
- "can't send file descriptor");
- return NULL;
- }
break;
default:
fprintf(stderr, "unhandled format code: '%c'\n",
@@ -767,11 +762,38 @@ wl_closure_invoke(struct wl_closure *closure,
ffi_call(&closure->cif, func, &result, closure->args);
}
+static int
+copy_fds_to_connection(struct wl_closure *closure,
+ struct wl_connection *connection)
+{
+ const struct wl_message *message = closure->message;
+ uint32_t i, count;
+ int *fd;
+
+ count = strlen(message->signature) + 2;
+ for (i = 2; i < count; i++) {
+ if (message->signature[i - 2] != 'h')
+ continue;
+
+ fd = closure->args[i];
+ if (wl_connection_put_fd(connection, *fd)) {
+ fprintf(stderr, "request could not be marshaled: "
+ "can't send file descriptor");
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
int
wl_closure_send(struct wl_closure *closure, struct wl_connection *connection)
{
uint32_t size;
+ if (copy_fds_to_connection(closure, connection))
+ return -1;
+
size = closure->start[1] >> 16;
return wl_connection_write(connection, closure->start, size);
@@ -782,6 +804,9 @@ wl_closure_queue(struct wl_closure *closure, struct wl_connection *connection)
{
uint32_t size;
+ if (copy_fds_to_connection(closure, connection))
+ return -1;
+
size = closure->start[1] >> 16;
return wl_connection_queue(connection, closure->start, size);