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