1 /* 2 * Copyright 2008 Kristian Hgsberg 3 * Copyright 2013 Jason Ekstrand 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining 6 * a copy of this software and associated documentation files (the 7 * "Software"), to deal in the Software without restriction, including 8 * without limitation the rights to use, copy, modify, merge, publish, 9 * distribute, sublicense, and/or sell copies of the Software, and to 10 * permit persons to whom the Software is furnished to do so, subject to 11 * the following conditions: 12 * 13 * The above copyright notice and this permission notice (including the 14 * next paragraph) shall be included in all copies or substantial 15 * portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 21 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 22 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 24 * SOFTWARE. 25 */ 26 27 #define _GNU_SOURCE 28 29 #include <math.h> 30 #include <stdlib.h> 31 #include <stdint.h> 32 #include <string.h> 33 #include <stdio.h> 34 #include <errno.h> 35 #include <sys/uio.h> 36 #include <fcntl.h> 37 #include <unistd.h> 38 #include <sys/types.h> 39 #include <sys/socket.h> 40 #include <time.h> 41 #include <ffi.h> 42 43 #include "wayland-util.h" 44 #include "wayland-private.h" 45 #include "wayland-os.h" 46 47 #define DIV_ROUNDUP(n, a) ( ((n) + ((a) - 1)) / (a) ) 48 49 struct wl_buffer { 50 char data[4096]; 51 uint32_t head, tail; 52 }; 53 54 #define MASK(i) ((i) & 4095) 55 56 #define MAX_FDS_OUT 28 57 #define CLEN (CMSG_LEN(MAX_FDS_OUT * sizeof(int32_t))) 58 59 struct wl_connection { 60 struct wl_buffer in, out; 61 struct wl_buffer fds_in, fds_out; 62 int fd; 63 int want_flush; 64 }; 65 66 static int 67 wl_buffer_put(struct wl_buffer *b, const void *data, size_t count) 68 { 69 uint32_t head, size; 70 71 if (count > sizeof(b->data)) { 72 wl_log("Data too big for buffer (%d > %d).\n", 73 count, sizeof(b->data)); 74 errno = E2BIG; 75 return -1; 76 } 77 78 head = MASK(b->head); 79 if (head + count <= sizeof b->data) { 80 memcpy(b->data + head, data, count); 81 } else { 82 size = sizeof b->data - head; 83 memcpy(b->data + head, data, size); 84 memcpy(b->data, (const char *) data + size, count - size); 85 } 86 87 b->head += count; 88 89 return 0; 90 } 91 92 static void 93 wl_buffer_put_iov(struct wl_buffer *b, struct iovec *iov, int *count) 94 { 95 uint32_t 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 uint32_t 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 uint32_t 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 static uint32_t 156 wl_buffer_size(struct wl_buffer *b) 157 { 158 return b->head - b->tail; 159 } 160 161 struct wl_connection * 162 wl_connection_create(int fd) 163 { 164 struct wl_connection *connection; 165 166 connection = zalloc(sizeof *connection); 167 if (connection == NULL) 168 return NULL; 169 170 connection->fd = fd; 171 172 return connection; 173 } 174 175 static void 176 close_fds(struct wl_buffer *buffer, int max) 177 { 178 int32_t fds[sizeof(buffer->data) / sizeof(int32_t)], i, count; 179 size_t size; 180 181 size = buffer->head - buffer->tail; 182 if (size == 0) 183 return; 184 185 wl_buffer_copy(buffer, fds, size); 186 count = size / sizeof fds[0]; 187 if (max > 0 && max < count) 188 count = max; 189 for (i = 0; i < count; i++) 190 close(fds[i]); 191 buffer->tail += size; 192 } 193 194 int 195 wl_connection_destroy(struct wl_connection *connection) 196 { 197 int fd = connection->fd; 198 199 close_fds(&connection->fds_out, -1); 200 close_fds(&connection->fds_in, -1); 201 free(connection); 202 203 return fd; 204 } 205 206 void 207 wl_connection_copy(struct wl_connection *connection, void *data, size_t size) 208 { 209 wl_buffer_copy(&connection->in, data, size); 210 } 211 212 void 213 wl_connection_consume(struct wl_connection *connection, size_t size) 214 { 215 connection->in.tail += size; 216 } 217 218 static void 219 build_cmsg(struct wl_buffer *buffer, char *data, int *clen) 220 { 221 struct cmsghdr *cmsg; 222 size_t size; 223 224 size = buffer->head - buffer->tail; 225 if (size > MAX_FDS_OUT * sizeof(int32_t)) 226 size = MAX_FDS_OUT * sizeof(int32_t); 227 228 if (size > 0) { 229 cmsg = (struct cmsghdr *) data; 230 cmsg->cmsg_level = SOL_SOCKET; 231 cmsg->cmsg_type = SCM_RIGHTS; 232 cmsg->cmsg_len = CMSG_LEN(size); 233 wl_buffer_copy(buffer, CMSG_DATA(cmsg), size); 234 *clen = cmsg->cmsg_len; 235 } else { 236 *clen = 0; 237 } 238 } 239 240 static int 241 decode_cmsg(struct wl_buffer *buffer, struct msghdr *msg) 242 { 243 struct cmsghdr *cmsg; 244 size_t size, max, i; 245 int overflow = 0; 246 247 for (cmsg = CMSG_FIRSTHDR(msg); cmsg != NULL; 248 cmsg = CMSG_NXTHDR(msg, cmsg)) { 249 if (cmsg->cmsg_level != SOL_SOCKET || 250 cmsg->cmsg_type != SCM_RIGHTS) 251 continue; 252 253 size = cmsg->cmsg_len - CMSG_LEN(0); 254 max = sizeof(buffer->data) - wl_buffer_size(buffer); 255 if (size > max || overflow) { 256 overflow = 1; 257 size /= sizeof(int32_t); 258 for (i = 0; i < size; i++) 259 close(((int*)CMSG_DATA(cmsg))[i]); 260 } else if (wl_buffer_put(buffer, CMSG_DATA(cmsg), size) < 0) { 261 return -1; 262 } 263 } 264 265 if (overflow) { 266 errno = EOVERFLOW; 267 return -1; 268 } 269 270 return 0; 271 } 272 273 int 274 wl_connection_flush(struct wl_connection *connection) 275 { 276 struct iovec iov[2]; 277 struct msghdr msg; 278 char cmsg[CLEN]; 279 int len = 0, count, clen; 280 uint32_t tail; 281 282 if (!connection->want_flush) 283 return 0; 284 285 tail = connection->out.tail; 286 while (connection->out.head - connection->out.tail > 0) { 287 wl_buffer_get_iov(&connection->out, iov, &count); 288 289 build_cmsg(&connection->fds_out, cmsg, &clen); 290 291 msg.msg_name = NULL; 292 msg.msg_namelen = 0; 293 msg.msg_iov = iov; 294 msg.msg_iovlen = count; 295 msg.msg_control = (clen > 0) ? cmsg : NULL; 296 msg.msg_controllen = clen; 297 msg.msg_flags = 0; 298 299 do { 300 len = sendmsg(connection->fd, &msg, 301 MSG_NOSIGNAL | MSG_DONTWAIT); 302 } while (len == -1 && errno == EINTR); 303 304 if (len == -1) 305 return -1; 306 307 close_fds(&connection->fds_out, MAX_FDS_OUT); 308 309 connection->out.tail += len; 310 } 311 312 connection->want_flush = 0; 313 314 return connection->out.head - tail; 315 } 316 317 uint32_t 318 wl_connection_pending_input(struct wl_connection *connection) 319 { 320 return wl_buffer_size(&connection->in); 321 } 322 323 int 324 wl_connection_read(struct wl_connection *connection) 325 { 326 struct iovec iov[2]; 327 struct msghdr msg; 328 char cmsg[CLEN]; 329 int len, count, ret; 330 331 if (wl_buffer_size(&connection->in) >= sizeof(connection->in.data)) { 332 errno = EOVERFLOW; 333 return -1; 334 } 335 336 wl_buffer_put_iov(&connection->in, iov, &count); 337 338 msg.msg_name = NULL; 339 msg.msg_namelen = 0; 340 msg.msg_iov = iov; 341 msg.msg_iovlen = count; 342 msg.msg_control = cmsg; 343 msg.msg_controllen = sizeof cmsg; 344 msg.msg_flags = 0; 345 346 do { 347 len = wl_os_recvmsg_cloexec(connection->fd, &msg, MSG_DONTWAIT); 348 } while (len < 0 && errno == EINTR); 349 350 if (len <= 0) 351 return len; 352 353 ret = decode_cmsg(&connection->fds_in, &msg); 354 if (ret) 355 return -1; 356 357 connection->in.head += len; 358 359 return wl_connection_pending_input(connection); 360 } 361 362 int 363 wl_connection_write(struct wl_connection *connection, 364 const void *data, size_t count) 365 { 366 if (connection->out.head - connection->out.tail + 367 count > ARRAY_LENGTH(connection->out.data)) { 368 connection->want_flush = 1; 369 if (wl_connection_flush(connection) < 0) 370 return -1; 371 } 372 373 if (wl_buffer_put(&connection->out, data, count) < 0) 374 return -1; 375 376 connection->want_flush = 1; 377 378 return 0; 379 } 380 381 int 382 wl_connection_queue(struct wl_connection *connection, 383 const void *data, size_t count) 384 { 385 if (connection->out.head - connection->out.tail + 386 count > ARRAY_LENGTH(connection->out.data)) { 387 connection->want_flush = 1; 388 if (wl_connection_flush(connection) < 0) 389 return -1; 390 } 391 392 return wl_buffer_put(&connection->out, data, count); 393 } 394 395 int 396 wl_message_count_arrays(const struct wl_message *message) 397 { 398 int i, arrays; 399 400 for (i = 0, arrays = 0; message->signature[i]; i++) { 401 if (message->signature[i] == 'a') 402 arrays++; 403 } 404 405 return arrays; 406 } 407 408 int 409 wl_connection_get_fd(struct wl_connection *connection) 410 { 411 return connection->fd; 412 } 413 414 static int 415 wl_connection_put_fd(struct wl_connection *connection, int32_t fd) 416 { 417 if (wl_buffer_size(&connection->fds_out) == MAX_FDS_OUT * sizeof fd) { 418 connection->want_flush = 1; 419 if (wl_connection_flush(connection) < 0) 420 return -1; 421 } 422 423 return wl_buffer_put(&connection->fds_out, &fd, sizeof fd); 424 } 425 426 const char * 427 get_next_argument(const char *signature, struct argument_details *details) 428 { 429 details->nullable = 0; 430 for(; *signature; ++signature) { 431 switch(*signature) { 432 case 'i': 433 case 'u': 434 case 'f': 435 case 's': 436 case 'o': 437 case 'n': 438 case 'a': 439 case 'h': 440 details->type = *signature; 441 return signature + 1; 442 case '?': 443 details->nullable = 1; 444 } 445 } 446 details->type = '\0'; 447 return signature; 448 } 449 450 int 451 arg_count_for_signature(const char *signature) 452 { 453 int count = 0; 454 for(; *signature; ++signature) { 455 switch(*signature) { 456 case 'i': 457 case 'u': 458 case 'f': 459 case 's': 460 case 'o': 461 case 'n': 462 case 'a': 463 case 'h': 464 ++count; 465 } 466 } 467 return count; 468 } 469 470 int 471 wl_message_get_since(const struct wl_message *message) 472 { 473 int since; 474 475 since = atoi(message->signature); 476 477 if (since == 0) 478 since = 1; 479 480 return since; 481 } 482 483 void 484 wl_argument_from_va_list(const char *signature, union wl_argument *args, 485 int count, va_list ap) 486 { 487 int i; 488 const char *sig_iter; 489 struct argument_details arg; 490 491 sig_iter = signature; 492 for (i = 0; i < count; i++) { 493 sig_iter = get_next_argument(sig_iter, &arg); 494 495 switch(arg.type) { 496 case 'i': 497 args[i].i = va_arg(ap, int32_t); 498 break; 499 case 'u': 500 args[i].u = va_arg(ap, uint32_t); 501 break; 502 case 'f': 503 args[i].f = va_arg(ap, wl_fixed_t); 504 break; 505 case 's': 506 args[i].s = va_arg(ap, const char *); 507 break; 508 case 'o': 509 args[i].o = va_arg(ap, struct wl_object *); 510 break; 511 case 'n': 512 args[i].o = va_arg(ap, struct wl_object *); 513 break; 514 case 'a': 515 args[i].a = va_arg(ap, struct wl_array *); 516 break; 517 case 'h': 518 args[i].h = va_arg(ap, int32_t); 519 break; 520 case '\0': 521 return; 522 } 523 } 524 } 525 526 struct wl_closure * 527 wl_closure_marshal(struct wl_object *sender, uint32_t opcode, 528 union wl_argument *args, 529 const struct wl_message *message) 530 { 531 struct wl_closure *closure; 532 struct wl_object *object; 533 int i, count, fd, dup_fd; 534 const char *signature; 535 struct argument_details arg; 536 537 count = arg_count_for_signature(message->signature); 538 if (count > WL_CLOSURE_MAX_ARGS) { 539 wl_log("too many args (%d)\n", count); 540 errno = EINVAL; 541 return NULL; 542 } 543 544 closure = malloc(sizeof *closure); 545 if (closure == NULL) { 546 errno = ENOMEM; 547 return NULL; 548 } 549 550 memcpy(closure->args, args, count * sizeof *args); 551 552 signature = message->signature; 553 for (i = 0; i < count; i++) { 554 signature = get_next_argument(signature, &arg); 555 556 switch (arg.type) { 557 case 'f': 558 case 'u': 559 case 'i': 560 break; 561 case 's': 562 if (!arg.nullable && args[i].s == NULL) 563 goto err_null; 564 break; 565 case 'o': 566 if (!arg.nullable && args[i].o == NULL) 567 goto err_null; 568 break; 569 case 'n': 570 object = args[i].o; 571 if (!arg.nullable && object == NULL) 572 goto err_null; 573 574 closure->args[i].n = object ? object->id : 0; 575 break; 576 case 'a': 577 if (!arg.nullable && args[i].a == NULL) 578 goto err_null; 579 break; 580 case 'h': 581 fd = args[i].h; 582 dup_fd = wl_os_dupfd_cloexec(fd, 0); 583 if (dup_fd < 0) 584 wl_abort("dup failed: %s\n", strerror(errno)); 585 closure->args[i].h = dup_fd; 586 break; 587 default: 588 wl_abort("unhandled format code: '%c'\n", arg.type); 589 break; 590 } 591 } 592 593 closure->sender_id = sender->id; 594 closure->opcode = opcode; 595 closure->message = message; 596 closure->count = count; 597 598 return closure; 599 600 err_null: 601 wl_closure_destroy(closure); 602 wl_log("error marshalling arguments for %s (signature %s): " 603 "null value passed for arg %i\n", message->name, 604 message->signature, i); 605 errno = EINVAL; 606 return NULL; 607 } 608 609 struct wl_closure * 610 wl_closure_vmarshal(struct wl_object *sender, uint32_t opcode, va_list ap, 611 const struct wl_message *message) 612 { 613 union wl_argument args[WL_CLOSURE_MAX_ARGS]; 614 615 wl_argument_from_va_list(message->signature, args, 616 WL_CLOSURE_MAX_ARGS, ap); 617 618 return wl_closure_marshal(sender, opcode, args, message); 619 } 620 621 struct wl_closure * 622 wl_connection_demarshal(struct wl_connection *connection, 623 uint32_t size, 624 struct wl_map *objects, 625 const struct wl_message *message) 626 { 627 uint32_t *p, *next, *end, length, id; 628 int fd; 629 char *s; 630 unsigned int i, count, num_arrays; 631 const char *signature; 632 struct argument_details arg; 633 struct wl_closure *closure; 634 struct wl_array *array, *array_extra; 635 636 count = arg_count_for_signature(message->signature); 637 if (count > WL_CLOSURE_MAX_ARGS) { 638 wl_log("too many args (%d)\n", count); 639 errno = EINVAL; 640 wl_connection_consume(connection, size); 641 return NULL; 642 } 643 644 num_arrays = wl_message_count_arrays(message); 645 closure = malloc(sizeof *closure + size + num_arrays * sizeof *array); 646 if (closure == NULL) { 647 errno = ENOMEM; 648 wl_connection_consume(connection, size); 649 return NULL; 650 } 651 652 array_extra = closure->extra; 653 p = (uint32_t *)(closure->extra + num_arrays); 654 end = p + size / sizeof *p; 655 656 wl_connection_copy(connection, p, size); 657 closure->sender_id = *p++; 658 closure->opcode = *p++ & 0x0000ffff; 659 660 signature = message->signature; 661 for (i = 0; i < count; i++) { 662 signature = get_next_argument(signature, &arg); 663 664 if (arg.type != 'h' && p + 1 > end) { 665 wl_log("message too short, " 666 "object (%d), message %s(%s)\n", 667 *p, message->name, message->signature); 668 errno = EINVAL; 669 goto err; 670 } 671 672 switch (arg.type) { 673 case 'u': 674 closure->args[i].u = *p++; 675 break; 676 case 'i': 677 closure->args[i].i = *p++; 678 break; 679 case 'f': 680 closure->args[i].f = *p++; 681 break; 682 case 's': 683 length = *p++; 684 685 if (length == 0) { 686 closure->args[i].s = NULL; 687 break; 688 } 689 690 next = p + DIV_ROUNDUP(length, sizeof *p); 691 if (next > end) { 692 wl_log("message too short, " 693 "object (%d), message %s(%s)\n", 694 closure->sender_id, message->name, 695 message->signature); 696 errno = EINVAL; 697 goto err; 698 } 699 700 s = (char *) p; 701 702 if (length > 0 && s[length - 1] != '\0') { 703 wl_log("string not nul-terminated, " 704 "message %s(%s)\n", 705 message->name, message->signature); 706 errno = EINVAL; 707 goto err; 708 } 709 710 closure->args[i].s = s; 711 p = next; 712 break; 713 case 'o': 714 id = *p++; 715 closure->args[i].n = id; 716 717 if (id == 0 && !arg.nullable) { 718 wl_log("NULL object received on non-nullable " 719 "type, message %s(%s)\n", message->name, 720 message->signature); 721 errno = EINVAL; 722 goto err; 723 } 724 break; 725 case 'n': 726 id = *p++; 727 closure->args[i].n = id; 728 729 if (id == 0 && !arg.nullable) { 730 wl_log("NULL new ID received on non-nullable " 731 "type, message %s(%s)\n", message->name, 732 message->signature); 733 errno = EINVAL; 734 goto err; 735 } 736 737 if (wl_map_reserve_new(objects, id) < 0) { 738 wl_log("not a valid new object id (%u), " 739 "message %s(%s)\n", 740 id, message->name, message->signature); 741 errno = EINVAL; 742 goto err; 743 } 744 745 break; 746 case 'a': 747 length = *p++; 748 749 next = p + DIV_ROUNDUP(length, sizeof *p); 750 if (next > end) { 751 wl_log("message too short, " 752 "object (%d), message %s(%s)\n", 753 closure->sender_id, message->name, 754 message->signature); 755 errno = EINVAL; 756 goto err; 757 } 758 759 array_extra->size = length; 760 array_extra->alloc = 0; 761 array_extra->data = p; 762 763 closure->args[i].a = array_extra++; 764 p = next; 765 break; 766 case 'h': 767 if (connection->fds_in.tail == connection->fds_in.head) { 768 wl_log("file descriptor expected, " 769 "object (%d), message %s(%s)\n", 770 closure->sender_id, message->name, 771 message->signature); 772 errno = EINVAL; 773 goto err; 774 } 775 776 wl_buffer_copy(&connection->fds_in, &fd, sizeof fd); 777 connection->fds_in.tail += sizeof fd; 778 closure->args[i].h = fd; 779 break; 780 default: 781 wl_abort("unknown type\n"); 782 break; 783 } 784 } 785 786 closure->count = count; 787 closure->message = message; 788 789 wl_connection_consume(connection, size); 790 791 return closure; 792 793 err: 794 wl_closure_destroy(closure); 795 wl_connection_consume(connection, size); 796 797 return NULL; 798 } 799 800 int 801 wl_closure_lookup_objects(struct wl_closure *closure, struct wl_map *objects) 802 { 803 struct wl_object *object; 804 const struct wl_message *message; 805 const char *signature; 806 struct argument_details arg; 807 int i, count; 808 uint32_t id; 809 810 message = closure->message; 811 signature = message->signature; 812 count = arg_count_for_signature(signature); 813 for (i = 0; i < count; i++) { 814 signature = get_next_argument(signature, &arg); 815 switch (arg.type) { 816 case 'o': 817 id = closure->args[i].n; 818 closure->args[i].o = NULL; 819 820 object = wl_map_lookup(objects, id); 821 if (object == WL_ZOMBIE_OBJECT) { 822 /* references object we've already 823 * destroyed client side */ 824 object = NULL; 825 } else if (object == NULL && id != 0) { 826 wl_log("unknown object (%u), message %s(%s)\n", 827 id, message->name, message->signature); 828 errno = EINVAL; 829 return -1; 830 } 831 832 if (object != NULL && message->types[i] != NULL && 833 !wl_interface_equal((object)->interface, 834 message->types[i])) { 835 wl_log("invalid object (%u), type (%s), " 836 "message %s(%s)\n", 837 id, (object)->interface->name, 838 message->name, message->signature); 839 errno = EINVAL; 840 return -1; 841 } 842 closure->args[i].o = object; 843 } 844 } 845 846 return 0; 847 } 848 849 static void 850 convert_arguments_to_ffi(const char *signature, uint32_t flags, 851 union wl_argument *args, 852 int count, ffi_type **ffi_types, void** ffi_args) 853 { 854 int i; 855 const char *sig_iter; 856 struct argument_details arg; 857 858 sig_iter = signature; 859 for (i = 0; i < count; i++) { 860 sig_iter = get_next_argument(sig_iter, &arg); 861 862 switch(arg.type) { 863 case 'i': 864 ffi_types[i] = &ffi_type_sint32; 865 ffi_args[i] = &args[i].i; 866 break; 867 case 'u': 868 ffi_types[i] = &ffi_type_uint32; 869 ffi_args[i] = &args[i].u; 870 break; 871 case 'f': 872 ffi_types[i] = &ffi_type_sint32; 873 ffi_args[i] = &args[i].f; 874 break; 875 case 's': 876 ffi_types[i] = &ffi_type_pointer; 877 ffi_args[i] = &args[i].s; 878 break; 879 case 'o': 880 ffi_types[i] = &ffi_type_pointer; 881 ffi_args[i] = &args[i].o; 882 break; 883 case 'n': 884 if (flags & WL_CLOSURE_INVOKE_CLIENT) { 885 ffi_types[i] = &ffi_type_pointer; 886 ffi_args[i] = &args[i].o; 887 } else { 888 ffi_types[i] = &ffi_type_uint32; 889 ffi_args[i] = &args[i].n; 890 } 891 break; 892 case 'a': 893 ffi_types[i] = &ffi_type_pointer; 894 ffi_args[i] = &args[i].a; 895 break; 896 case 'h': 897 ffi_types[i] = &ffi_type_sint32; 898 ffi_args[i] = &args[i].h; 899 break; 900 default: 901 wl_abort("unknown type\n"); 902 break; 903 } 904 } 905 } 906 907 void 908 wl_closure_invoke(struct wl_closure *closure, uint32_t flags, 909 struct wl_object *target, uint32_t opcode, void *data) 910 { 911 int count; 912 ffi_cif cif; 913 ffi_type *ffi_types[WL_CLOSURE_MAX_ARGS + 2]; 914 void * ffi_args[WL_CLOSURE_MAX_ARGS + 2]; 915 void (* const *implementation)(void); 916 917 count = arg_count_for_signature(closure->message->signature); 918 919 ffi_types[0] = &ffi_type_pointer; 920 ffi_args[0] = &data; 921 ffi_types[1] = &ffi_type_pointer; 922 ffi_args[1] = ⌖ 923 924 convert_arguments_to_ffi(closure->message->signature, flags, closure->args, 925 count, ffi_types + 2, ffi_args + 2); 926 927 ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 928 count + 2, &ffi_type_void, ffi_types); 929 930 implementation = target->implementation; 931 if (!implementation[opcode]) { 932 wl_abort("listener function for opcode %u of %s is NULL\n", 933 opcode, target->interface->name); 934 } 935 ffi_call(&cif, implementation[opcode], NULL, ffi_args); 936 } 937 938 void 939 wl_closure_dispatch(struct wl_closure *closure, wl_dispatcher_func_t dispatcher, 940 struct wl_object *target, uint32_t opcode) 941 { 942 dispatcher(target->implementation, target, opcode, closure->message, 943 closure->args); 944 } 945 946 static int 947 copy_fds_to_connection(struct wl_closure *closure, 948 struct wl_connection *connection) 949 { 950 const struct wl_message *message = closure->message; 951 uint32_t i, count; 952 struct argument_details arg; 953 const char *signature = message->signature; 954 int fd; 955 956 count = arg_count_for_signature(signature); 957 for (i = 0; i < count; i++) { 958 signature = get_next_argument(signature, &arg); 959 if (arg.type != 'h') 960 continue; 961 962 fd = closure->args[i].h; 963 if (wl_connection_put_fd(connection, fd)) { 964 wl_log("request could not be marshaled: " 965 "can't send file descriptor"); 966 return -1; 967 } 968 } 969 970 return 0; 971 } 972 973 974 static uint32_t 975 buffer_size_for_closure(struct wl_closure *closure) 976 { 977 const struct wl_message *message = closure->message; 978 int i, count; 979 struct argument_details arg; 980 const char *signature; 981 uint32_t size, buffer_size = 0; 982 983 signature = message->signature; 984 count = arg_count_for_signature(signature); 985 for (i = 0; i < count; i++) { 986 signature = get_next_argument(signature, &arg); 987 988 switch (arg.type) { 989 case 'h': 990 break; 991 case 'u': 992 case 'i': 993 case 'f': 994 case 'o': 995 case 'n': 996 buffer_size++; 997 break; 998 case 's': 999 if (closure->args[i].s == NULL) { 1000 buffer_size++; 1001 break; 1002 } 1003 1004 size = strlen(closure->args[i].s) + 1; 1005 buffer_size += 1 + DIV_ROUNDUP(size, sizeof(uint32_t)); 1006 break; 1007 case 'a': 1008 if (closure->args[i].a == NULL) { 1009 buffer_size++; 1010 break; 1011 } 1012 1013 size = closure->args[i].a->size; 1014 buffer_size += (1 + DIV_ROUNDUP(size, sizeof(uint32_t))); 1015 break; 1016 default: 1017 break; 1018 } 1019 } 1020 1021 return buffer_size + 2; 1022 } 1023 1024 static int 1025 serialize_closure(struct wl_closure *closure, uint32_t *buffer, 1026 size_t buffer_count) 1027 { 1028 const struct wl_message *message = closure->message; 1029 unsigned int i, count, size; 1030 uint32_t *p, *end; 1031 struct argument_details arg; 1032 const char *signature; 1033 1034 if (buffer_count < 2) 1035 goto overflow; 1036 1037 p = buffer + 2; 1038 end = buffer + buffer_count; 1039 1040 signature = message->signature; 1041 count = arg_count_for_signature(signature); 1042 for (i = 0; i < count; i++) { 1043 signature = get_next_argument(signature, &arg); 1044 1045 if (arg.type == 'h') 1046 continue; 1047 1048 if (p + 1 > end) 1049 goto overflow; 1050 1051 switch (arg.type) { 1052 case 'u': 1053 *p++ = closure->args[i].u; 1054 break; 1055 case 'i': 1056 *p++ = closure->args[i].i; 1057 break; 1058 case 'f': 1059 *p++ = closure->args[i].f; 1060 break; 1061 case 'o': 1062 *p++ = closure->args[i].o ? closure->args[i].o->id : 0; 1063 break; 1064 case 'n': 1065 *p++ = closure->args[i].n; 1066 break; 1067 case 's': 1068 if (closure->args[i].s == NULL) { 1069 *p++ = 0; 1070 break; 1071 } 1072 1073 size = strlen(closure->args[i].s) + 1; 1074 *p++ = size; 1075 1076 if (p + DIV_ROUNDUP(size, sizeof *p) > end) 1077 goto overflow; 1078 1079 memcpy(p, closure->args[i].s, size); 1080 p += DIV_ROUNDUP(size, sizeof *p); 1081 break; 1082 case 'a': 1083 if (closure->args[i].a == NULL) { 1084 *p++ = 0; 1085 break; 1086 } 1087 1088 size = closure->args[i].a->size; 1089 *p++ = size; 1090 1091 if (p + DIV_ROUNDUP(size, sizeof *p) > end) 1092 goto overflow; 1093 1094 memcpy(p, closure->args[i].a->data, size); 1095 p += DIV_ROUNDUP(size, sizeof *p); 1096 break; 1097 default: 1098 break; 1099 } 1100 } 1101 1102 size = (p - buffer) * sizeof *p; 1103 1104 buffer[0] = closure->sender_id; 1105 buffer[1] = size << 16 | (closure->opcode & 0x0000ffff); 1106 1107 return size; 1108 1109 overflow: 1110 errno = ERANGE; 1111 return -1; 1112 } 1113 1114 int 1115 wl_closure_send(struct wl_closure *closure, struct wl_connection *connection) 1116 { 1117 int size; 1118 uint32_t buffer_size; 1119 uint32_t *buffer; 1120 int result; 1121 1122 if (copy_fds_to_connection(closure, connection)) 1123 return -1; 1124 1125 buffer_size = buffer_size_for_closure(closure); 1126 buffer = zalloc(buffer_size * sizeof buffer[0]); 1127 if (buffer == NULL) 1128 return -1; 1129 1130 size = serialize_closure(closure, buffer, buffer_size); 1131 if (size < 0) { 1132 free(buffer); 1133 return -1; 1134 } 1135 1136 result = wl_connection_write(connection, buffer, size); 1137 free(buffer); 1138 1139 return result; 1140 } 1141 1142 int 1143 wl_closure_queue(struct wl_closure *closure, struct wl_connection *connection) 1144 { 1145 int size; 1146 uint32_t buffer_size; 1147 uint32_t *buffer; 1148 int result; 1149 1150 if (copy_fds_to_connection(closure, connection)) 1151 return -1; 1152 1153 buffer_size = buffer_size_for_closure(closure); 1154 buffer = malloc(buffer_size * sizeof buffer[0]); 1155 if (buffer == NULL) 1156 return -1; 1157 1158 size = serialize_closure(closure, buffer, buffer_size); 1159 if (size < 0) { 1160 free(buffer); 1161 return -1; 1162 } 1163 1164 result = wl_connection_queue(connection, buffer, size); 1165 free(buffer); 1166 1167 return result; 1168 } 1169 1170 void 1171 wl_closure_print(struct wl_closure *closure, struct wl_object *target, int send) 1172 { 1173 int i; 1174 struct argument_details arg; 1175 const char *signature = closure->message->signature; 1176 struct timespec tp; 1177 unsigned int time; 1178 1179 clock_gettime(CLOCK_REALTIME, &tp); 1180 time = (tp.tv_sec * 1000000L) + (tp.tv_nsec / 1000); 1181 1182 fprintf(stderr, "[%10.3f] %s%s@%u.%s(", 1183 time / 1000.0, 1184 send ? " -> " : "", 1185 target->interface->name, target->id, 1186 closure->message->name); 1187 1188 for (i = 0; i < closure->count; i++) { 1189 signature = get_next_argument(signature, &arg); 1190 if (i > 0) 1191 fprintf(stderr, ", "); 1192 1193 switch (arg.type) { 1194 case 'u': 1195 fprintf(stderr, "%u", closure->args[i].u); 1196 break; 1197 case 'i': 1198 fprintf(stderr, "%d", closure->args[i].i); 1199 break; 1200 case 'f': 1201 fprintf(stderr, "%f", 1202 wl_fixed_to_double(closure->args[i].f)); 1203 break; 1204 case 's': 1205 fprintf(stderr, "\"%s\"", closure->args[i].s); 1206 break; 1207 case 'o': 1208 if (closure->args[i].o) 1209 fprintf(stderr, "%s@%u", 1210 closure->args[i].o->interface->name, 1211 closure->args[i].o->id); 1212 else 1213 fprintf(stderr, "nil"); 1214 break; 1215 case 'n': 1216 fprintf(stderr, "new id %s@", 1217 (closure->message->types[i]) ? 1218 closure->message->types[i]->name : 1219 "[unknown]"); 1220 if (closure->args[i].n != 0) 1221 fprintf(stderr, "%u", closure->args[i].n); 1222 else 1223 fprintf(stderr, "nil"); 1224 break; 1225 case 'a': 1226 fprintf(stderr, "array"); 1227 break; 1228 case 'h': 1229 fprintf(stderr, "fd %d", closure->args[i].h); 1230 break; 1231 } 1232 } 1233 1234 fprintf(stderr, ")\n"); 1235 } 1236 1237 void 1238 wl_closure_destroy(struct wl_closure *closure) 1239 { 1240 free(closure); 1241 } 1242