2 * Copyright © 2008 Kristian Høgsberg
3 * Copyright © 2013 Jason Ekstrand
5 * Permission to use, copy, modify, distribute, and sell this software and its
6 * documentation for any purpose is hereby granted without fee, provided that
7 * the above copyright notice appear in all copies and that both that copyright
8 * notice and this permission notice appear in supporting documentation, and
9 * that the name of the copyright holders not be used in advertising or
10 * publicity pertaining to distribution of the software without specific,
11 * written prior permission. The copyright holders make no representations
12 * about the suitability of this software for any purpose. It is provided "as
13 * is" without express or implied warranty.
15 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
17 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
18 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
19 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
20 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
36 #include <sys/types.h>
37 #include <sys/socket.h>
41 #include "wayland-util.h"
42 #include "wayland-private.h"
43 #include "wayland-os.h"
45 #define DIV_ROUNDUP(n, a) ( ((n) + ((a) - 1)) / (a) )
52 #define MASK(i) ((i) & 4095)
54 #define MAX_FDS_OUT 28
55 #define CLEN (CMSG_LEN(MAX_FDS_OUT * sizeof(int32_t)))
57 struct wl_connection {
58 struct wl_buffer in, out;
59 struct wl_buffer fds_in, fds_out;
65 wl_buffer_put(struct wl_buffer *b, const void *data, size_t count)
70 if (head + count <= sizeof b->data) {
71 memcpy(b->data + head, data, count);
73 size = sizeof b->data - head;
74 memcpy(b->data + head, data, size);
75 memcpy(b->data, (const char *) data + size, count - size);
82 wl_buffer_put_iov(struct wl_buffer *b, struct iovec *iov, int *count)
89 iov[0].iov_base = b->data + head;
90 iov[0].iov_len = tail - head;
92 } else if (tail == 0) {
93 iov[0].iov_base = b->data + head;
94 iov[0].iov_len = sizeof b->data - head;
97 iov[0].iov_base = b->data + head;
98 iov[0].iov_len = sizeof b->data - head;
99 iov[1].iov_base = b->data;
100 iov[1].iov_len = tail;
106 wl_buffer_get_iov(struct wl_buffer *b, struct iovec *iov, int *count)
110 head = MASK(b->head);
111 tail = MASK(b->tail);
113 iov[0].iov_base = b->data + tail;
114 iov[0].iov_len = head - tail;
116 } else if (head == 0) {
117 iov[0].iov_base = b->data + tail;
118 iov[0].iov_len = sizeof b->data - tail;
121 iov[0].iov_base = b->data + tail;
122 iov[0].iov_len = sizeof b->data - tail;
123 iov[1].iov_base = b->data;
124 iov[1].iov_len = head;
130 wl_buffer_copy(struct wl_buffer *b, void *data, size_t count)
134 tail = MASK(b->tail);
135 if (tail + count <= sizeof b->data) {
136 memcpy(data, b->data + tail, count);
138 size = sizeof b->data - tail;
139 memcpy(data, b->data + tail, size);
140 memcpy((char *) data + size, b->data, count - size);
145 wl_buffer_size(struct wl_buffer *b)
147 return b->head - b->tail;
150 struct wl_connection *
151 wl_connection_create(int fd)
153 struct wl_connection *connection;
155 connection = malloc(sizeof *connection);
156 if (connection == NULL)
158 memset(connection, 0, sizeof *connection);
165 close_fds(struct wl_buffer *buffer, int max)
167 int32_t fds[sizeof(buffer->data) / sizeof(int32_t)], i, count;
170 size = buffer->head - buffer->tail;
174 wl_buffer_copy(buffer, fds, size);
175 count = size / sizeof fds[0];
176 if (max > 0 && max < count)
178 for (i = 0; i < count; i++)
180 buffer->tail += size;
184 wl_connection_destroy(struct wl_connection *connection)
186 close_fds(&connection->fds_out, -1);
187 close_fds(&connection->fds_in, -1);
188 close(connection->fd);
193 wl_connection_copy(struct wl_connection *connection, void *data, size_t size)
195 wl_buffer_copy(&connection->in, data, size);
199 wl_connection_consume(struct wl_connection *connection, size_t size)
201 connection->in.tail += size;
205 build_cmsg(struct wl_buffer *buffer, char *data, int *clen)
207 struct cmsghdr *cmsg;
210 size = buffer->head - buffer->tail;
211 if (size > MAX_FDS_OUT * sizeof(int32_t))
212 size = MAX_FDS_OUT * sizeof(int32_t);
215 cmsg = (struct cmsghdr *) data;
216 cmsg->cmsg_level = SOL_SOCKET;
217 cmsg->cmsg_type = SCM_RIGHTS;
218 cmsg->cmsg_len = CMSG_LEN(size);
219 wl_buffer_copy(buffer, CMSG_DATA(cmsg), size);
220 *clen = cmsg->cmsg_len;
227 decode_cmsg(struct wl_buffer *buffer, struct msghdr *msg)
229 struct cmsghdr *cmsg;
233 for (cmsg = CMSG_FIRSTHDR(msg); cmsg != NULL;
234 cmsg = CMSG_NXTHDR(msg, cmsg)) {
235 if (cmsg->cmsg_level != SOL_SOCKET ||
236 cmsg->cmsg_type != SCM_RIGHTS)
239 size = cmsg->cmsg_len - CMSG_LEN(0);
240 max = sizeof(buffer->data) - wl_buffer_size(buffer);
241 if (size > max || overflow) {
243 size /= sizeof(int32_t);
244 for (i = 0; i < size; i++)
245 close(((int*)CMSG_DATA(cmsg))[i]);
247 wl_buffer_put(buffer, CMSG_DATA(cmsg), size);
260 wl_connection_flush(struct wl_connection *connection)
265 int len = 0, count, clen;
268 if (!connection->want_flush)
271 tail = connection->out.tail;
272 while (connection->out.head - connection->out.tail > 0) {
273 wl_buffer_get_iov(&connection->out, iov, &count);
275 build_cmsg(&connection->fds_out, cmsg, &clen);
280 msg.msg_iovlen = count;
281 msg.msg_control = cmsg;
282 msg.msg_controllen = clen;
286 len = sendmsg(connection->fd, &msg,
287 MSG_NOSIGNAL | MSG_DONTWAIT);
288 } while (len == -1 && errno == EINTR);
293 close_fds(&connection->fds_out, MAX_FDS_OUT);
295 connection->out.tail += len;
298 connection->want_flush = 0;
300 return connection->out.head - tail;
304 wl_connection_read(struct wl_connection *connection)
311 if (wl_buffer_size(&connection->in) >= sizeof(connection->in.data)) {
316 wl_buffer_put_iov(&connection->in, iov, &count);
321 msg.msg_iovlen = count;
322 msg.msg_control = cmsg;
323 msg.msg_controllen = sizeof cmsg;
327 len = wl_os_recvmsg_cloexec(connection->fd, &msg, 0);
328 } while (len < 0 && errno == EINTR);
333 ret = decode_cmsg(&connection->fds_in, &msg);
337 connection->in.head += len;
339 return connection->in.head - connection->in.tail;
343 wl_connection_write(struct wl_connection *connection,
344 const void *data, size_t count)
346 if (connection->out.head - connection->out.tail +
347 count > ARRAY_LENGTH(connection->out.data)) {
348 connection->want_flush = 1;
349 if (wl_connection_flush(connection) < 0)
353 wl_buffer_put(&connection->out, data, count);
354 connection->want_flush = 1;
360 wl_connection_queue(struct wl_connection *connection,
361 const void *data, size_t count)
363 if (connection->out.head - connection->out.tail +
364 count > ARRAY_LENGTH(connection->out.data)) {
365 connection->want_flush = 1;
366 if (wl_connection_flush(connection) < 0)
370 wl_buffer_put(&connection->out, data, count);
376 wl_message_count_arrays(const struct wl_message *message)
380 for (i = 0, arrays = 0; message->signature[i]; i++) {
381 if (message->signature[i] == 'a')
389 wl_connection_put_fd(struct wl_connection *connection, int32_t fd)
391 if (wl_buffer_size(&connection->fds_out) == MAX_FDS_OUT * sizeof fd) {
392 connection->want_flush = 1;
393 if (wl_connection_flush(connection) < 0)
397 wl_buffer_put(&connection->fds_out, &fd, sizeof fd);
403 get_next_argument(const char *signature, struct argument_details *details)
405 if (*signature == '?') {
406 details->nullable = 1;
409 details->nullable = 0;
411 details->type = *signature;
412 return signature + 1;
416 arg_count_for_signature(const char *signature)
420 if (*signature != '?')
428 wl_argument_from_va_list(const char *signature, union wl_argument *args,
429 int count, va_list ap)
432 const char *sig_iter;
433 struct argument_details arg;
435 sig_iter = signature;
436 for (i = 0; i < count; i++) {
437 sig_iter = get_next_argument(sig_iter, &arg);
441 args[i].i = va_arg(ap, int32_t);
444 args[i].u = va_arg(ap, uint32_t);
447 args[i].f = va_arg(ap, wl_fixed_t);
450 args[i].s = va_arg(ap, const char *);
453 args[i].o = va_arg(ap, struct wl_object *);
456 args[i].o = va_arg(ap, struct wl_object *);
459 args[i].a = va_arg(ap, struct wl_array *);
462 args[i].h = va_arg(ap, int32_t);
471 wl_closure_marshal(struct wl_object *sender, uint32_t opcode,
472 union wl_argument *args,
473 const struct wl_message *message)
475 struct wl_closure *closure;
476 struct wl_object *object;
477 int i, count, fd, dup_fd;
478 const char *signature;
479 struct argument_details arg;
481 count = arg_count_for_signature(message->signature);
482 if (count > WL_CLOSURE_MAX_ARGS) {
483 printf("too many args (%d)\n", count);
488 closure = malloc(sizeof *closure);
489 if (closure == NULL) {
494 memcpy(closure->args, args, count * sizeof *args);
496 signature = message->signature;
497 for (i = 0; i < count; i++) {
498 signature = get_next_argument(signature, &arg);
506 if (!arg.nullable && args[i].s == NULL)
510 if (!arg.nullable && args[i].o == NULL)
515 if (!arg.nullable && object == NULL)
518 closure->args[i].n = object ? object->id : 0;
521 if (!arg.nullable && args[i].a == NULL)
526 dup_fd = wl_os_dupfd_cloexec(fd, 0);
528 fprintf(stderr, "dup failed: %m");
531 closure->args[i].h = dup_fd;
534 fprintf(stderr, "unhandled format code: '%c'\n",
541 closure->sender_id = sender->id;
542 closure->opcode = opcode;
543 closure->message = message;
544 closure->count = count;
549 wl_closure_destroy(closure);
550 wl_log("error marshalling arguments for %s (signature %s): "
551 "null value passed for arg %i\n", message->name,
552 message->signature, i);
558 wl_closure_vmarshal(struct wl_object *sender, uint32_t opcode, va_list ap,
559 const struct wl_message *message)
561 union wl_argument args[WL_CLOSURE_MAX_ARGS];
563 wl_argument_from_va_list(message->signature, args,
564 WL_CLOSURE_MAX_ARGS, ap);
566 return wl_closure_marshal(sender, opcode, args, message);
570 wl_connection_demarshal(struct wl_connection *connection,
572 struct wl_map *objects,
573 const struct wl_message *message)
575 uint32_t *p, *next, *end, length, id;
578 unsigned int i, count, num_arrays;
579 const char *signature;
580 struct argument_details arg;
581 struct wl_closure *closure;
582 struct wl_array *array, *array_extra;
584 count = arg_count_for_signature(message->signature);
585 if (count > WL_CLOSURE_MAX_ARGS) {
586 printf("too many args (%d)\n", count);
588 wl_connection_consume(connection, size);
592 num_arrays = wl_message_count_arrays(message);
593 closure = malloc(sizeof *closure + size + num_arrays * sizeof *array);
594 if (closure == NULL) {
596 wl_connection_consume(connection, size);
600 array_extra = closure->extra;
601 p = (uint32_t *)(closure->extra + num_arrays);
602 end = p + size / sizeof *p;
604 wl_connection_copy(connection, p, size);
605 closure->sender_id = *p++;
606 closure->opcode = *p++ & 0x0000ffff;
608 signature = message->signature;
609 for (i = 0; i < count; i++) {
610 signature = get_next_argument(signature, &arg);
612 if (arg.type != 'h' && p + 1 > end) {
613 printf("message too short, "
614 "object (%d), message %s(%s)\n",
615 *p, message->name, message->signature);
622 closure->args[i].u = *p++;
625 closure->args[i].i = *p++;
628 closure->args[i].f = *p++;
634 closure->args[i].s = NULL;
638 next = p + DIV_ROUNDUP(length, sizeof *p);
640 printf("message too short, "
641 "object (%d), message %s(%s)\n",
642 closure->sender_id, message->name,
650 if (length > 0 && s[length - 1] != '\0') {
651 printf("string not nul-terminated, "
653 message->name, message->signature);
658 closure->args[i].s = s;
663 closure->args[i].n = id;
665 if (id == 0 && !arg.nullable) {
666 printf("NULL object received on non-nullable "
667 "type, message %s(%s)\n", message->name,
675 closure->args[i].n = id;
677 if (id == 0 && !arg.nullable) {
678 printf("NULL new ID received on non-nullable "
679 "type, message %s(%s)\n", message->name,
685 if (wl_map_reserve_new(objects, id) < 0) {
686 printf("not a valid new object id (%d), "
688 id, message->name, message->signature);
697 next = p + DIV_ROUNDUP(length, sizeof *p);
699 printf("message too short, "
700 "object (%d), message %s(%s)\n",
701 closure->sender_id, message->name,
707 array_extra->size = length;
708 array_extra->alloc = 0;
709 array_extra->data = p;
711 closure->args[i].a = array_extra++;
715 wl_buffer_copy(&connection->fds_in, &fd, sizeof fd);
716 connection->fds_in.tail += sizeof fd;
717 closure->args[i].h = fd;
720 printf("unknown type\n");
726 closure->count = count;
727 closure->message = message;
729 wl_connection_consume(connection, size);
734 wl_closure_destroy(closure);
735 wl_connection_consume(connection, size);
741 interface_equal(const struct wl_interface *a, const struct wl_interface *b)
743 /* In most cases the pointer equality test is sufficient.
744 * However, in some cases, depending on how things are split
745 * across shared objects, we can end up with multiple
746 * instances of the interface metadata constants. So if the
747 * pointers match, the interfaces are equal, if they don't
748 * match we have to compare the interface names. */
750 return a == b || strcmp(a->name, b->name) == 0;
754 wl_closure_lookup_objects(struct wl_closure *closure, struct wl_map *objects)
756 struct wl_object *object;
757 const struct wl_message *message;
758 const char *signature;
759 struct argument_details arg;
763 message = closure->message;
764 signature = message->signature;
765 count = arg_count_for_signature(signature);
766 for (i = 0; i < count; i++) {
767 signature = get_next_argument(signature, &arg);
770 id = closure->args[i].n;
771 closure->args[i].o = NULL;
773 object = wl_map_lookup(objects, id);
774 if (object == WL_ZOMBIE_OBJECT) {
775 /* references object we've already
776 * destroyed client side */
778 } else if (object == NULL && id != 0) {
779 printf("unknown object (%u), message %s(%s)\n",
780 id, message->name, message->signature);
786 if (object != NULL && message->types[i] != NULL &&
787 !interface_equal((object)->interface,
788 message->types[i])) {
789 printf("invalid object (%u), type (%s), "
791 id, (object)->interface->name,
792 message->name, message->signature);
796 closure->args[i].o = object;
804 convert_arguments_to_ffi(const char *signature, union wl_argument *args,
805 int count, ffi_type **ffi_types, void** ffi_args)
808 const char *sig_iter;
809 struct argument_details arg;
811 sig_iter = signature;
812 for (i = 0; i < count; i++) {
813 sig_iter = get_next_argument(sig_iter, &arg);
817 ffi_types[i] = &ffi_type_sint32;
818 ffi_args[i] = &args[i].i;
821 ffi_types[i] = &ffi_type_uint32;
822 ffi_args[i] = &args[i].u;
825 ffi_types[i] = &ffi_type_sint32;
826 ffi_args[i] = &args[i].f;
829 ffi_types[i] = &ffi_type_pointer;
830 ffi_args[i] = &args[i].s;
833 ffi_types[i] = &ffi_type_pointer;
834 ffi_args[i] = &args[i].o;
837 ffi_types[i] = &ffi_type_uint32;
838 ffi_args[i] = &args[i].n;
841 ffi_types[i] = &ffi_type_pointer;
842 ffi_args[i] = &args[i].a;
845 ffi_types[i] = &ffi_type_sint32;
846 ffi_args[i] = &args[i].h;
849 printf("unknown type\n");
858 wl_closure_invoke(struct wl_closure *closure,
859 struct wl_object *target, void (*func)(void), void *data)
863 ffi_type *ffi_types[WL_CLOSURE_MAX_ARGS + 2];
864 void * ffi_args[WL_CLOSURE_MAX_ARGS + 2];
866 count = arg_count_for_signature(closure->message->signature);
868 ffi_types[0] = &ffi_type_pointer;
870 ffi_types[1] = &ffi_type_pointer;
871 ffi_args[1] = ⌖
873 convert_arguments_to_ffi(closure->message->signature, closure->args,
874 count, ffi_types + 2, ffi_args + 2);
876 ffi_prep_cif(&cif, FFI_DEFAULT_ABI,
877 count + 2, &ffi_type_void, ffi_types);
879 ffi_call(&cif, func, NULL, ffi_args);
883 copy_fds_to_connection(struct wl_closure *closure,
884 struct wl_connection *connection)
886 const struct wl_message *message = closure->message;
888 struct argument_details arg;
889 const char *signature = message->signature;
892 count = arg_count_for_signature(signature);
893 for (i = 0; i < count; i++) {
894 signature = get_next_argument(signature, &arg);
898 fd = closure->args[i].h;
899 if (wl_connection_put_fd(connection, fd)) {
900 fprintf(stderr, "request could not be marshaled: "
901 "can't send file descriptor");
910 serialize_closure(struct wl_closure *closure, uint32_t *buffer,
913 const struct wl_message *message = closure->message;
914 unsigned int i, count, size;
916 struct argument_details arg;
917 const char *signature;
919 if (buffer_count < 2)
923 end = buffer + buffer_count;
925 signature = message->signature;
926 count = arg_count_for_signature(signature);
927 for (i = 0; i < count; i++) {
928 signature = get_next_argument(signature, &arg);
938 *p++ = closure->args[i].u;
941 *p++ = closure->args[i].i;
944 *p++ = closure->args[i].f;
947 *p++ = closure->args[i].o ? closure->args[i].o->id : 0;
950 *p++ = closure->args[i].n;
953 if (closure->args[i].s == NULL) {
958 size = strlen(closure->args[i].s) + 1;
961 if (p + DIV_ROUNDUP(size, sizeof *p) > end)
964 memcpy(p, closure->args[i].s, size);
965 p += DIV_ROUNDUP(size, sizeof *p);
968 if (closure->args[i].a == NULL) {
973 size = closure->args[i].a->size;
976 if (p + DIV_ROUNDUP(size, sizeof *p) > end)
979 memcpy(p, closure->args[i].a->data, size);
980 p += DIV_ROUNDUP(size, sizeof *p);
987 size = (p - buffer) * sizeof *p;
989 buffer[0] = closure->sender_id;
990 buffer[1] = size << 16 | (closure->opcode & 0x0000ffff);
1000 wl_closure_send(struct wl_closure *closure, struct wl_connection *connection)
1002 uint32_t buffer[256];
1005 if (copy_fds_to_connection(closure, connection))
1008 size = serialize_closure(closure, buffer, 256);
1012 return wl_connection_write(connection, buffer, size);
1016 wl_closure_queue(struct wl_closure *closure, struct wl_connection *connection)
1018 uint32_t buffer[256];
1021 if (copy_fds_to_connection(closure, connection))
1024 size = serialize_closure(closure, buffer, 256);
1028 return wl_connection_queue(connection, buffer, size);
1032 wl_closure_print(struct wl_closure *closure, struct wl_object *target, int send)
1035 struct argument_details arg;
1036 const char *signature = closure->message->signature;
1040 clock_gettime(CLOCK_REALTIME, &tp);
1041 time = (tp.tv_sec * 1000000L) + (tp.tv_nsec / 1000);
1043 fprintf(stderr, "[%10.3f] %s%s@%u.%s(",
1046 target->interface->name, target->id,
1047 closure->message->name);
1049 for (i = 0; i < closure->count; i++) {
1050 signature = get_next_argument(signature, &arg);
1052 fprintf(stderr, ", ");
1056 fprintf(stderr, "%u", closure->args[i].u);
1059 fprintf(stderr, "%d", closure->args[i].i);
1062 fprintf(stderr, "%f",
1063 wl_fixed_to_double(closure->args[i].f));
1066 fprintf(stderr, "\"%s\"", closure->args[i].s);
1069 if (closure->args[i].o)
1070 fprintf(stderr, "%s@%u",
1071 closure->args[i].o->interface->name,
1072 closure->args[i].o->id);
1074 fprintf(stderr, "nil");
1077 fprintf(stderr, "new id %s@",
1078 (closure->message->types[i]) ?
1079 closure->message->types[i]->name :
1081 if (closure->args[i].n != 0)
1082 fprintf(stderr, "%u", closure->args[i].n);
1084 fprintf(stderr, "nil");
1087 fprintf(stderr, "array");
1090 fprintf(stderr, "fd %d", closure->args[i].h);
1095 fprintf(stderr, ")\n");
1099 wl_closure_destroy(struct wl_closure *closure)