Change scanner.c license to MIT
[profile/ivi/wayland.git] / wayland / 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 <stdlib.h>
26 #include <stdint.h>
27 #include <string.h>
28 #include <stdio.h>
29 #include <errno.h>
30 #include <sys/uio.h>
31 #include <ffi.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 "connection.h"
41
42 #define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0])
43
44 struct wl_buffer {
45         char data[4096];
46         int head, tail;
47 };
48
49 #define MASK(i) ((i) & 4095)
50
51 struct wl_closure {
52         int count;
53         const struct wl_message *message;
54         ffi_type *types[20];
55         ffi_cif cif;
56         void *args[20];
57         uint32_t buffer[64];
58         uint32_t *start;
59 };
60
61 struct wl_connection {
62         struct wl_buffer in, out;
63         struct wl_buffer fds_in, fds_out;
64         int fd;
65         void *data;
66         wl_connection_update_func_t update;
67         struct wl_closure receive_closure, send_closure;
68 };
69
70 union wl_value {
71         uint32_t uint32;
72         char *string;
73         struct wl_object *object;
74         uint32_t new_id;
75         struct wl_array *array;
76 };
77
78 static void
79 wl_buffer_put(struct wl_buffer *b, const void *data, size_t count)
80 {
81         int head, size;
82
83         head = MASK(b->head);
84         if (head + count <= sizeof b->data) {
85                 memcpy(b->data + head, data, count);
86         } else {
87                 size = sizeof b->data - head;
88                 memcpy(b->data + head, data, size);
89                 memcpy(b->data, (const char *) data + size, count - size);
90         }
91
92         b->head += count;
93 }
94
95 static void
96 wl_buffer_put_iov(struct wl_buffer *b, struct iovec *iov, int *count)
97 {
98         int head, tail;
99
100         head = MASK(b->head);
101         tail = MASK(b->tail);
102         if (head < tail) {
103                 iov[0].iov_base = b->data + head;
104                 iov[0].iov_len = tail - head;
105                 *count = 1;
106         } else if (tail == 0) {
107                 iov[0].iov_base = b->data + head;
108                 iov[0].iov_len = sizeof b->data - head;
109                 *count = 1;
110         } else {
111                 iov[0].iov_base = b->data + head;
112                 iov[0].iov_len = sizeof b->data - head;
113                 iov[1].iov_base = b->data;
114                 iov[1].iov_len = tail;
115                 *count = 2;
116         }
117 }
118
119 static void
120 wl_buffer_get_iov(struct wl_buffer *b, struct iovec *iov, int *count)
121 {
122         int head, tail;
123
124         head = MASK(b->head);
125         tail = MASK(b->tail);
126         if (tail < head) {
127                 iov[0].iov_base = b->data + tail;
128                 iov[0].iov_len = head - tail;
129                 *count = 1;
130         } else if (head == 0) {
131                 iov[0].iov_base = b->data + tail;
132                 iov[0].iov_len = sizeof b->data - tail;
133                 *count = 1;
134         } else {
135                 iov[0].iov_base = b->data + tail;
136                 iov[0].iov_len = sizeof b->data - tail;
137                 iov[1].iov_base = b->data;
138                 iov[1].iov_len = head;
139                 *count = 2;
140         }
141 }
142
143 static void
144 wl_buffer_copy(struct wl_buffer *b, void *data, size_t count)
145 {
146         int tail, size;
147
148         tail = MASK(b->tail);
149         if (tail + count <= sizeof b->data) {
150                 memcpy(data, b->data + tail, count);
151         } else {
152                 size = sizeof b->data - tail;
153                 memcpy(data, b->data + tail, size);
154                 memcpy((char *) data + size, b->data, count - size);
155         }
156 }
157
158 struct wl_connection *
159 wl_connection_create(int fd,
160                      wl_connection_update_func_t update,
161                      void *data)
162 {
163         struct wl_connection *connection;
164
165         connection = malloc(sizeof *connection);
166         if (connection == NULL)
167                 return NULL;
168         memset(connection, 0, sizeof *connection);
169         connection->fd = fd;
170         connection->update = update;
171         connection->data = data;
172
173         connection->update(connection,
174                            WL_CONNECTION_READABLE,
175                            connection->data);
176
177         return connection;
178 }
179
180 void
181 wl_connection_destroy(struct wl_connection *connection)
182 {
183         close(connection->fd);
184         free(connection);
185 }
186
187 void
188 wl_connection_copy(struct wl_connection *connection, void *data, size_t size)
189 {
190         wl_buffer_copy(&connection->in, data, size);
191 }
192
193 void
194 wl_connection_consume(struct wl_connection *connection, size_t size)
195 {
196         connection->in.tail += size;
197 }
198
199 static void
200 build_cmsg(struct wl_buffer *buffer, char *data, int *clen)
201 {
202         struct cmsghdr *cmsg;
203         size_t size;
204
205         size = buffer->head - buffer->tail;
206         if (size > 0) {
207                 cmsg = (struct cmsghdr *) data;
208                 cmsg->cmsg_level = SOL_SOCKET;
209                 cmsg->cmsg_type = SCM_RIGHTS;
210                 cmsg->cmsg_len = CMSG_LEN(size);
211                 wl_buffer_copy(buffer, CMSG_DATA(cmsg), size);
212                 *clen = cmsg->cmsg_len;
213         } else {
214                 *clen = 0;
215         }
216 }
217
218 static void
219 close_fds(struct wl_buffer *buffer)
220 {
221         int fds[32], i, count;
222         size_t size;
223
224         size = buffer->head - buffer->tail;
225         if (size == 0)
226                 return;
227
228         wl_buffer_copy(buffer, fds, size);
229         count = size / sizeof fds[0];
230         for (i = 0; i < count; i++)
231                 close(fds[i]);
232         buffer->tail += size;
233 }
234
235 static void
236 decode_cmsg(struct wl_buffer *buffer, struct msghdr *msg)
237 {
238         struct cmsghdr *cmsg;
239         size_t size;
240
241         for (cmsg = CMSG_FIRSTHDR(msg); cmsg != NULL;
242              cmsg = CMSG_NXTHDR(msg, cmsg)) {
243                 if (cmsg->cmsg_level == SOL_SOCKET &&
244                     cmsg->cmsg_type == SCM_RIGHTS) {
245                         size = cmsg->cmsg_len - CMSG_LEN(0);
246                         wl_buffer_put(buffer, CMSG_DATA(cmsg), size);
247                 }
248         }
249 }
250
251 int
252 wl_connection_data(struct wl_connection *connection, uint32_t mask)
253 {
254         struct iovec iov[2];
255         struct msghdr msg;
256         char cmsg[128];
257         int len, count, clen;
258
259         if (mask & WL_CONNECTION_WRITABLE) {
260                 wl_buffer_get_iov(&connection->out, iov, &count);
261
262                 build_cmsg(&connection->fds_out, cmsg, &clen);
263
264                 msg.msg_name = NULL;
265                 msg.msg_namelen = 0;
266                 msg.msg_iov = iov;
267                 msg.msg_iovlen = count;
268                 msg.msg_control = cmsg;
269                 msg.msg_controllen = clen;
270                 msg.msg_flags = 0;
271
272                 do {
273                         len = sendmsg(connection->fd, &msg, MSG_NOSIGNAL);
274                 } while (len < 0 && errno == EINTR);
275
276                 if (len == -1 && errno == EPIPE) {
277                         return -1;
278                 } else if (len < 0) {
279                         fprintf(stderr,
280                                 "write error for connection %p, fd %d: %m\n",
281                                 connection, connection->fd);
282                         return -1;
283                 }
284
285                 close_fds(&connection->fds_out);
286
287                 connection->out.tail += len;
288                 if (connection->out.tail == connection->out.head)
289                         connection->update(connection,
290                                            WL_CONNECTION_READABLE,
291                                            connection->data);
292         }
293
294         if (mask & WL_CONNECTION_READABLE) {
295                 wl_buffer_put_iov(&connection->in, iov, &count);
296
297                 msg.msg_name = NULL;
298                 msg.msg_namelen = 0;
299                 msg.msg_iov = iov;
300                 msg.msg_iovlen = count;
301                 msg.msg_control = cmsg;
302                 msg.msg_controllen = sizeof cmsg;
303                 msg.msg_flags = 0;
304
305                 do {
306                         len = recvmsg(connection->fd, &msg, MSG_CMSG_CLOEXEC);
307                 } while (len < 0 && errno == EINTR);
308
309                 if (len < 0) {
310                         fprintf(stderr,
311                                 "read error from connection %p: %m (%d)\n",
312                                 connection, errno);
313                         return -1;
314                 } else if (len == 0) {
315                         /* FIXME: Handle this better? */
316                         return -1;
317                 }
318
319                 decode_cmsg(&connection->fds_in, &msg);
320
321                 connection->in.head += len;
322         }       
323
324         return connection->in.head - connection->in.tail;
325 }
326
327 void
328 wl_connection_write(struct wl_connection *connection,
329                     const void *data, size_t count)
330 {
331         if (connection->out.head - connection->out.tail +
332             count > ARRAY_LENGTH(connection->out.data))
333                 wl_connection_data(connection, WL_CONNECTION_WRITABLE);
334
335         wl_buffer_put(&connection->out, data, count);
336
337         if (connection->out.head - connection->out.tail == count)
338                 connection->update(connection,
339                                    WL_CONNECTION_READABLE |
340                                    WL_CONNECTION_WRITABLE,
341                                    connection->data);
342 }
343
344 static int
345 wl_message_size_extra(const struct wl_message *message)
346 {
347         int i, extra;
348
349         for (i = 0, extra = 0; message->signature[i]; i++) {
350
351                 switch (message->signature[i]) {
352                 case 's':
353                 case 'o':
354                         extra += sizeof (void *);
355                         break;
356                 case 'a':
357                         extra += sizeof (void *) + sizeof (struct wl_array);
358                         break;
359                 case 'h':
360                         extra += sizeof (int);
361                         break;
362                 default:
363                         break;
364                 }
365         }
366
367         return extra;
368 }
369
370 struct wl_closure *
371 wl_connection_vmarshal(struct wl_connection *connection,
372                        struct wl_object *sender,
373                        uint32_t opcode, va_list ap,
374                        const struct wl_message *message)
375 {
376         struct wl_closure *closure = &connection->send_closure;
377         struct wl_object **objectp, *object;
378         uint32_t length, *p, *start, size;
379         int dup_fd;
380         struct wl_array **arrayp, *array;
381         const char **sp, *s;
382         char *extra;
383         int i, count, fd, extra_size, *fd_ptr;
384
385         extra_size = wl_message_size_extra(message);
386         count = strlen(message->signature) + 2;
387         extra = (char *) closure->buffer;
388         start = &closure->buffer[DIV_ROUNDUP(extra_size, sizeof *p)];
389         p = &start[2];
390         for (i = 2; i < count; i++) {
391                 switch (message->signature[i - 2]) {
392                 case 'u':
393                         closure->types[i] = &ffi_type_uint32;
394                         closure->args[i] = p;
395                         *p++ = va_arg(ap, uint32_t);
396                         break;
397                 case 'i':
398                         closure->types[i] = &ffi_type_sint32;
399                         closure->args[i] = p;
400                         *p++ = va_arg(ap, int32_t);
401                         break;
402                 case 's':
403                         closure->types[i] = &ffi_type_pointer;
404                         closure->args[i] = extra;
405                         sp = (const char **) extra;
406                         extra += sizeof *sp;
407
408                         s = va_arg(ap, const char *);
409                         length = s ? strlen(s) + 1: 0;
410                         *p++ = length;
411
412                         if (length > 0)
413                                 *sp = (const char *) p;
414                         else
415                                 *sp = NULL;
416
417                         memcpy(p, s, length);
418                         p += DIV_ROUNDUP(length, sizeof *p);
419                         break;
420                 case 'o':
421                         closure->types[i] = &ffi_type_pointer;
422                         closure->args[i] = extra;
423                         objectp = (struct wl_object **) extra;
424                         extra += sizeof *objectp;
425
426                         object = va_arg(ap, struct wl_object *);
427                         *objectp = object;
428                         *p++ = object ? object->id : 0;
429                         break;
430
431                 case 'n':
432                         closure->types[i] = &ffi_type_uint32;
433                         closure->args[i] = p;
434                         object = va_arg(ap, struct wl_object *);
435                         *p++ = object->id;
436                         break;
437
438                 case 'a':
439                         closure->types[i] = &ffi_type_pointer;
440                         closure->args[i] = extra;
441                         arrayp = (struct wl_array **) extra;
442                         extra += sizeof *arrayp;
443
444                         *arrayp = (struct wl_array *) extra;
445                         extra += sizeof **arrayp;
446
447                         array = va_arg(ap, struct wl_array *);
448                         if (array == NULL || array->size == 0) {
449                                 *p++ = 0;
450                                 break;
451                         }
452                         *p++ = array->size;
453                         memcpy(p, array->data, array->size);
454
455                         (*arrayp)->size = array->size;
456                         (*arrayp)->alloc = array->alloc;
457                         (*arrayp)->data = p;
458
459                         p += DIV_ROUNDUP(array->size, sizeof *p);
460                         break;
461
462                 case 'h':
463                         closure->types[i] = &ffi_type_sint;
464                         closure->args[i] = extra;
465                         fd_ptr = (int *) extra;
466                         extra += sizeof *fd_ptr;
467
468                         fd = va_arg(ap, int);
469                         dup_fd = fcntl(fd, F_DUPFD_CLOEXEC, 0);
470                         if (dup_fd < 0) {
471                                 fprintf(stderr, "dup failed: %m");
472                                 abort();
473                         }
474                         *fd_ptr = dup_fd;
475                         wl_buffer_put(&connection->fds_out,
476                                       &dup_fd, sizeof dup_fd);
477                         break;
478                 default:
479                         assert(0);
480                         break;
481                 }
482         }
483
484         size = (p - start) * sizeof *p;
485         start[0] = sender->id;
486         start[1] = opcode | (size << 16);
487
488         closure->start = start;
489         closure->message = message;
490         closure->count = count;
491
492         return closure;
493 }
494
495 struct wl_closure *
496 wl_connection_demarshal(struct wl_connection *connection,
497                         uint32_t size,
498                         struct wl_hash_table *objects,
499                         const struct wl_message *message)
500 {
501         uint32_t *p, *next, *end, length;
502         int *fd;
503         char *extra, **s;
504         int i, count, extra_space;
505         struct wl_object **object;
506         struct wl_array **array;
507         struct wl_closure *closure = &connection->receive_closure;
508
509         count = strlen(message->signature) + 2;
510         if (count > ARRAY_LENGTH(closure->types)) {
511                 printf("too many args (%d)\n", count);
512                 errno = EINVAL;
513                 wl_connection_consume(connection, size);
514                 return NULL;
515         }
516
517         extra_space = wl_message_size_extra(message);
518         if (sizeof closure->buffer < size + extra_space) {
519                 printf("request too big, should malloc tmp buffer here\n");
520                 errno = ENOMEM;
521                 wl_connection_consume(connection, size);
522                 return NULL;
523         }
524
525         closure->message = message;
526         closure->types[0] = &ffi_type_pointer;
527         closure->types[1] = &ffi_type_pointer;
528
529         wl_connection_copy(connection, closure->buffer, size);
530         p = &closure->buffer[2];
531         end = (uint32_t *) ((char *) p + size);
532         extra = (char *) end;
533         for (i = 2; i < count; i++) {
534                 if (p + 1 > end) {
535                         printf("message too short, "
536                                "object (%d), message %s(%s)\n",
537                                *p, message->name, message->signature);
538                         errno = EINVAL;
539                         goto err;
540                 }
541
542                 switch (message->signature[i - 2]) {
543                 case 'u':
544                         closure->types[i] = &ffi_type_uint32;
545                         closure->args[i] = p++;
546                         break;
547                 case 'i':
548                         closure->types[i] = &ffi_type_sint32;
549                         closure->args[i] = p++;
550                         break;
551                 case 's':
552                         closure->types[i] = &ffi_type_pointer;
553                         length = *p++;
554
555                         next = p + DIV_ROUNDUP(length, sizeof *p);
556                         if (next > end) {
557                                 printf("message too short, "
558                                        "object (%d), message %s(%s)\n",
559                                        *p, message->name, message->signature);
560                                 errno = EINVAL;
561                                 goto err;
562                         }
563
564                         s = (char **) extra;
565                         extra += sizeof *s;
566                         closure->args[i] = s;
567
568                         if (length == 0) {
569                                 *s = NULL;
570                         } else {
571                                 *s = (char *) p;
572                         }
573
574                         if (length > 0 && (*s)[length - 1] != '\0') {
575                                 printf("string not nul-terminated, "
576                                        "message %s(%s)\n",
577                                        message->name, message->signature);
578                                 errno = EINVAL;
579                                 goto err;
580                         }
581                         p = next;
582                         break;
583                 case 'o':
584                         closure->types[i] = &ffi_type_pointer;
585                         object = (struct wl_object **) extra;
586                         extra += sizeof *object;
587                         closure->args[i] = object;
588
589                         *object = wl_hash_table_lookup(objects, *p);
590                         if (*object == NULL && *p != 0) {
591                                 printf("unknown object (%d), message %s(%s)\n",
592                                        *p, message->name, message->signature);
593                                 errno = EINVAL;
594                                 goto err;
595                         }
596
597                         p++;
598                         break;
599                 case 'n':
600                         closure->types[i] = &ffi_type_uint32;
601                         closure->args[i] = p;
602                         object = wl_hash_table_lookup(objects, *p);
603                         if (object != NULL) {
604                                 printf("not a new object (%d), "
605                                        "message %s(%s)\n",
606                                        *p, message->name, message->signature);
607                                 errno = EINVAL;
608                                 goto err;
609                         }
610                         p++;
611                         break;
612                 case 'a':
613                         closure->types[i] = &ffi_type_pointer;
614                         length = *p++;
615
616                         next = p + DIV_ROUNDUP(length, sizeof *p);
617                         if (next > end) {
618                                 printf("message too short, "
619                                        "object (%d), message %s(%s)\n",
620                                        *p, message->name, message->signature);
621                                 errno = EINVAL;
622                                 goto err;
623                         }
624
625                         array = (struct wl_array **) extra;
626                         extra += sizeof *array;
627                         closure->args[i] = array;
628
629                         *array = (struct wl_array *) extra;
630                         extra += sizeof **array;
631
632                         (*array)->size = length;
633                         (*array)->alloc = 0;
634                         (*array)->data = p;
635                         p = next;
636                         break;
637                 case 'h':
638                         closure->types[i] = &ffi_type_sint;
639
640                         fd = (int *) extra;
641                         extra += sizeof *fd;
642                         closure->args[i] = fd;
643
644                         wl_buffer_copy(&connection->fds_in, fd, sizeof *fd);
645                         connection->fds_in.tail += sizeof *fd;
646                         break;
647                 default:
648                         printf("unknown type\n");
649                         assert(0);
650                         break;
651                 }
652         }
653
654         closure->count = i;
655         ffi_prep_cif(&closure->cif, FFI_DEFAULT_ABI,
656                      closure->count, &ffi_type_uint32, closure->types);
657
658         wl_connection_consume(connection, size);
659
660         return closure;
661
662  err:
663         closure->count = i;
664         wl_closure_destroy(closure);
665         wl_connection_consume(connection, size);
666
667         return NULL;
668 }
669
670 void
671 wl_closure_invoke(struct wl_closure *closure,
672                   struct wl_object *target, void (*func)(void), void *data)
673 {
674         int result;
675
676         closure->args[0] = &data;
677         closure->args[1] = &target;
678
679         ffi_call(&closure->cif, func, &result, closure->args);
680 }
681
682 void
683 wl_closure_send(struct wl_closure *closure, struct wl_connection *connection)
684 {
685         uint32_t size;
686
687         size = closure->start[1] >> 16;
688         wl_connection_write(connection, closure->start, size);
689 }
690
691 void
692 wl_closure_print(struct wl_closure *closure, struct wl_object *target, int send)
693 {
694         union wl_value *value;
695         int i;
696         struct timespec tp;
697         unsigned int time;
698
699         clock_gettime(CLOCK_REALTIME, &tp);
700         time = (tp.tv_sec * 1000000L) + (tp.tv_nsec / 1000);
701
702         fprintf(stderr, "[%10.3f] %s%s@%d.%s(",
703                 time / 1000.0,
704                 send ? " -> " : "",
705                 target->interface->name, target->id,
706                 closure->message->name);
707
708         for (i = 2; i < closure->count; i++) {
709                 if (i > 2)
710                         fprintf(stderr, ", ");
711
712                 value = closure->args[i];
713                 switch (closure->message->signature[i - 2]) {
714                 case 'u':
715                         fprintf(stderr, "%u", value->uint32);
716                         break;
717                 case 'i':
718                         fprintf(stderr, "%d", value->uint32);
719                         break;
720                 case 's':
721                         fprintf(stderr, "\"%s\"", value->string);
722                         break;
723                 case 'o':
724                         if (value->object)
725                                 fprintf(stderr, "%s@%u",
726                                         value->object->interface->name,
727                                         value->object->id);
728                         else
729                                 fprintf(stderr, "nil");
730                         break;
731                 case 'n':
732                         fprintf(stderr, "new id %u", value->uint32);
733                         break;
734                 case 'a':
735                         fprintf(stderr, "array");
736                         break;
737                 case 'h':
738                         fprintf(stderr, "fd %d", value->uint32);
739                         break;
740                 }
741         }
742
743         fprintf(stderr, ")\n");
744 }
745
746 void
747 wl_closure_destroy(struct wl_closure *closure)
748 {
749 }