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