2 * Copyright © 2008 Kristian Høgsberg
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.
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
35 #include <sys/types.h>
36 #include <sys/socket.h>
39 #include "wayland-util.h"
40 #include "wayland-private.h"
41 #include "wayland-os.h"
43 #define DIV_ROUNDUP(n, a) ( ((n) + ((a) - 1)) / (a) )
50 #define MASK(i) ((i) & 4095)
52 #define MAX_FDS_OUT 28
53 #define CLEN (CMSG_LEN(MAX_FDS_OUT * sizeof(int32_t)))
55 struct wl_connection {
56 struct wl_buffer in, out;
57 struct wl_buffer fds_in, fds_out;
65 struct wl_object *object;
67 struct wl_array *array;
71 wl_buffer_put(struct wl_buffer *b, const void *data, size_t count)
76 if (head + count <= sizeof b->data) {
77 memcpy(b->data + head, data, count);
79 size = sizeof b->data - head;
80 memcpy(b->data + head, data, size);
81 memcpy(b->data, (const char *) data + size, count - size);
88 wl_buffer_put_iov(struct wl_buffer *b, struct iovec *iov, int *count)
95 iov[0].iov_base = b->data + head;
96 iov[0].iov_len = tail - head;
98 } else if (tail == 0) {
99 iov[0].iov_base = b->data + head;
100 iov[0].iov_len = sizeof b->data - head;
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;
112 wl_buffer_get_iov(struct wl_buffer *b, struct iovec *iov, int *count)
116 head = MASK(b->head);
117 tail = MASK(b->tail);
119 iov[0].iov_base = b->data + tail;
120 iov[0].iov_len = head - tail;
122 } else if (head == 0) {
123 iov[0].iov_base = b->data + tail;
124 iov[0].iov_len = sizeof b->data - tail;
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;
136 wl_buffer_copy(struct wl_buffer *b, void *data, size_t count)
140 tail = MASK(b->tail);
141 if (tail + count <= sizeof b->data) {
142 memcpy(data, b->data + tail, count);
144 size = sizeof b->data - tail;
145 memcpy(data, b->data + tail, size);
146 memcpy((char *) data + size, b->data, count - size);
151 wl_buffer_size(struct wl_buffer *b)
153 return b->head - b->tail;
156 struct wl_connection *
157 wl_connection_create(int fd)
159 struct wl_connection *connection;
161 connection = malloc(sizeof *connection);
162 if (connection == NULL)
164 memset(connection, 0, sizeof *connection);
171 close_fds(struct wl_buffer *buffer, int max)
173 int32_t fds[sizeof(buffer->data) / sizeof(int32_t)], i, count;
176 size = buffer->head - buffer->tail;
180 wl_buffer_copy(buffer, fds, size);
181 count = size / sizeof fds[0];
182 if (max > 0 && max < count)
184 for (i = 0; i < count; i++)
186 buffer->tail += size;
190 wl_connection_destroy(struct wl_connection *connection)
192 close_fds(&connection->fds_out, -1);
193 close_fds(&connection->fds_in, -1);
194 close(connection->fd);
199 wl_connection_copy(struct wl_connection *connection, void *data, size_t size)
201 wl_buffer_copy(&connection->in, data, size);
205 wl_connection_consume(struct wl_connection *connection, size_t size)
207 connection->in.tail += size;
211 build_cmsg(struct wl_buffer *buffer, char *data, int *clen)
213 struct cmsghdr *cmsg;
216 size = buffer->head - buffer->tail;
217 if (size > MAX_FDS_OUT * sizeof(int32_t))
218 size = MAX_FDS_OUT * sizeof(int32_t);
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;
233 decode_cmsg(struct wl_buffer *buffer, struct msghdr *msg)
235 struct cmsghdr *cmsg;
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)
245 size = cmsg->cmsg_len - CMSG_LEN(0);
246 max = sizeof(buffer->data) - wl_buffer_size(buffer);
247 if (size > max || overflow) {
249 size /= sizeof(int32_t);
250 for (i = 0; i < size; ++i)
251 close(((int*)CMSG_DATA(cmsg))[i]);
253 wl_buffer_put(buffer, CMSG_DATA(cmsg), size);
266 wl_connection_flush(struct wl_connection *connection)
271 int len = 0, count, clen;
274 if (!connection->want_flush)
277 tail = connection->out.tail;
278 while (connection->out.head - connection->out.tail > 0) {
279 wl_buffer_get_iov(&connection->out, iov, &count);
281 build_cmsg(&connection->fds_out, cmsg, &clen);
286 msg.msg_iovlen = count;
287 msg.msg_control = cmsg;
288 msg.msg_controllen = clen;
292 len = sendmsg(connection->fd, &msg,
293 MSG_NOSIGNAL | MSG_DONTWAIT);
294 } while (len == -1 && errno == EINTR);
299 close_fds(&connection->fds_out, MAX_FDS_OUT);
301 connection->out.tail += len;
304 connection->want_flush = 0;
306 return connection->out.head - tail;
310 wl_connection_read(struct wl_connection *connection)
317 if (wl_buffer_size(&connection->in) >= sizeof(connection->in.data)) {
322 wl_buffer_put_iov(&connection->in, iov, &count);
327 msg.msg_iovlen = count;
328 msg.msg_control = cmsg;
329 msg.msg_controllen = sizeof cmsg;
333 len = wl_os_recvmsg_cloexec(connection->fd, &msg, 0);
334 } while (len < 0 && errno == EINTR);
339 ret = decode_cmsg(&connection->fds_in, &msg);
343 connection->in.head += len;
345 return connection->in.head - connection->in.tail;
349 wl_connection_write(struct wl_connection *connection,
350 const void *data, size_t count)
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)
359 wl_buffer_put(&connection->out, data, count);
360 connection->want_flush = 1;
366 wl_connection_queue(struct wl_connection *connection,
367 const void *data, size_t count)
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)
376 wl_buffer_put(&connection->out, data, count);
382 wl_message_size_extra(const struct wl_message *message)
386 for (i = 0, extra = 0; message->signature[i]; i++) {
388 switch (message->signature[i]) {
392 extra += sizeof (void *);
395 extra += sizeof (void *) + sizeof (struct wl_array);
398 extra += sizeof (int);
409 wl_connection_put_fd(struct wl_connection *connection, int32_t fd)
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)
417 wl_buffer_put(&connection->fds_out, &fd, sizeof fd);
423 get_next_argument(const char *signature, struct argument_details *details)
425 if (*signature == '?') {
426 details->nullable = 1;
429 details->nullable = 0;
431 details->type = *signature;
432 return signature + 1;
436 arg_count_for_signature(const char *signature)
440 if (*signature != '?')
448 wl_closure_vmarshal(struct wl_object *sender,
449 uint32_t opcode, va_list ap,
450 const struct wl_message *message)
452 struct wl_closure *closure;
453 struct wl_object **objectp, *object;
454 uint32_t length, aligned, *p, *start, size, *end;
456 struct wl_array **arrayp, *array;
458 const char *signature = message->signature;
459 struct argument_details arg;
461 int i, count, fd, extra_size, *fd_ptr;
463 /* FIXME: Match old fixed allocation for now */
464 closure = malloc(sizeof *closure + 1024);
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];
475 closure->types[0] = &ffi_type_pointer;
476 closure->types[1] = &ffi_type_pointer;
478 for (i = 2; i < count; i++) {
479 signature = get_next_argument(signature, &arg);
483 closure->types[i] = &ffi_type_sint32;
484 closure->args[i] = p;
487 *p++ = va_arg(ap, wl_fixed_t);
490 closure->types[i] = &ffi_type_uint32;
491 closure->args[i] = p;
494 *p++ = va_arg(ap, uint32_t);
497 closure->types[i] = &ffi_type_sint32;
498 closure->args[i] = p;
501 *p++ = va_arg(ap, int32_t);
504 closure->types[i] = &ffi_type_pointer;
505 closure->args[i] = extra;
506 sp = (const char **) extra;
509 s = va_arg(ap, const char *);
511 if (!arg.nullable && s == NULL)
514 length = s ? strlen(s) + 1: 0;
515 aligned = (length + 3) & ~3;
516 if (p + aligned / sizeof *p + 1 > end)
521 *sp = (const char *) p;
525 memcpy(p, s, length);
526 memset((char *) p + length, 0, aligned - length);
527 p += aligned / sizeof *p;
530 closure->types[i] = &ffi_type_pointer;
531 closure->args[i] = extra;
532 objectp = (struct wl_object **) extra;
533 extra += sizeof *objectp;
535 object = va_arg(ap, struct wl_object *);
537 if (!arg.nullable && object == NULL)
543 *p++ = object ? object->id : 0;
547 closure->types[i] = &ffi_type_uint32;
548 closure->args[i] = p;
549 object = va_arg(ap, struct wl_object *);
553 if (!arg.nullable && object == NULL)
556 *p++ = object ? object->id : 0;
560 closure->types[i] = &ffi_type_pointer;
561 closure->args[i] = extra;
562 arrayp = (struct wl_array **) extra;
563 extra += sizeof *arrayp;
565 *arrayp = (struct wl_array *) extra;
566 extra += sizeof **arrayp;
568 array = va_arg(ap, struct wl_array *);
570 if (!arg.nullable && array == NULL)
573 if (array == NULL || array->size == 0) {
579 if (p + DIV_ROUNDUP(array->size, sizeof *p) + 1 > end)
582 memcpy(p, array->data, array->size);
584 (*arrayp)->size = array->size;
585 (*arrayp)->alloc = array->alloc;
588 p += DIV_ROUNDUP(array->size, sizeof *p);
592 closure->types[i] = &ffi_type_sint;
593 closure->args[i] = extra;
594 fd_ptr = (int *) extra;
595 extra += sizeof *fd_ptr;
597 fd = va_arg(ap, int);
598 dup_fd = wl_os_dupfd_cloexec(fd, 0);
600 fprintf(stderr, "dup failed: %m");
606 fprintf(stderr, "unhandled format code: '%c'\n",
613 size = (p - start) * sizeof *p;
614 start[0] = sender->id;
615 start[1] = opcode | (size << 16);
617 closure->start = start;
618 closure->message = message;
619 closure->count = count;
621 ffi_prep_cif(&closure->cif, FFI_DEFAULT_ABI,
622 closure->count, &ffi_type_void, closure->types);
627 printf("request too big to marshal, maximum size is %zu\n",
628 sizeof closure->buffer);
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);
645 wl_connection_demarshal(struct wl_connection *connection,
647 struct wl_map *objects,
648 const struct wl_message *message)
650 uint32_t *p, *next, *end, length, **id;
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;
660 count = arg_count_for_signature(signature) + 2;
661 if (count > ARRAY_LENGTH(closure->types)) {
662 printf("too many args (%d)\n", count);
664 wl_connection_consume(connection, size);
668 extra_space = wl_message_size_extra(message);
669 closure = malloc(sizeof *closure + 8 + size + extra_space);
673 closure->message = message;
674 closure->types[0] = &ffi_type_pointer;
675 closure->types[1] = &ffi_type_pointer;
676 closure->start = closure->buffer;
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);
686 printf("message too short, "
687 "object (%d), message %s(%s)\n",
688 *p, message->name, message->signature);
695 closure->types[i] = &ffi_type_uint32;
696 closure->args[i] = p++;
699 closure->types[i] = &ffi_type_sint32;
700 closure->args[i] = p++;
703 closure->types[i] = &ffi_type_sint32;
704 closure->args[i] = p++;
707 closure->types[i] = &ffi_type_pointer;
710 next = p + DIV_ROUNDUP(length, sizeof *p);
712 printf("message too short, "
713 "object (%d), message %s(%s)\n",
714 *p, message->name, message->signature);
721 closure->args[i] = s;
729 if (length > 0 && (*s)[length - 1] != '\0') {
730 printf("string not nul-terminated, "
732 message->name, message->signature);
739 closure->types[i] = &ffi_type_pointer;
740 id = (uint32_t **) extra;
742 closure->args[i] = id;
745 if (*id == 0 && !arg.nullable) {
746 printf("NULL object received on non-nullable "
747 "type, message %s(%s)\n", message->name,
757 closure->types[i] = &ffi_type_pointer;
758 id = (uint32_t **) extra;
760 closure->args[i] = id;
763 if (*id == 0 && !arg.nullable) {
764 printf("NULL new ID received on non-nullable "
765 "type, message %s(%s)\n", message->name,
771 if (wl_map_reserve_new(objects, *p) < 0) {
772 printf("not a valid new object id (%d), "
774 *p, message->name, message->signature);
782 closure->types[i] = &ffi_type_pointer;
785 next = p + DIV_ROUNDUP(length, sizeof *p);
787 printf("message too short, "
788 "object (%d), message %s(%s)\n",
789 *p, message->name, message->signature);
794 array = (struct wl_array **) extra;
795 extra += sizeof *array;
796 closure->args[i] = array;
798 *array = (struct wl_array *) extra;
799 extra += sizeof **array;
801 (*array)->size = length;
807 closure->types[i] = &ffi_type_sint;
811 closure->args[i] = fd;
813 wl_buffer_copy(&connection->fds_in, fd, sizeof *fd);
814 connection->fds_in.tail += sizeof *fd;
817 printf("unknown type\n");
825 ffi_prep_cif(&closure->cif, FFI_DEFAULT_ABI,
826 closure->count, &ffi_type_void, closure->types);
828 wl_connection_consume(connection, size);
834 wl_closure_destroy(closure);
835 wl_connection_consume(connection, size);
841 interface_equal(const struct wl_interface *a, const struct wl_interface *b)
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. */
850 return a == b || strcmp(a->name, b->name) == 0;
854 wl_closure_lookup_objects(struct wl_closure *closure, struct wl_map *objects)
856 struct wl_object **object;
857 const struct wl_message *message;
858 const char *signature;
859 struct argument_details arg;
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);
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 */
877 } else if (*object == NULL && id != 0) {
878 printf("unknown object (%u), message %s(%s)\n",
879 id, message->name, message->signature);
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), "
890 id, (*object)->interface->name,
891 message->name, message->signature);
902 wl_closure_invoke(struct wl_closure *closure,
903 struct wl_object *target, void (*func)(void), void *data)
907 closure->args[0] = &data;
908 closure->args[1] = ⌖
910 ffi_call(&closure->cif, func, &result, closure->args);
914 copy_fds_to_connection(struct wl_closure *closure,
915 struct wl_connection *connection)
917 const struct wl_message *message = closure->message;
919 struct argument_details arg;
920 const char *signature = message->signature;
923 count = arg_count_for_signature(signature) + 2;
924 for (i = 2; i < count; i++) {
925 signature = get_next_argument(signature, &arg);
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");
941 wl_closure_send(struct wl_closure *closure, struct wl_connection *connection)
945 if (copy_fds_to_connection(closure, connection))
948 size = closure->start[1] >> 16;
950 return wl_connection_write(connection, closure->start, size);
954 wl_closure_queue(struct wl_closure *closure, struct wl_connection *connection)
958 if (copy_fds_to_connection(closure, connection))
961 size = closure->start[1] >> 16;
963 return wl_connection_queue(connection, closure->start, size);
967 wl_closure_print(struct wl_closure *closure, struct wl_object *target, int send)
969 union wl_value *value;
972 struct argument_details arg;
973 const char *signature = closure->message->signature;
977 clock_gettime(CLOCK_REALTIME, &tp);
978 time = (tp.tv_sec * 1000000L) + (tp.tv_nsec / 1000);
980 fprintf(stderr, "[%10.3f] %s%s@%u.%s(",
983 target->interface->name, target->id,
984 closure->message->name);
986 for (i = 2; i < closure->count; i++) {
987 signature = get_next_argument(signature, &arg);
989 fprintf(stderr, ", ");
991 value = closure->args[i];
994 fprintf(stderr, "%u", value->uint32);
997 si = (int32_t) value->uint32;
998 fprintf(stderr, "%d", si);
1001 si = (int32_t) value->uint32;
1002 fprintf(stderr, "%f", wl_fixed_to_double(si));
1005 fprintf(stderr, "\"%s\"", value->string);
1009 fprintf(stderr, "%s@%u",
1010 value->object->interface->name,
1013 fprintf(stderr, "nil");
1016 fprintf(stderr, "new id %s@",
1017 (closure->message->types[i - 2]) ?
1018 closure->message->types[i - 2]->name :
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);
1025 fprintf(stderr, "nil");
1028 fprintf(stderr, "array");
1031 fprintf(stderr, "fd %d", value->uint32);
1036 fprintf(stderr, ")\n");
1040 wl_closure_destroy(struct wl_closure *closure)