client: Don't forget to init and destroy mutex
[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         int 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         int 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         int 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         int 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         int 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 int
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 void
171 wl_connection_destroy(struct wl_connection *connection)
172 {
173         close(connection->fd);
174         free(connection);
175 }
176
177 void
178 wl_connection_copy(struct wl_connection *connection, void *data, size_t size)
179 {
180         wl_buffer_copy(&connection->in, data, size);
181 }
182
183 void
184 wl_connection_consume(struct wl_connection *connection, size_t size)
185 {
186         connection->in.tail += size;
187 }
188
189 static void
190 build_cmsg(struct wl_buffer *buffer, char *data, int *clen)
191 {
192         struct cmsghdr *cmsg;
193         size_t size;
194
195         size = buffer->head - buffer->tail;
196         if (size > 0) {
197                 cmsg = (struct cmsghdr *) data;
198                 cmsg->cmsg_level = SOL_SOCKET;
199                 cmsg->cmsg_type = SCM_RIGHTS;
200                 cmsg->cmsg_len = CMSG_LEN(size);
201                 wl_buffer_copy(buffer, CMSG_DATA(cmsg), size);
202                 *clen = cmsg->cmsg_len;
203         } else {
204                 *clen = 0;
205         }
206 }
207
208 static void
209 close_fds(struct wl_buffer *buffer)
210 {
211         int fds[MAX_FDS_OUT], i, count;
212         size_t size;
213
214         size = buffer->head - buffer->tail;
215         if (size == 0)
216                 return;
217
218         wl_buffer_copy(buffer, fds, size);
219         count = size / sizeof fds[0];
220         for (i = 0; i < count; i++)
221                 close(fds[i]);
222         buffer->tail += size;
223 }
224
225 static void
226 decode_cmsg(struct wl_buffer *buffer, struct msghdr *msg)
227 {
228         struct cmsghdr *cmsg;
229         size_t size;
230
231         for (cmsg = CMSG_FIRSTHDR(msg); cmsg != NULL;
232              cmsg = CMSG_NXTHDR(msg, cmsg)) {
233                 if (cmsg->cmsg_level == SOL_SOCKET &&
234                     cmsg->cmsg_type == SCM_RIGHTS) {
235                         size = cmsg->cmsg_len - CMSG_LEN(0);
236                         wl_buffer_put(buffer, CMSG_DATA(cmsg), size);
237                 }
238         }
239 }
240
241 int
242 wl_connection_flush(struct wl_connection *connection)
243 {
244         struct iovec iov[2];
245         struct msghdr msg;
246         char cmsg[CLEN];
247         int len = 0, count, clen;
248         uint32_t tail;
249
250         if (!connection->want_flush)
251                 return 0;
252
253         tail = connection->out.tail;
254         while (connection->out.head - connection->out.tail > 0) {
255                 wl_buffer_get_iov(&connection->out, iov, &count);
256
257                 build_cmsg(&connection->fds_out, cmsg, &clen);
258
259                 msg.msg_name = NULL;
260                 msg.msg_namelen = 0;
261                 msg.msg_iov = iov;
262                 msg.msg_iovlen = count;
263                 msg.msg_control = cmsg;
264                 msg.msg_controllen = clen;
265                 msg.msg_flags = 0;
266
267                 do {
268                         len = sendmsg(connection->fd, &msg,
269                                       MSG_NOSIGNAL | MSG_DONTWAIT);
270                 } while (len == -1 && errno == EINTR);
271
272                 if (len == -1)
273                         return -1;
274
275                 close_fds(&connection->fds_out);
276
277                 connection->out.tail += len;
278         }
279
280         connection->want_flush = 0;
281
282         return connection->out.head - tail;
283 }
284
285 int
286 wl_connection_read(struct wl_connection *connection)
287 {
288         struct iovec iov[2];
289         struct msghdr msg;
290         char cmsg[CLEN];
291         int len, count;
292
293         wl_buffer_put_iov(&connection->in, iov, &count);
294
295         msg.msg_name = NULL;
296         msg.msg_namelen = 0;
297         msg.msg_iov = iov;
298         msg.msg_iovlen = count;
299         msg.msg_control = cmsg;
300         msg.msg_controllen = sizeof cmsg;
301         msg.msg_flags = 0;
302
303         do {
304                 len = wl_os_recvmsg_cloexec(connection->fd, &msg, 0);
305         } while (len < 0 && errno == EINTR);
306
307         if (len <= 0)
308                 return len;
309
310         decode_cmsg(&connection->fds_in, &msg);
311
312         connection->in.head += len;
313
314         return connection->in.head - connection->in.tail;
315 }
316
317 int
318 wl_connection_write(struct wl_connection *connection,
319                     const void *data, size_t count)
320 {
321         if (connection->out.head - connection->out.tail +
322             count > ARRAY_LENGTH(connection->out.data)) {
323                 connection->want_flush = 1;
324                 if (wl_connection_flush(connection) < 0)
325                         return -1;
326         }
327
328         wl_buffer_put(&connection->out, data, count);
329         connection->want_flush = 1;
330
331         return 0;
332 }
333
334 int
335 wl_connection_queue(struct wl_connection *connection,
336                     const void *data, size_t count)
337 {
338         if (connection->out.head - connection->out.tail +
339             count > ARRAY_LENGTH(connection->out.data)) {
340                 connection->want_flush = 1;
341                 if (wl_connection_flush(connection) < 0)
342                         return -1;
343         }
344
345         wl_buffer_put(&connection->out, data, count);
346
347         return 0;
348 }
349
350 static int
351 wl_message_size_extra(const struct wl_message *message)
352 {
353         int i, extra;
354
355         for (i = 0, extra = 0; message->signature[i]; i++) {
356
357                 switch (message->signature[i]) {
358                 case 's':
359                 case 'o':
360                 case 'n':
361                         extra += sizeof (void *);
362                         break;
363                 case 'a':
364                         extra += sizeof (void *) + sizeof (struct wl_array);
365                         break;
366                 case 'h':
367                         extra += sizeof (int);
368                         break;
369                 default:
370                         break;
371                 }
372         }
373
374         return extra;
375 }
376
377 static int
378 wl_connection_put_fd(struct wl_connection *connection, int32_t fd)
379 {
380         if (wl_buffer_size(&connection->fds_out) == MAX_FDS_OUT * sizeof fd) {
381                 connection->want_flush = 1;
382                 if (wl_connection_flush(connection) < 0)
383                         return -1;
384         }
385
386         wl_buffer_put(&connection->fds_out, &fd, sizeof fd);
387
388         return 0;
389 }
390
391 const char *
392 get_next_argument(const char *signature, struct argument_details *details)
393 {
394         if (*signature == '?') {
395                 details->nullable = 1;
396                 signature++;
397         } else
398                 details->nullable = 0;
399
400         details->type = *signature;
401         return signature + 1;
402 }
403
404 int
405 arg_count_for_signature(const char *signature)
406 {
407         int count = 0;
408         while (*signature) {
409                 if (*signature != '?')
410                         count++;
411                 signature++;
412         }
413         return count;
414 }
415
416 struct wl_closure *
417 wl_closure_vmarshal(struct wl_object *sender,
418                     uint32_t opcode, va_list ap,
419                     const struct wl_message *message)
420 {
421         struct wl_closure *closure;
422         struct wl_object **objectp, *object;
423         uint32_t length, aligned, *p, *start, size, *end;
424         int dup_fd;
425         struct wl_array **arrayp, *array;
426         const char **sp, *s;
427         const char *signature = message->signature;
428         struct argument_details arg;
429         char *extra;
430         int i, count, fd, extra_size, *fd_ptr;
431
432         /* FIXME: Match old fixed allocation for now */
433         closure = malloc(sizeof *closure + 1024);
434         if (closure == NULL)
435                 return NULL;
436
437         extra_size = wl_message_size_extra(message);
438         count = arg_count_for_signature(signature) + 2;
439         extra = (char *) closure->buffer;
440         start = &closure->buffer[DIV_ROUNDUP(extra_size, sizeof *p)];
441         end = &closure->buffer[256];
442         p = &start[2];
443
444         closure->types[0] = &ffi_type_pointer;
445         closure->types[1] = &ffi_type_pointer;
446
447         for (i = 2; i < count; i++) {
448                 signature = get_next_argument(signature, &arg);
449
450                 switch (arg.type) {
451                 case 'f':
452                         closure->types[i] = &ffi_type_sint32;
453                         closure->args[i] = p;
454                         if (end - p < 1)
455                                 goto err;
456                         *p++ = va_arg(ap, wl_fixed_t);
457                         break;
458                 case 'u':
459                         closure->types[i] = &ffi_type_uint32;
460                         closure->args[i] = p;
461                         if (end - p < 1)
462                                 goto err;
463                         *p++ = va_arg(ap, uint32_t);
464                         break;
465                 case 'i':
466                         closure->types[i] = &ffi_type_sint32;
467                         closure->args[i] = p;
468                         if (end - p < 1)
469                                 goto err;
470                         *p++ = va_arg(ap, int32_t);
471                         break;
472                 case 's':
473                         closure->types[i] = &ffi_type_pointer;
474                         closure->args[i] = extra;
475                         sp = (const char **) extra;
476                         extra += sizeof *sp;
477
478                         s = va_arg(ap, const char *);
479
480                         if (!arg.nullable && s == NULL)
481                                 goto err_null;
482
483                         length = s ? strlen(s) + 1: 0;
484                         aligned = (length + 3) & ~3;
485                         if (p + aligned / sizeof *p + 1 > end)
486                                 goto err;
487                         *p++ = length;
488
489                         if (length > 0)
490                                 *sp = (const char *) p;
491                         else
492                                 *sp = NULL;
493
494                         memcpy(p, s, length);
495                         memset((char *) p + length, 0, aligned - length);
496                         p += aligned / sizeof *p;
497                         break;
498                 case 'o':
499                         closure->types[i] = &ffi_type_pointer;
500                         closure->args[i] = extra;
501                         objectp = (struct wl_object **) extra;
502                         extra += sizeof *objectp;
503
504                         object = va_arg(ap, struct wl_object *);
505
506                         if (!arg.nullable && object == NULL)
507                                 goto err_null;
508
509                         *objectp = object;
510                         if (end - p < 1)
511                                 goto err;
512                         *p++ = object ? object->id : 0;
513                         break;
514
515                 case 'n':
516                         closure->types[i] = &ffi_type_uint32;
517                         closure->args[i] = p;
518                         object = va_arg(ap, struct wl_object *);
519                         if (end - p < 1)
520                                 goto err;
521
522                         if (!arg.nullable && object == NULL)
523                                 goto err_null;
524
525                         *p++ = object ? object->id : 0;
526                         break;
527
528                 case 'a':
529                         closure->types[i] = &ffi_type_pointer;
530                         closure->args[i] = extra;
531                         arrayp = (struct wl_array **) extra;
532                         extra += sizeof *arrayp;
533
534                         *arrayp = (struct wl_array *) extra;
535                         extra += sizeof **arrayp;
536
537                         array = va_arg(ap, struct wl_array *);
538
539                         if (!arg.nullable && array == NULL)
540                                 goto err_null;
541
542                         if (array == NULL || array->size == 0) {
543                                 if (end - p < 1)
544                                         goto err;
545                                 *p++ = 0;
546                                 break;
547                         }
548                         if (p + DIV_ROUNDUP(array->size, sizeof *p) + 1 > end)
549                                 goto err;
550                         *p++ = array->size;
551                         memcpy(p, array->data, array->size);
552
553                         (*arrayp)->size = array->size;
554                         (*arrayp)->alloc = array->alloc;
555                         (*arrayp)->data = p;
556
557                         p += DIV_ROUNDUP(array->size, sizeof *p);
558                         break;
559
560                 case 'h':
561                         closure->types[i] = &ffi_type_sint;
562                         closure->args[i] = extra;
563                         fd_ptr = (int *) extra;
564                         extra += sizeof *fd_ptr;
565
566                         fd = va_arg(ap, int);
567                         dup_fd = wl_os_dupfd_cloexec(fd, 0);
568                         if (dup_fd < 0) {
569                                 fprintf(stderr, "dup failed: %m");
570                                 abort();
571                         }
572                         *fd_ptr = dup_fd;
573                         break;
574                 default:
575                         fprintf(stderr, "unhandled format code: '%c'\n",
576                                 arg.type);
577                         assert(0);
578                         break;
579                 }
580         }
581
582         size = (p - start) * sizeof *p;
583         start[0] = sender->id;
584         start[1] = opcode | (size << 16);
585
586         closure->start = start;
587         closure->message = message;
588         closure->count = count;
589
590         ffi_prep_cif(&closure->cif, FFI_DEFAULT_ABI,
591                      closure->count, &ffi_type_void, closure->types);
592
593         return closure;
594
595 err:
596         printf("request too big to marshal, maximum size is %zu\n",
597                sizeof closure->buffer);
598         errno = ENOMEM;
599         free(closure);
600
601         return NULL;
602
603 err_null:
604         free(closure);
605         wl_log("error marshalling arguments for %s:%i.%s (signature %s): "
606                "null value passed for arg %i\n",
607                sender->interface->name, sender->id, message->name,
608                message->signature, i);
609         errno = EINVAL;
610         return NULL;
611 }
612
613 struct wl_closure *
614 wl_connection_demarshal(struct wl_connection *connection,
615                         uint32_t size,
616                         struct wl_map *objects,
617                         const struct wl_message *message)
618 {
619         uint32_t *p, *next, *end, length, **id;
620         int *fd;
621         char *extra, **s;
622         unsigned int i, count, extra_space;
623         const char *signature = message->signature;
624         struct argument_details arg;
625         struct wl_object **object;
626         struct wl_array **array;
627         struct wl_closure *closure;
628
629         count = arg_count_for_signature(signature) + 2;
630         if (count > ARRAY_LENGTH(closure->types)) {
631                 printf("too many args (%d)\n", count);
632                 errno = EINVAL;
633                 wl_connection_consume(connection, size);
634                 return NULL;
635         }
636
637         extra_space = wl_message_size_extra(message);
638         closure = malloc(sizeof *closure + 8 + size + extra_space);
639         if (closure == NULL)
640                 return NULL;
641
642         closure->message = message;
643         closure->types[0] = &ffi_type_pointer;
644         closure->types[1] = &ffi_type_pointer;
645         closure->start = closure->buffer;
646
647         wl_connection_copy(connection, closure->buffer, size);
648         p = &closure->buffer[2];
649         end = (uint32_t *) ((char *) p + size);
650         extra = (char *) end;
651         for (i = 2; i < count; i++) {
652                 signature = get_next_argument(signature, &arg);
653
654                 if (p + 1 > end) {
655                         printf("message too short, "
656                                "object (%d), message %s(%s)\n",
657                                *p, message->name, message->signature);
658                         errno = EINVAL;
659                         goto err;
660                 }
661
662                 switch (arg.type) {
663                 case 'u':
664                         closure->types[i] = &ffi_type_uint32;
665                         closure->args[i] = p++;
666                         break;
667                 case 'i':
668                         closure->types[i] = &ffi_type_sint32;
669                         closure->args[i] = p++;
670                         break;
671                 case 'f':
672                         closure->types[i] = &ffi_type_sint32;
673                         closure->args[i] = p++;
674                         break;
675                 case 's':
676                         closure->types[i] = &ffi_type_pointer;
677                         length = *p++;
678
679                         next = p + DIV_ROUNDUP(length, sizeof *p);
680                         if (next > end) {
681                                 printf("message too short, "
682                                        "object (%d), message %s(%s)\n",
683                                        *p, message->name, message->signature);
684                                 errno = EINVAL;
685                                 goto err;
686                         }
687
688                         s = (char **) extra;
689                         extra += sizeof *s;
690                         closure->args[i] = s;
691
692                         if (length == 0) {
693                                 *s = NULL;
694                         } else {
695                                 *s = (char *) p;
696                         }
697
698                         if (length > 0 && (*s)[length - 1] != '\0') {
699                                 printf("string not nul-terminated, "
700                                        "message %s(%s)\n",
701                                        message->name, message->signature);
702                                 errno = EINVAL;
703                                 goto err;
704                         }
705                         p = next;
706                         break;
707                 case 'o':
708                         closure->types[i] = &ffi_type_pointer;
709                         id = (uint32_t **) extra;
710                         extra += sizeof *id;
711                         closure->args[i] = id;
712                         *id = p;
713
714                         if (*id == 0 && !arg.nullable) {
715                                 printf("NULL object received on non-nullable "
716                                        "type, message %s(%s)\n", message->name,
717                                        message->signature);
718                                 *object = NULL;
719                                 errno = EINVAL;
720                                 goto err;
721                         }
722
723                         p++;
724                         break;
725                 case 'n':
726                         closure->types[i] = &ffi_type_pointer;
727                         id = (uint32_t **) extra;
728                         extra += sizeof *id;
729                         closure->args[i] = id;
730                         *id = p;
731
732                         if (*id == 0 && !arg.nullable) {
733                                 printf("NULL new ID received on non-nullable "
734                                        "type, message %s(%s)\n", message->name,
735                                        message->signature);
736                                 errno = EINVAL;
737                                 goto err;
738                         }
739
740                         if (wl_map_reserve_new(objects, *p) < 0) {
741                                 printf("not a valid new object id (%d), "
742                                        "message %s(%s)\n",
743                                        *p, message->name, message->signature);
744                                 errno = EINVAL;
745                                 goto err;
746                         }
747
748                         p++;
749                         break;
750                 case 'a':
751                         closure->types[i] = &ffi_type_pointer;
752                         length = *p++;
753
754                         next = p + DIV_ROUNDUP(length, sizeof *p);
755                         if (next > end) {
756                                 printf("message too short, "
757                                        "object (%d), message %s(%s)\n",
758                                        *p, message->name, message->signature);
759                                 errno = EINVAL;
760                                 goto err;
761                         }
762
763                         array = (struct wl_array **) extra;
764                         extra += sizeof *array;
765                         closure->args[i] = array;
766
767                         *array = (struct wl_array *) extra;
768                         extra += sizeof **array;
769
770                         (*array)->size = length;
771                         (*array)->alloc = 0;
772                         (*array)->data = p;
773                         p = next;
774                         break;
775                 case 'h':
776                         closure->types[i] = &ffi_type_sint;
777
778                         fd = (int *) extra;
779                         extra += sizeof *fd;
780                         closure->args[i] = fd;
781
782                         wl_buffer_copy(&connection->fds_in, fd, sizeof *fd);
783                         connection->fds_in.tail += sizeof *fd;
784                         break;
785                 default:
786                         printf("unknown type\n");
787                         assert(0);
788                         break;
789                 }
790         }
791
792         closure->count = i;
793
794         ffi_prep_cif(&closure->cif, FFI_DEFAULT_ABI,
795                      closure->count, &ffi_type_void, closure->types);
796
797         wl_connection_consume(connection, size);
798
799         return closure;
800
801  err:
802         closure->count = i;
803         wl_closure_destroy(closure);
804         wl_connection_consume(connection, size);
805
806         return NULL;
807 }
808
809 static int
810 interface_equal(const struct wl_interface *a, const struct wl_interface *b)
811 {
812         /* In most cases the pointer equality test is sufficient.
813          * However, in some cases, depending on how things are split
814          * across shared objects, we can end up with multiple
815          * instances of the interface metadata constants.  So if the
816          * pointers match, the interfaces are equal, if they don't
817          * match we have to compare the interface names. */
818
819         return a == b || strcmp(a->name, b->name) == 0;
820 }
821
822 int
823 wl_closure_lookup_objects(struct wl_closure *closure, struct wl_map *objects)
824 {
825         struct wl_object **object;
826         const struct wl_message *message;
827         const char *signature;
828         struct argument_details arg;
829         int i, count;
830         uint32_t id;
831
832         message = closure->message;
833         signature = message->signature;
834         count = arg_count_for_signature(signature) + 2;
835         for (i = 2; i < count; i++) {
836                 signature = get_next_argument(signature, &arg);
837                 switch (arg.type) {
838                 case 'o':
839                         id = **(uint32_t **) closure->args[i];
840                         object = closure->args[i];
841                         *object = wl_map_lookup(objects, id);
842                         if (*object == WL_ZOMBIE_OBJECT) {
843                                 /* references object we've already
844                                  * destroyed client side */
845                                 *object = NULL;
846                         } else if (*object == NULL && id != 0) {
847                                 printf("unknown object (%u), message %s(%s)\n",
848                                        id, message->name, message->signature);
849                                 *object = NULL;
850                                 errno = EINVAL;
851                                 return -1;
852                         }
853
854                         if (*object != NULL && message->types[i-2] != NULL &&
855                             !interface_equal((*object)->interface,
856                                              message->types[i-2])) {
857                                 printf("invalid object (%u), type (%s), "
858                                        "message %s(%s)\n",
859                                        id, (*object)->interface->name,
860                                        message->name, message->signature);
861                                 errno = EINVAL;
862                                 return -1;
863                         }
864                 }
865         }
866
867         return 0;
868 }
869
870 void
871 wl_closure_invoke(struct wl_closure *closure,
872                   struct wl_object *target, void (*func)(void), void *data)
873 {
874         int result;
875
876         closure->args[0] = &data;
877         closure->args[1] = &target;
878
879         ffi_call(&closure->cif, func, &result, closure->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) + 2;
893         for (i = 2; i < count; i++) {
894                 signature = get_next_argument(signature, &arg);
895                 if (arg.type != 'h')
896                         continue;
897
898                 fd = closure->args[i];
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 int
910 wl_closure_send(struct wl_closure *closure, struct wl_connection *connection)
911 {
912         uint32_t size;
913
914         if (copy_fds_to_connection(closure, connection))
915                 return -1;
916
917         size = closure->start[1] >> 16;
918
919         return wl_connection_write(connection, closure->start, size);
920 }
921
922 int
923 wl_closure_queue(struct wl_closure *closure, struct wl_connection *connection)
924 {
925         uint32_t size;
926
927         if (copy_fds_to_connection(closure, connection))
928                 return -1;
929
930         size = closure->start[1] >> 16;
931
932         return wl_connection_queue(connection, closure->start, size);
933 }
934
935 void
936 wl_closure_print(struct wl_closure *closure, struct wl_object *target, int send)
937 {
938         union wl_value *value;
939         int32_t si;
940         int i;
941         struct argument_details arg;
942         const char *signature = closure->message->signature;
943         struct timespec tp;
944         unsigned int time;
945
946         clock_gettime(CLOCK_REALTIME, &tp);
947         time = (tp.tv_sec * 1000000L) + (tp.tv_nsec / 1000);
948
949         fprintf(stderr, "[%10.3f] %s%s@%u.%s(",
950                 time / 1000.0,
951                 send ? " -> " : "",
952                 target->interface->name, target->id,
953                 closure->message->name);
954
955         for (i = 2; i < closure->count; i++) {
956                 signature = get_next_argument(signature, &arg);
957                 if (i > 2)
958                         fprintf(stderr, ", ");
959
960                 value = closure->args[i];
961                 switch (arg.type) {
962                 case 'u':
963                         fprintf(stderr, "%u", value->uint32);
964                         break;
965                 case 'i':
966                         si = (int32_t) value->uint32;
967                         fprintf(stderr, "%d", si);
968                         break;
969                 case 'f':
970                         si = (int32_t) value->uint32;
971                         fprintf(stderr, "%f", wl_fixed_to_double(si));
972                         break;
973                 case 's':
974                         fprintf(stderr, "\"%s\"", value->string);
975                         break;
976                 case 'o':
977                         if (value->object)
978                                 fprintf(stderr, "%s@%u",
979                                         value->object->interface->name,
980                                         value->object->id);
981                         else
982                                 fprintf(stderr, "nil");
983                         break;
984                 case 'n':
985                         fprintf(stderr, "new id %s@",
986                                 (closure->message->types[i - 2]) ?
987                                  closure->message->types[i - 2]->name :
988                                   "[unknown]");
989                         if (send && value->new_id != 0)
990                                 fprintf(stderr, "%u", value->new_id);
991                         else if (!send && value->object != NULL)
992                                 fprintf(stderr, "%u", value->object->id);
993                         else
994                                 fprintf(stderr, "nil");
995                         break;
996                 case 'a':
997                         fprintf(stderr, "array");
998                         break;
999                 case 'h':
1000                         fprintf(stderr, "fd %d", value->uint32);
1001                         break;
1002                 }
1003         }
1004
1005         fprintf(stderr, ")\n");
1006 }
1007
1008 void
1009 wl_closure_destroy(struct wl_closure *closure)
1010 {
1011         free(closure);
1012 }