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;
60 wl_connection_update_func_t update;
61 struct wl_closure receive_closure, send_closure;
68 struct wl_object *object;
70 struct wl_array *array;
74 wl_buffer_put(struct wl_buffer *b, const void *data, size_t count)
79 if (head + count <= sizeof b->data) {
80 memcpy(b->data + head, data, count);
82 size = sizeof b->data - head;
83 memcpy(b->data + head, data, size);
84 memcpy(b->data, (const char *) data + size, count - size);
91 wl_buffer_put_iov(struct wl_buffer *b, struct iovec *iov, int *count)
98 iov[0].iov_base = b->data + head;
99 iov[0].iov_len = tail - head;
101 } else if (tail == 0) {
102 iov[0].iov_base = b->data + head;
103 iov[0].iov_len = sizeof b->data - head;
106 iov[0].iov_base = b->data + head;
107 iov[0].iov_len = sizeof b->data - head;
108 iov[1].iov_base = b->data;
109 iov[1].iov_len = tail;
115 wl_buffer_get_iov(struct wl_buffer *b, struct iovec *iov, int *count)
119 head = MASK(b->head);
120 tail = MASK(b->tail);
122 iov[0].iov_base = b->data + tail;
123 iov[0].iov_len = head - tail;
125 } else if (head == 0) {
126 iov[0].iov_base = b->data + tail;
127 iov[0].iov_len = sizeof b->data - tail;
130 iov[0].iov_base = b->data + tail;
131 iov[0].iov_len = sizeof b->data - tail;
132 iov[1].iov_base = b->data;
133 iov[1].iov_len = head;
139 wl_buffer_copy(struct wl_buffer *b, void *data, size_t count)
143 tail = MASK(b->tail);
144 if (tail + count <= sizeof b->data) {
145 memcpy(data, b->data + tail, count);
147 size = sizeof b->data - tail;
148 memcpy(data, b->data + tail, size);
149 memcpy((char *) data + size, b->data, count - size);
154 wl_buffer_size(struct wl_buffer *b)
156 return b->head - b->tail;
159 struct wl_connection *
160 wl_connection_create(int fd,
161 wl_connection_update_func_t update,
164 struct wl_connection *connection;
166 connection = malloc(sizeof *connection);
167 if (connection == NULL)
169 memset(connection, 0, sizeof *connection);
171 connection->update = update;
172 connection->data = data;
174 connection->update(connection,
175 WL_CONNECTION_READABLE,
182 wl_connection_destroy(struct wl_connection *connection)
184 close(connection->fd);
189 wl_connection_copy(struct wl_connection *connection, void *data, size_t size)
191 wl_buffer_copy(&connection->in, data, size);
195 wl_connection_consume(struct wl_connection *connection, size_t size)
197 connection->in.tail += size;
201 build_cmsg(struct wl_buffer *buffer, char *data, int *clen)
203 struct cmsghdr *cmsg;
206 size = buffer->head - buffer->tail;
208 cmsg = (struct cmsghdr *) data;
209 cmsg->cmsg_level = SOL_SOCKET;
210 cmsg->cmsg_type = SCM_RIGHTS;
211 cmsg->cmsg_len = CMSG_LEN(size);
212 wl_buffer_copy(buffer, CMSG_DATA(cmsg), size);
213 *clen = cmsg->cmsg_len;
220 close_fds(struct wl_buffer *buffer)
222 int fds[MAX_FDS_OUT], i, count;
225 size = buffer->head - buffer->tail;
229 wl_buffer_copy(buffer, fds, size);
230 count = size / sizeof fds[0];
231 for (i = 0; i < count; i++)
233 buffer->tail += size;
237 decode_cmsg(struct wl_buffer *buffer, struct msghdr *msg)
239 struct cmsghdr *cmsg;
242 for (cmsg = CMSG_FIRSTHDR(msg); cmsg != NULL;
243 cmsg = CMSG_NXTHDR(msg, cmsg)) {
244 if (cmsg->cmsg_level == SOL_SOCKET &&
245 cmsg->cmsg_type == SCM_RIGHTS) {
246 size = cmsg->cmsg_len - CMSG_LEN(0);
247 wl_buffer_put(buffer, CMSG_DATA(cmsg), size);
253 wl_connection_data(struct wl_connection *connection, uint32_t mask)
258 int len, count, clen;
260 if (mask & WL_CONNECTION_WRITABLE) {
261 wl_buffer_get_iov(&connection->out, iov, &count);
263 build_cmsg(&connection->fds_out, cmsg, &clen);
268 msg.msg_iovlen = count;
269 msg.msg_control = cmsg;
270 msg.msg_controllen = clen;
274 len = sendmsg(connection->fd, &msg,
275 MSG_NOSIGNAL | MSG_DONTWAIT);
276 } while (len < 0 && errno == EINTR);
278 if (len == -1 && errno == EPIPE) {
280 } else if (len < 0) {
282 "write error for connection %p, fd %d: %m\n",
283 connection, connection->fd);
287 close_fds(&connection->fds_out);
289 connection->out.tail += len;
290 if (connection->out.tail == connection->out.head &&
291 connection->write_signalled) {
292 connection->update(connection,
293 WL_CONNECTION_READABLE,
295 connection->write_signalled = 0;
299 if (mask & WL_CONNECTION_READABLE) {
300 wl_buffer_put_iov(&connection->in, iov, &count);
305 msg.msg_iovlen = count;
306 msg.msg_control = cmsg;
307 msg.msg_controllen = sizeof cmsg;
311 len = wl_os_recvmsg_cloexec(connection->fd, &msg, 0);
312 } while (len < 0 && errno == EINTR);
316 "read error from connection %p: %m (%d)\n",
319 } else if (len == 0) {
320 /* FIXME: Handle this better? */
324 decode_cmsg(&connection->fds_in, &msg);
326 connection->in.head += len;
329 return connection->in.head - connection->in.tail;
333 wl_connection_write(struct wl_connection *connection,
334 const void *data, size_t count)
336 if (connection->out.head - connection->out.tail +
337 count > ARRAY_LENGTH(connection->out.data))
338 if (wl_connection_data(connection, WL_CONNECTION_WRITABLE))
341 wl_buffer_put(&connection->out, data, count);
343 if (!connection->write_signalled) {
344 connection->update(connection,
345 WL_CONNECTION_READABLE |
346 WL_CONNECTION_WRITABLE,
348 connection->write_signalled = 1;
355 wl_connection_queue(struct wl_connection *connection,
356 const void *data, size_t count)
358 if (connection->out.head - connection->out.tail +
359 count > ARRAY_LENGTH(connection->out.data))
360 if (wl_connection_data(connection, WL_CONNECTION_WRITABLE))
363 wl_buffer_put(&connection->out, data, count);
369 wl_message_size_extra(const struct wl_message *message)
373 for (i = 0, extra = 0; message->signature[i]; i++) {
375 switch (message->signature[i]) {
379 extra += sizeof (void *);
382 extra += sizeof (void *) + sizeof (struct wl_array);
385 extra += sizeof (int);
396 wl_connection_put_fd(struct wl_connection *connection, int32_t fd)
398 if (wl_buffer_size(&connection->fds_out) == MAX_FDS_OUT * sizeof fd)
399 if (wl_connection_data(connection, WL_CONNECTION_WRITABLE))
402 wl_buffer_put(&connection->fds_out, &fd, sizeof fd);
408 get_next_argument(const char *signature, struct argument_details *details)
410 if (*signature == '?') {
411 details->nullable = 1;
414 details->nullable = 0;
416 details->type = *signature;
417 return signature + 1;
421 arg_count_for_signature(const char *signature)
425 if (*signature != '?')
433 wl_closure_vmarshal(struct wl_object *sender,
434 uint32_t opcode, va_list ap,
435 const struct wl_message *message)
437 struct wl_closure *closure;
438 struct wl_object **objectp, *object;
439 uint32_t length, aligned, *p, *start, size, *end;
441 struct wl_array **arrayp, *array;
443 const char *signature = message->signature;
444 struct argument_details arg;
446 int i, count, fd, extra_size, *fd_ptr;
448 /* FIXME: Match old fixed allocation for now */
449 closure = malloc(sizeof *closure + 1024);
453 extra_size = wl_message_size_extra(message);
454 count = arg_count_for_signature(signature) + 2;
455 extra = (char *) closure->buffer;
456 start = &closure->buffer[DIV_ROUNDUP(extra_size, sizeof *p)];
457 end = &closure->buffer[256];
460 closure->types[0] = &ffi_type_pointer;
461 closure->types[1] = &ffi_type_pointer;
463 for (i = 2; i < count; i++) {
464 signature = get_next_argument(signature, &arg);
468 closure->types[i] = &ffi_type_sint32;
469 closure->args[i] = p;
472 *p++ = va_arg(ap, wl_fixed_t);
475 closure->types[i] = &ffi_type_uint32;
476 closure->args[i] = p;
479 *p++ = va_arg(ap, uint32_t);
482 closure->types[i] = &ffi_type_sint32;
483 closure->args[i] = p;
486 *p++ = va_arg(ap, int32_t);
489 closure->types[i] = &ffi_type_pointer;
490 closure->args[i] = extra;
491 sp = (const char **) extra;
494 s = va_arg(ap, const char *);
496 if (!arg.nullable && s == NULL)
499 length = s ? strlen(s) + 1: 0;
500 aligned = (length + 3) & ~3;
501 if (p + aligned / sizeof *p + 1 > end)
506 *sp = (const char *) p;
510 memcpy(p, s, length);
511 memset((char *) p + length, 0, aligned - length);
512 p += aligned / sizeof *p;
515 closure->types[i] = &ffi_type_pointer;
516 closure->args[i] = extra;
517 objectp = (struct wl_object **) extra;
518 extra += sizeof *objectp;
520 object = va_arg(ap, struct wl_object *);
522 if (!arg.nullable && object == NULL)
528 *p++ = object ? object->id : 0;
532 closure->types[i] = &ffi_type_uint32;
533 closure->args[i] = p;
534 object = va_arg(ap, struct wl_object *);
538 if (!arg.nullable && object == NULL)
541 *p++ = object ? object->id : 0;
545 closure->types[i] = &ffi_type_pointer;
546 closure->args[i] = extra;
547 arrayp = (struct wl_array **) extra;
548 extra += sizeof *arrayp;
550 *arrayp = (struct wl_array *) extra;
551 extra += sizeof **arrayp;
553 array = va_arg(ap, struct wl_array *);
555 if (!arg.nullable && array == NULL)
558 if (array == NULL || array->size == 0) {
564 if (p + DIV_ROUNDUP(array->size, sizeof *p) + 1 > end)
567 memcpy(p, array->data, array->size);
569 (*arrayp)->size = array->size;
570 (*arrayp)->alloc = array->alloc;
573 p += DIV_ROUNDUP(array->size, sizeof *p);
577 closure->types[i] = &ffi_type_sint;
578 closure->args[i] = extra;
579 fd_ptr = (int *) extra;
580 extra += sizeof *fd_ptr;
582 fd = va_arg(ap, int);
583 dup_fd = wl_os_dupfd_cloexec(fd, 0);
585 fprintf(stderr, "dup failed: %m");
591 fprintf(stderr, "unhandled format code: '%c'\n",
598 size = (p - start) * sizeof *p;
599 start[0] = sender->id;
600 start[1] = opcode | (size << 16);
602 closure->start = start;
603 closure->message = message;
604 closure->count = count;
606 ffi_prep_cif(&closure->cif, FFI_DEFAULT_ABI,
607 closure->count, &ffi_type_void, closure->types);
612 printf("request too big to marshal, maximum size is %zu\n",
613 sizeof closure->buffer);
620 wl_log("error marshalling arguments for %s:%i.%s (signature %s): "
621 "null value passed for arg %i\n",
622 sender->interface->name, sender->id, message->name,
623 message->signature, i);
629 wl_connection_demarshal(struct wl_connection *connection,
631 struct wl_map *objects,
632 const struct wl_message *message)
634 uint32_t *p, *next, *end, length, **id;
637 unsigned int i, count, extra_space;
638 const char *signature = message->signature;
639 struct argument_details arg;
640 struct wl_object **object;
641 struct wl_array **array;
642 struct wl_closure *closure;
644 count = arg_count_for_signature(signature) + 2;
645 if (count > ARRAY_LENGTH(closure->types)) {
646 printf("too many args (%d)\n", count);
648 wl_connection_consume(connection, size);
652 extra_space = wl_message_size_extra(message);
653 closure = malloc(sizeof *closure + 8 + size + extra_space);
657 closure->message = message;
658 closure->types[0] = &ffi_type_pointer;
659 closure->types[1] = &ffi_type_pointer;
660 closure->start = closure->buffer;
662 wl_connection_copy(connection, closure->buffer, size);
663 p = &closure->buffer[2];
664 end = (uint32_t *) ((char *) p + size);
665 extra = (char *) end;
666 for (i = 2; i < count; i++) {
667 signature = get_next_argument(signature, &arg);
670 printf("message too short, "
671 "object (%d), message %s(%s)\n",
672 *p, message->name, message->signature);
679 closure->types[i] = &ffi_type_uint32;
680 closure->args[i] = p++;
683 closure->types[i] = &ffi_type_sint32;
684 closure->args[i] = p++;
687 closure->types[i] = &ffi_type_sint32;
688 closure->args[i] = p++;
691 closure->types[i] = &ffi_type_pointer;
694 next = p + DIV_ROUNDUP(length, sizeof *p);
696 printf("message too short, "
697 "object (%d), message %s(%s)\n",
698 *p, message->name, message->signature);
705 closure->args[i] = s;
713 if (length > 0 && (*s)[length - 1] != '\0') {
714 printf("string not nul-terminated, "
716 message->name, message->signature);
723 closure->types[i] = &ffi_type_pointer;
724 object = (struct wl_object **) extra;
725 extra += sizeof *object;
726 closure->args[i] = object;
728 if (*p == 0 && !arg.nullable) {
729 printf("NULL new ID received on non-nullable "
730 "type, message %s(%s)\n", message->name,
737 *object = wl_map_lookup(objects, *p);
738 if (*object == WL_ZOMBIE_OBJECT) {
739 /* references object we've already
740 * destroyed client side */
742 } else if (*object == NULL && *p != 0) {
743 printf("unknown object (%u), message %s(%s)\n",
744 *p, message->name, message->signature);
750 if (*object != NULL && message->types[i-2] != NULL &&
751 (*object)->interface != message->types[i-2]) {
752 printf("invalid object (%u), type (%s), "
754 *p, (*object)->interface->name,
755 message->name, message->signature);
763 closure->types[i] = &ffi_type_pointer;
764 id = (uint32_t **) extra;
766 closure->args[i] = id;
769 if (*id == 0 && !arg.nullable) {
770 printf("NULL new ID received on non-nullable "
771 "type, message %s(%s)\n", message->name,
777 if (wl_map_reserve_new(objects, *p) < 0) {
778 printf("not a valid new object id (%d), "
780 *p, message->name, message->signature);
788 closure->types[i] = &ffi_type_pointer;
791 next = p + DIV_ROUNDUP(length, sizeof *p);
793 printf("message too short, "
794 "object (%d), message %s(%s)\n",
795 *p, message->name, message->signature);
800 array = (struct wl_array **) extra;
801 extra += sizeof *array;
802 closure->args[i] = array;
804 *array = (struct wl_array *) extra;
805 extra += sizeof **array;
807 (*array)->size = length;
813 closure->types[i] = &ffi_type_sint;
817 closure->args[i] = fd;
819 wl_buffer_copy(&connection->fds_in, fd, sizeof *fd);
820 connection->fds_in.tail += sizeof *fd;
823 printf("unknown type\n");
831 ffi_prep_cif(&closure->cif, FFI_DEFAULT_ABI,
832 closure->count, &ffi_type_void, closure->types);
834 wl_connection_consume(connection, size);
840 wl_closure_destroy(closure);
841 wl_connection_consume(connection, size);
847 wl_closure_invoke(struct wl_closure *closure,
848 struct wl_object *target, void (*func)(void), void *data)
852 closure->args[0] = &data;
853 closure->args[1] = ⌖
855 ffi_call(&closure->cif, func, &result, closure->args);
859 copy_fds_to_connection(struct wl_closure *closure,
860 struct wl_connection *connection)
862 const struct wl_message *message = closure->message;
864 struct argument_details arg;
865 const char *signature = message->signature;
868 count = arg_count_for_signature(signature) + 2;
869 for (i = 2; i < count; i++) {
870 signature = get_next_argument(signature, &arg);
874 fd = closure->args[i];
875 if (wl_connection_put_fd(connection, *fd)) {
876 fprintf(stderr, "request could not be marshaled: "
877 "can't send file descriptor");
886 wl_closure_send(struct wl_closure *closure, struct wl_connection *connection)
890 if (copy_fds_to_connection(closure, connection))
893 size = closure->start[1] >> 16;
895 return wl_connection_write(connection, closure->start, size);
899 wl_closure_queue(struct wl_closure *closure, struct wl_connection *connection)
903 if (copy_fds_to_connection(closure, connection))
906 size = closure->start[1] >> 16;
908 return wl_connection_queue(connection, closure->start, size);
912 wl_closure_print(struct wl_closure *closure, struct wl_object *target, int send)
914 union wl_value *value;
917 struct argument_details arg;
918 const char *signature = closure->message->signature;
922 clock_gettime(CLOCK_REALTIME, &tp);
923 time = (tp.tv_sec * 1000000L) + (tp.tv_nsec / 1000);
925 fprintf(stderr, "[%10.3f] %s%s@%u.%s(",
928 target->interface->name, target->id,
929 closure->message->name);
931 for (i = 2; i < closure->count; i++) {
932 signature = get_next_argument(signature, &arg);
934 fprintf(stderr, ", ");
936 value = closure->args[i];
939 fprintf(stderr, "%u", value->uint32);
942 si = (int32_t) value->uint32;
943 fprintf(stderr, "%d", si);
946 si = (int32_t) value->uint32;
947 fprintf(stderr, "%f", wl_fixed_to_double(si));
950 fprintf(stderr, "\"%s\"", value->string);
954 fprintf(stderr, "%s@%u",
955 value->object->interface->name,
958 fprintf(stderr, "nil");
961 fprintf(stderr, "new id %s@",
962 (closure->message->types[i - 2]) ?
963 closure->message->types[i - 2]->name :
965 if (send && value->new_id != 0)
966 fprintf(stderr, "%u", value->new_id);
967 else if (!send && value->object != NULL)
968 fprintf(stderr, "%u",
969 *((uint32_t *)value->object));
971 fprintf(stderr, "nil");
974 fprintf(stderr, "array");
977 fprintf(stderr, "fd %d", value->uint32);
982 fprintf(stderr, ")\n");
986 wl_closure_destroy(struct wl_closure *closure)