e6c2b646671007688a02e6b90d52a47ac38b9fa5
[profile/ivi/wayland.git] / src / connection.c
1 /*
2  * Copyright © 2008 Kristian Høgsberg
3  * Copyright © 2013 Jason Ekstrand
4  *
5  * Permission to use, copy, modify, distribute, and sell this software and its
6  * documentation for any purpose is hereby granted without fee, provided that
7  * the above copyright notice appear in all copies and that both that copyright
8  * notice and this permission notice appear in supporting documentation, and
9  * that the name of the copyright holders not be used in advertising or
10  * publicity pertaining to distribution of the software without specific,
11  * written prior permission.  The copyright holders make no representations
12  * about the suitability of this software for any purpose.  It is provided "as
13  * is" without express or implied warranty.
14  *
15  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
17  * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
18  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
19  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
20  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
21  * OF THIS SOFTWARE.
22  */
23
24 #define _GNU_SOURCE
25
26 #include <math.h>
27 #include <stdlib.h>
28 #include <stdint.h>
29 #include <string.h>
30 #include <stdio.h>
31 #include <errno.h>
32 #include <sys/uio.h>
33 #include <assert.h>
34 #include <fcntl.h>
35 #include <unistd.h>
36 #include <sys/types.h>
37 #include <sys/socket.h>
38 #include <time.h>
39 #include <ffi.h>
40
41 #include "wayland-util.h"
42 #include "wayland-private.h"
43 #include "wayland-os.h"
44
45 #define DIV_ROUNDUP(n, a) ( ((n) + ((a) - 1)) / (a) )
46
47 struct wl_buffer {
48         char data[4096];
49         uint32_t head, tail;
50 };
51
52 #define MASK(i) ((i) & 4095)
53
54 #define MAX_FDS_OUT     28
55 #define CLEN            (CMSG_LEN(MAX_FDS_OUT * sizeof(int32_t)))
56
57 struct wl_connection {
58         struct wl_buffer in, out;
59         struct wl_buffer fds_in, fds_out;
60         int fd;
61         int want_flush;
62 };
63
64 static void
65 wl_buffer_put(struct wl_buffer *b, const void *data, size_t count)
66 {
67         uint32_t head, size;
68
69         head = MASK(b->head);
70         if (head + count <= sizeof b->data) {
71                 memcpy(b->data + head, data, count);
72         } else {
73                 size = sizeof b->data - head;
74                 memcpy(b->data + head, data, size);
75                 memcpy(b->data, (const char *) data + size, count - size);
76         }
77
78         b->head += count;
79 }
80
81 static void
82 wl_buffer_put_iov(struct wl_buffer *b, struct iovec *iov, int *count)
83 {
84         uint32_t head, tail;
85
86         head = MASK(b->head);
87         tail = MASK(b->tail);
88         if (head < tail) {
89                 iov[0].iov_base = b->data + head;
90                 iov[0].iov_len = tail - head;
91                 *count = 1;
92         } else if (tail == 0) {
93                 iov[0].iov_base = b->data + head;
94                 iov[0].iov_len = sizeof b->data - head;
95                 *count = 1;
96         } else {
97                 iov[0].iov_base = b->data + head;
98                 iov[0].iov_len = sizeof b->data - head;
99                 iov[1].iov_base = b->data;
100                 iov[1].iov_len = tail;
101                 *count = 2;
102         }
103 }
104
105 static void
106 wl_buffer_get_iov(struct wl_buffer *b, struct iovec *iov, int *count)
107 {
108         uint32_t head, tail;
109
110         head = MASK(b->head);
111         tail = MASK(b->tail);
112         if (tail < head) {
113                 iov[0].iov_base = b->data + tail;
114                 iov[0].iov_len = head - tail;
115                 *count = 1;
116         } else if (head == 0) {
117                 iov[0].iov_base = b->data + tail;
118                 iov[0].iov_len = sizeof b->data - tail;
119                 *count = 1;
120         } else {
121                 iov[0].iov_base = b->data + tail;
122                 iov[0].iov_len = sizeof b->data - tail;
123                 iov[1].iov_base = b->data;
124                 iov[1].iov_len = head;
125                 *count = 2;
126         }
127 }
128
129 static void
130 wl_buffer_copy(struct wl_buffer *b, void *data, size_t count)
131 {
132         uint32_t tail, size;
133
134         tail = MASK(b->tail);
135         if (tail + count <= sizeof b->data) {
136                 memcpy(data, b->data + tail, count);
137         } else {
138                 size = sizeof b->data - tail;
139                 memcpy(data, b->data + tail, size);
140                 memcpy((char *) data + size, b->data, count - size);
141         }
142 }
143
144 static uint32_t
145 wl_buffer_size(struct wl_buffer *b)
146 {
147         return b->head - b->tail;
148 }
149
150 struct wl_connection *
151 wl_connection_create(int fd)
152 {
153         struct wl_connection *connection;
154
155         connection = malloc(sizeof *connection);
156         if (connection == NULL)
157                 return NULL;
158         memset(connection, 0, sizeof *connection);
159         connection->fd = fd;
160
161         return connection;
162 }
163
164 static void
165 close_fds(struct wl_buffer *buffer, int max)
166 {
167         int32_t fds[sizeof(buffer->data) / sizeof(int32_t)], i, count;
168         size_t size;
169
170         size = buffer->head - buffer->tail;
171         if (size == 0)
172                 return;
173
174         wl_buffer_copy(buffer, fds, size);
175         count = size / sizeof fds[0];
176         if (max > 0 && max < count)
177                 count = max;
178         for (i = 0; i < count; i++)
179                 close(fds[i]);
180         buffer->tail += size;
181 }
182
183 void
184 wl_connection_destroy(struct wl_connection *connection)
185 {
186         close_fds(&connection->fds_out, -1);
187         close_fds(&connection->fds_in, -1);
188         close(connection->fd);
189         free(connection);
190 }
191
192 void
193 wl_connection_copy(struct wl_connection *connection, void *data, size_t size)
194 {
195         wl_buffer_copy(&connection->in, data, size);
196 }
197
198 void
199 wl_connection_consume(struct wl_connection *connection, size_t size)
200 {
201         connection->in.tail += size;
202 }
203
204 static void
205 build_cmsg(struct wl_buffer *buffer, char *data, int *clen)
206 {
207         struct cmsghdr *cmsg;
208         size_t size;
209
210         size = buffer->head - buffer->tail;
211         if (size > MAX_FDS_OUT * sizeof(int32_t))
212                 size = MAX_FDS_OUT * sizeof(int32_t);
213
214         if (size > 0) {
215                 cmsg = (struct cmsghdr *) data;
216                 cmsg->cmsg_level = SOL_SOCKET;
217                 cmsg->cmsg_type = SCM_RIGHTS;
218                 cmsg->cmsg_len = CMSG_LEN(size);
219                 wl_buffer_copy(buffer, CMSG_DATA(cmsg), size);
220                 *clen = cmsg->cmsg_len;
221         } else {
222                 *clen = 0;
223         }
224 }
225
226 static int
227 decode_cmsg(struct wl_buffer *buffer, struct msghdr *msg)
228 {
229         struct cmsghdr *cmsg;
230         size_t size, max, i;
231         int overflow = 0;
232
233         for (cmsg = CMSG_FIRSTHDR(msg); cmsg != NULL;
234              cmsg = CMSG_NXTHDR(msg, cmsg)) {
235                 if (cmsg->cmsg_level != SOL_SOCKET ||
236                     cmsg->cmsg_type != SCM_RIGHTS)
237                         continue;
238
239                 size = cmsg->cmsg_len - CMSG_LEN(0);
240                 max = sizeof(buffer->data) - wl_buffer_size(buffer);
241                 if (size > max || overflow) {
242                         overflow = 1;
243                         size /= sizeof(int32_t);
244                         for (i = 0; i < size; i++)
245                                 close(((int*)CMSG_DATA(cmsg))[i]);
246                 } else {
247                         wl_buffer_put(buffer, CMSG_DATA(cmsg), size);
248                 }
249         }
250
251         if (overflow) {
252                 errno = EOVERFLOW;
253                 return -1;
254         }
255
256         return 0;
257 }
258
259 int
260 wl_connection_flush(struct wl_connection *connection)
261 {
262         struct iovec iov[2];
263         struct msghdr msg;
264         char cmsg[CLEN];
265         int len = 0, count, clen;
266         uint32_t tail;
267
268         if (!connection->want_flush)
269                 return 0;
270
271         tail = connection->out.tail;
272         while (connection->out.head - connection->out.tail > 0) {
273                 wl_buffer_get_iov(&connection->out, iov, &count);
274
275                 build_cmsg(&connection->fds_out, cmsg, &clen);
276
277                 msg.msg_name = NULL;
278                 msg.msg_namelen = 0;
279                 msg.msg_iov = iov;
280                 msg.msg_iovlen = count;
281                 msg.msg_control = cmsg;
282                 msg.msg_controllen = clen;
283                 msg.msg_flags = 0;
284
285                 do {
286                         len = sendmsg(connection->fd, &msg,
287                                       MSG_NOSIGNAL | MSG_DONTWAIT);
288                 } while (len == -1 && errno == EINTR);
289
290                 if (len == -1)
291                         return -1;
292
293                 close_fds(&connection->fds_out, MAX_FDS_OUT);
294
295                 connection->out.tail += len;
296         }
297
298         connection->want_flush = 0;
299
300         return connection->out.head - tail;
301 }
302
303 int
304 wl_connection_read(struct wl_connection *connection)
305 {
306         struct iovec iov[2];
307         struct msghdr msg;
308         char cmsg[CLEN];
309         int len, count, ret;
310
311         if (wl_buffer_size(&connection->in) >= sizeof(connection->in.data)) {
312                 errno = EOVERFLOW;
313                 return -1;
314         }
315
316         wl_buffer_put_iov(&connection->in, iov, &count);
317
318         msg.msg_name = NULL;
319         msg.msg_namelen = 0;
320         msg.msg_iov = iov;
321         msg.msg_iovlen = count;
322         msg.msg_control = cmsg;
323         msg.msg_controllen = sizeof cmsg;
324         msg.msg_flags = 0;
325
326         do {
327                 len = wl_os_recvmsg_cloexec(connection->fd, &msg, 0);
328         } while (len < 0 && errno == EINTR);
329
330         if (len <= 0)
331                 return len;
332
333         ret = decode_cmsg(&connection->fds_in, &msg);
334         if (ret)
335                 return -1;
336
337         connection->in.head += len;
338
339         return connection->in.head - connection->in.tail;
340 }
341
342 int
343 wl_connection_write(struct wl_connection *connection,
344                     const void *data, size_t count)
345 {
346         if (connection->out.head - connection->out.tail +
347             count > ARRAY_LENGTH(connection->out.data)) {
348                 connection->want_flush = 1;
349                 if (wl_connection_flush(connection) < 0)
350                         return -1;
351         }
352
353         wl_buffer_put(&connection->out, data, count);
354         connection->want_flush = 1;
355
356         return 0;
357 }
358
359 int
360 wl_connection_queue(struct wl_connection *connection,
361                     const void *data, size_t count)
362 {
363         if (connection->out.head - connection->out.tail +
364             count > ARRAY_LENGTH(connection->out.data)) {
365                 connection->want_flush = 1;
366                 if (wl_connection_flush(connection) < 0)
367                         return -1;
368         }
369
370         wl_buffer_put(&connection->out, data, count);
371
372         return 0;
373 }
374
375 static int
376 wl_message_count_arrays(const struct wl_message *message)
377 {
378         int i, arrays;
379
380         for (i = 0, arrays = 0; message->signature[i]; i++) {
381                 if (message->signature[i] == 'a')
382                         arrays++;
383         }
384
385         return arrays;
386 }
387
388 static int
389 wl_connection_put_fd(struct wl_connection *connection, int32_t fd)
390 {
391         if (wl_buffer_size(&connection->fds_out) == MAX_FDS_OUT * sizeof fd) {
392                 connection->want_flush = 1;
393                 if (wl_connection_flush(connection) < 0)
394                         return -1;
395         }
396
397         wl_buffer_put(&connection->fds_out, &fd, sizeof fd);
398
399         return 0;
400 }
401
402 const char *
403 get_next_argument(const char *signature, struct argument_details *details)
404 {
405         if (*signature == '?') {
406                 details->nullable = 1;
407                 signature++;
408         } else
409                 details->nullable = 0;
410
411         details->type = *signature;
412         return signature + 1;
413 }
414
415 int
416 arg_count_for_signature(const char *signature)
417 {
418         int count = 0;
419         while (*signature) {
420                 if (*signature != '?')
421                         count++;
422                 signature++;
423         }
424         return count;
425 }
426
427 void
428 wl_argument_from_va_list(const char *signature, union wl_argument *args,
429                          int count, va_list ap)
430 {
431         int i;
432         const char *sig_iter;
433         struct argument_details arg;
434
435         sig_iter = signature;
436         for (i = 0; i < count; i++) {
437                 sig_iter = get_next_argument(sig_iter, &arg);
438
439                 switch(arg.type) {
440                 case 'i':
441                         args[i].i = va_arg(ap, int32_t);
442                         break;
443                 case 'u':
444                         args[i].u = va_arg(ap, uint32_t);
445                         break;
446                 case 'f':
447                         args[i].f = va_arg(ap, wl_fixed_t);
448                         break;
449                 case 's':
450                         args[i].s = va_arg(ap, const char *);
451                         break;
452                 case 'o':
453                         args[i].o = va_arg(ap, struct wl_object *);
454                         break;
455                 case 'n':
456                         args[i].o = va_arg(ap, struct wl_object *);
457                         break;
458                 case 'a':
459                         args[i].a = va_arg(ap, struct wl_array *);
460                         break;
461                 case 'h':
462                         args[i].h = va_arg(ap, int32_t);
463                         break;
464                 case '\0':
465                         return;
466                 }
467         }
468 }
469
470 struct wl_closure *
471 wl_closure_marshal(struct wl_object *sender, uint32_t opcode,
472                    union wl_argument *args,
473                    const struct wl_message *message)
474 {
475         struct wl_closure *closure;
476         struct wl_object *object;
477         int i, count, fd, dup_fd;
478         const char *signature;
479         struct argument_details arg;
480
481         count = arg_count_for_signature(message->signature);
482         if (count > WL_CLOSURE_MAX_ARGS) {
483                 printf("too many args (%d)\n", count);
484                 errno = EINVAL;
485                 return NULL;
486         }
487
488         closure = malloc(sizeof *closure);
489         if (closure == NULL) {
490                 errno = ENOMEM;
491                 return NULL;
492         }
493
494         memcpy(closure->args, args, count * sizeof *args);
495
496         signature = message->signature;
497         for (i = 0; i < count; i++) {
498                 signature = get_next_argument(signature, &arg);
499
500                 switch (arg.type) {
501                 case 'f':
502                 case 'u':
503                 case 'i':
504                         break;
505                 case 's':
506                         if (!arg.nullable && args[i].s == NULL)
507                                 goto err_null;
508                         break;
509                 case 'o':
510                         if (!arg.nullable && args[i].o == NULL)
511                                 goto err_null;
512                         break;
513                 case 'n':
514                         object = args[i].o;
515                         if (!arg.nullable && object == NULL)
516                                 goto err_null;
517
518                         closure->args[i].n = object ? object->id : 0;
519                         break;
520                 case 'a':
521                         if (!arg.nullable && args[i].a == NULL)
522                                 goto err_null;
523                         break;
524                 case 'h':
525                         fd = args[i].h;
526                         dup_fd = wl_os_dupfd_cloexec(fd, 0);
527                         if (dup_fd < 0) {
528                                 fprintf(stderr, "dup failed: %m");
529                                 abort();
530                         }
531                         closure->args[i].h = dup_fd;
532                         break;
533                 default:
534                         fprintf(stderr, "unhandled format code: '%c'\n",
535                                 arg.type);
536                         assert(0);
537                         break;
538                 }
539         }
540
541         closure->sender_id = sender->id;
542         closure->opcode = opcode;
543         closure->message = message;
544         closure->count = count;
545
546         return closure;
547
548 err_null:
549         wl_closure_destroy(closure);
550         wl_log("error marshalling arguments for %s (signature %s): "
551                "null value passed for arg %i\n", message->name,
552                message->signature, i);
553         errno = EINVAL;
554         return NULL;
555 }
556
557 struct wl_closure *
558 wl_closure_vmarshal(struct wl_object *sender, uint32_t opcode, va_list ap,
559                     const struct wl_message *message)
560 {
561         union wl_argument args[WL_CLOSURE_MAX_ARGS];
562
563         wl_argument_from_va_list(message->signature, args,
564                                  WL_CLOSURE_MAX_ARGS, ap);
565
566         return wl_closure_marshal(sender, opcode, args, message);
567 }
568
569 struct wl_closure *
570 wl_connection_demarshal(struct wl_connection *connection,
571                         uint32_t size,
572                         struct wl_map *objects,
573                         const struct wl_message *message)
574 {
575         uint32_t *p, *next, *end, length, id;
576         int fd;
577         char *s;
578         unsigned int i, count, num_arrays;
579         const char *signature;
580         struct argument_details arg;
581         struct wl_closure *closure;
582         struct wl_array *array, *array_extra;
583
584         count = arg_count_for_signature(message->signature);
585         if (count > WL_CLOSURE_MAX_ARGS) {
586                 printf("too many args (%d)\n", count);
587                 errno = EINVAL;
588                 wl_connection_consume(connection, size);
589                 return NULL;
590         }
591
592         num_arrays = wl_message_count_arrays(message);
593         closure = malloc(sizeof *closure + size + num_arrays * sizeof *array);
594         if (closure == NULL) {
595                 errno = ENOMEM;
596                 wl_connection_consume(connection, size);
597                 return NULL;
598         }
599
600         array_extra = closure->extra;
601         p = (uint32_t *)(closure->extra + num_arrays);
602         end = p + size / sizeof *p;
603
604         wl_connection_copy(connection, p, size);
605         closure->sender_id = *p++;
606         closure->opcode = *p++ & 0x0000ffff;
607
608         signature = message->signature;
609         for (i = 0; i < count; i++) {
610                 signature = get_next_argument(signature, &arg);
611
612                 if (arg.type != 'h' && p + 1 > end) {
613                         printf("message too short, "
614                                "object (%d), message %s(%s)\n",
615                                *p, message->name, message->signature);
616                         errno = EINVAL;
617                         goto err;
618                 }
619
620                 switch (arg.type) {
621                 case 'u':
622                         closure->args[i].u = *p++;
623                         break;
624                 case 'i':
625                         closure->args[i].i = *p++;
626                         break;
627                 case 'f':
628                         closure->args[i].f = *p++;
629                         break;
630                 case 's':
631                         length = *p++;
632
633                         if (length == 0) {
634                                 closure->args[i].s = NULL;
635                                 break;
636                         }
637
638                         next = p + DIV_ROUNDUP(length, sizeof *p);
639                         if (next > end) {
640                                 printf("message too short, "
641                                        "object (%d), message %s(%s)\n",
642                                        closure->sender_id, message->name,
643                                        message->signature);
644                                 errno = EINVAL;
645                                 goto err;
646                         }
647
648                         s = (char *) p;
649
650                         if (length > 0 && s[length - 1] != '\0') {
651                                 printf("string not nul-terminated, "
652                                        "message %s(%s)\n",
653                                        message->name, message->signature);
654                                 errno = EINVAL;
655                                 goto err;
656                         }
657
658                         closure->args[i].s = s;
659                         p = next;
660                         break;
661                 case 'o':
662                         id = *p++;
663                         closure->args[i].n = id;
664
665                         if (id == 0 && !arg.nullable) {
666                                 printf("NULL object received on non-nullable "
667                                        "type, message %s(%s)\n", message->name,
668                                        message->signature);
669                                 errno = EINVAL;
670                                 goto err;
671                         }
672                         break;
673                 case 'n':
674                         id = *p++;
675                         closure->args[i].n = id;
676
677                         if (id == 0 && !arg.nullable) {
678                                 printf("NULL new ID received on non-nullable "
679                                        "type, message %s(%s)\n", message->name,
680                                        message->signature);
681                                 errno = EINVAL;
682                                 goto err;
683                         }
684
685                         if (wl_map_reserve_new(objects, id) < 0) {
686                                 printf("not a valid new object id (%d), "
687                                        "message %s(%s)\n",
688                                        id, message->name, message->signature);
689                                 errno = EINVAL;
690                                 goto err;
691                         }
692
693                         break;
694                 case 'a':
695                         length = *p++;
696
697                         next = p + DIV_ROUNDUP(length, sizeof *p);
698                         if (next > end) {
699                                 printf("message too short, "
700                                        "object (%d), message %s(%s)\n",
701                                        closure->sender_id, message->name,
702                                        message->signature);
703                                 errno = EINVAL;
704                                 goto err;
705                         }
706
707                         array_extra->size = length;
708                         array_extra->alloc = 0;
709                         array_extra->data = p;
710
711                         closure->args[i].a = array_extra++;
712                         p = next;
713                         break;
714                 case 'h':
715                         wl_buffer_copy(&connection->fds_in, &fd, sizeof fd);
716                         connection->fds_in.tail += sizeof fd;
717                         closure->args[i].h = fd;
718                         break;
719                 default:
720                         printf("unknown type\n");
721                         assert(0);
722                         break;
723                 }
724         }
725
726         closure->count = count;
727         closure->message = message;
728
729         wl_connection_consume(connection, size);
730
731         return closure;
732
733  err:
734         wl_closure_destroy(closure);
735         wl_connection_consume(connection, size);
736
737         return NULL;
738 }
739
740 static int
741 interface_equal(const struct wl_interface *a, const struct wl_interface *b)
742 {
743         /* In most cases the pointer equality test is sufficient.
744          * However, in some cases, depending on how things are split
745          * across shared objects, we can end up with multiple
746          * instances of the interface metadata constants.  So if the
747          * pointers match, the interfaces are equal, if they don't
748          * match we have to compare the interface names. */
749
750         return a == b || strcmp(a->name, b->name) == 0;
751 }
752
753 int
754 wl_closure_lookup_objects(struct wl_closure *closure, struct wl_map *objects)
755 {
756         struct wl_object *object;
757         const struct wl_message *message;
758         const char *signature;
759         struct argument_details arg;
760         int i, count;
761         uint32_t id;
762
763         message = closure->message;
764         signature = message->signature;
765         count = arg_count_for_signature(signature);
766         for (i = 0; i < count; i++) {
767                 signature = get_next_argument(signature, &arg);
768                 switch (arg.type) {
769                 case 'o':
770                         id = closure->args[i].n;
771                         closure->args[i].o = NULL;
772
773                         object = wl_map_lookup(objects, id);
774                         if (object == WL_ZOMBIE_OBJECT) {
775                                 /* references object we've already
776                                  * destroyed client side */
777                                 object = NULL;
778                         } else if (object == NULL && id != 0) {
779                                 printf("unknown object (%u), message %s(%s)\n",
780                                        id, message->name, message->signature);
781                                 object = NULL;
782                                 errno = EINVAL;
783                                 return -1;
784                         }
785
786                         if (object != NULL && message->types[i] != NULL &&
787                             !interface_equal((object)->interface,
788                                              message->types[i])) {
789                                 printf("invalid object (%u), type (%s), "
790                                        "message %s(%s)\n",
791                                        id, (object)->interface->name,
792                                        message->name, message->signature);
793                                 errno = EINVAL;
794                                 return -1;
795                         }
796                         closure->args[i].o = object;
797                 }
798         }
799
800         return 0;
801 }
802
803 static void
804 convert_arguments_to_ffi(const char *signature, union wl_argument *args,
805                          int count, ffi_type **ffi_types, void** ffi_args)
806 {
807         int i;
808         const char *sig_iter;
809         struct argument_details arg;
810
811         sig_iter = signature;
812         for (i = 0; i < count; i++) {
813                 sig_iter = get_next_argument(sig_iter, &arg);
814
815                 switch(arg.type) {
816                 case 'i':
817                         ffi_types[i] = &ffi_type_sint32;
818                         ffi_args[i] = &args[i].i;
819                         break;
820                 case 'u':
821                         ffi_types[i] = &ffi_type_uint32;
822                         ffi_args[i] = &args[i].u;
823                         break;
824                 case 'f':
825                         ffi_types[i] = &ffi_type_sint32;
826                         ffi_args[i] = &args[i].f;
827                         break;
828                 case 's':
829                         ffi_types[i] = &ffi_type_pointer;
830                         ffi_args[i] = &args[i].s;
831                         break;
832                 case 'o':
833                         ffi_types[i] = &ffi_type_pointer;
834                         ffi_args[i] = &args[i].o;
835                         break;
836                 case 'n':
837                         ffi_types[i] = &ffi_type_uint32;
838                         ffi_args[i] = &args[i].n;
839                         break;
840                 case 'a':
841                         ffi_types[i] = &ffi_type_pointer;
842                         ffi_args[i] = &args[i].a;
843                         break;
844                 case 'h':
845                         ffi_types[i] = &ffi_type_sint32;
846                         ffi_args[i] = &args[i].h;
847                         break;
848                 default:
849                         printf("unknown type\n");
850                         assert(0);
851                         break;
852                 }
853         }
854 }
855
856
857 void
858 wl_closure_invoke(struct wl_closure *closure,
859                   struct wl_object *target, void (*func)(void), void *data)
860 {
861         int count;
862         ffi_cif cif;
863         ffi_type *ffi_types[WL_CLOSURE_MAX_ARGS + 2];
864         void * ffi_args[WL_CLOSURE_MAX_ARGS + 2];
865
866         count = arg_count_for_signature(closure->message->signature);
867
868         ffi_types[0] = &ffi_type_pointer;
869         ffi_args[0] = &data;
870         ffi_types[1] = &ffi_type_pointer;
871         ffi_args[1] = &target;
872
873         convert_arguments_to_ffi(closure->message->signature, closure->args,
874                                  count, ffi_types + 2, ffi_args + 2);
875
876         ffi_prep_cif(&cif, FFI_DEFAULT_ABI,
877                      count + 2, &ffi_type_void, ffi_types);
878
879         ffi_call(&cif, func, NULL, ffi_args);
880 }
881
882 static int
883 copy_fds_to_connection(struct wl_closure *closure,
884                        struct wl_connection *connection)
885 {
886         const struct wl_message *message = closure->message;
887         uint32_t i, count;
888         struct argument_details arg;
889         const char *signature = message->signature;
890         int fd;
891
892         count = arg_count_for_signature(signature);
893         for (i = 0; i < count; i++) {
894                 signature = get_next_argument(signature, &arg);
895                 if (arg.type != 'h')
896                         continue;
897
898                 fd = closure->args[i].h;
899                 if (wl_connection_put_fd(connection, fd)) {
900                         fprintf(stderr, "request could not be marshaled: "
901                                 "can't send file descriptor");
902                         return -1;
903                 }
904         }
905
906         return 0;
907 }
908
909 static int
910 serialize_closure(struct wl_closure *closure, uint32_t *buffer,
911                   size_t buffer_count)
912 {
913         const struct wl_message *message = closure->message;
914         unsigned int i, count, size;
915         uint32_t *p, *end;
916         struct argument_details arg;
917         const char *signature;
918
919         if (buffer_count < 2)
920                 goto overflow;
921
922         p = buffer + 2;
923         end = buffer + buffer_count;
924
925         signature = message->signature;
926         count = arg_count_for_signature(signature);
927         for (i = 0; i < count; i++) {
928                 signature = get_next_argument(signature, &arg);
929
930                 if (arg.type == 'h')
931                         continue;
932
933                 if (p + 1 > end)
934                         goto overflow;
935
936                 switch (arg.type) {
937                 case 'u':
938                         *p++ = closure->args[i].u;
939                         break;
940                 case 'i':
941                         *p++ = closure->args[i].i;
942                         break;
943                 case 'f':
944                         *p++ = closure->args[i].f;
945                         break;
946                 case 'o':
947                         *p++ = closure->args[i].o ? closure->args[i].o->id : 0;
948                         break;
949                 case 'n':
950                         *p++ = closure->args[i].n;
951                         break;
952                 case 's':
953                         if (closure->args[i].s == NULL) {
954                                 *p++ = 0;
955                                 break;
956                         }
957
958                         size = strlen(closure->args[i].s) + 1;
959                         *p++ = size;
960
961                         if (p + DIV_ROUNDUP(size, sizeof *p) > end)
962                                 goto overflow;
963
964                         memcpy(p, closure->args[i].s, size);
965                         p += DIV_ROUNDUP(size, sizeof *p);
966                         break;
967                 case 'a':
968                         if (closure->args[i].a == NULL) {
969                                 *p++ = 0;
970                                 break;
971                         }
972
973                         size = closure->args[i].a->size;
974                         *p++ = size;
975
976                         if (p + DIV_ROUNDUP(size, sizeof *p) > end)
977                                 goto overflow;
978
979                         memcpy(p, closure->args[i].a->data, size);
980                         p += DIV_ROUNDUP(size, sizeof *p);
981                         break;
982                 default:
983                         break;
984                 }
985         }
986
987         size = (p - buffer) * sizeof *p;
988
989         buffer[0] = closure->sender_id;
990         buffer[1] = size << 16 | (closure->opcode & 0x0000ffff);
991
992         return size;
993
994 overflow:
995         errno = ERANGE;
996         return -1;
997 }
998
999 int
1000 wl_closure_send(struct wl_closure *closure, struct wl_connection *connection)
1001 {
1002         uint32_t buffer[256];
1003         int size;
1004
1005         if (copy_fds_to_connection(closure, connection))
1006                 return -1;
1007
1008         size = serialize_closure(closure, buffer, 256);
1009         if (size < 0)
1010                 return -1;
1011
1012         return wl_connection_write(connection, buffer, size);
1013 }
1014
1015 int
1016 wl_closure_queue(struct wl_closure *closure, struct wl_connection *connection)
1017 {
1018         uint32_t buffer[256];
1019         int size;
1020
1021         if (copy_fds_to_connection(closure, connection))
1022                 return -1;
1023
1024         size = serialize_closure(closure, buffer, 256);
1025         if (size < 0)
1026                 return -1;
1027
1028         return wl_connection_queue(connection, buffer, size);
1029 }
1030
1031 void
1032 wl_closure_print(struct wl_closure *closure, struct wl_object *target, int send)
1033 {
1034         int i;
1035         struct argument_details arg;
1036         const char *signature = closure->message->signature;
1037         struct timespec tp;
1038         unsigned int time;
1039
1040         clock_gettime(CLOCK_REALTIME, &tp);
1041         time = (tp.tv_sec * 1000000L) + (tp.tv_nsec / 1000);
1042
1043         fprintf(stderr, "[%10.3f] %s%s@%u.%s(",
1044                 time / 1000.0,
1045                 send ? " -> " : "",
1046                 target->interface->name, target->id,
1047                 closure->message->name);
1048
1049         for (i = 0; i < closure->count; i++) {
1050                 signature = get_next_argument(signature, &arg);
1051                 if (i > 0)
1052                         fprintf(stderr, ", ");
1053
1054                 switch (arg.type) {
1055                 case 'u':
1056                         fprintf(stderr, "%u", closure->args[i].u);
1057                         break;
1058                 case 'i':
1059                         fprintf(stderr, "%d", closure->args[i].i);
1060                         break;
1061                 case 'f':
1062                         fprintf(stderr, "%f",
1063                                 wl_fixed_to_double(closure->args[i].f));
1064                         break;
1065                 case 's':
1066                         fprintf(stderr, "\"%s\"", closure->args[i].s);
1067                         break;
1068                 case 'o':
1069                         if (closure->args[i].o)
1070                                 fprintf(stderr, "%s@%u",
1071                                         closure->args[i].o->interface->name,
1072                                         closure->args[i].o->id);
1073                         else
1074                                 fprintf(stderr, "nil");
1075                         break;
1076                 case 'n':
1077                         fprintf(stderr, "new id %s@",
1078                                 (closure->message->types[i]) ?
1079                                  closure->message->types[i]->name :
1080                                   "[unknown]");
1081                         if (closure->args[i].n != 0)
1082                                 fprintf(stderr, "%u", closure->args[i].n);
1083                         else
1084                                 fprintf(stderr, "nil");
1085                         break;
1086                 case 'a':
1087                         fprintf(stderr, "array");
1088                         break;
1089                 case 'h':
1090                         fprintf(stderr, "fd %d", closure->args[i].h);
1091                         break;
1092                 }
1093         }
1094
1095         fprintf(stderr, ")\n");
1096 }
1097
1098 void
1099 wl_closure_destroy(struct wl_closure *closure)
1100 {
1101         free(closure);
1102 }