"Fossies" - the Fresh Open Source Software Archive

Member "wayland-1.18.0/src/connection.c" (11 Feb 2020, 29408 Bytes) of package /linux/misc/wayland-1.18.0.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "connection.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 1.17.0_vs_1.18.0.

    1 /*
    2  * Copyright © 2008 Kristian Høgsberg
    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 static inline uint32_t
   48 div_roundup(uint32_t n, size_t a)
   49 {
   50     /* The cast to uint64_t is necessary to prevent overflow when rounding
   51      * values close to UINT32_MAX. After the division it is again safe to
   52      * cast back to uint32_t.
   53      */
   54     return (uint32_t) (((uint64_t) n + (a - 1)) / a);
   55 }
   56 
   57 struct wl_buffer {
   58     char data[4096];
   59     uint32_t head, tail;
   60 };
   61 
   62 #define MASK(i) ((i) & 4095)
   63 
   64 #define MAX_FDS_OUT 28
   65 #define CLEN        (CMSG_LEN(MAX_FDS_OUT * sizeof(int32_t)))
   66 
   67 struct wl_connection {
   68     struct wl_buffer in, out;
   69     struct wl_buffer fds_in, fds_out;
   70     int fd;
   71     int want_flush;
   72 };
   73 
   74 static int
   75 wl_buffer_put(struct wl_buffer *b, const void *data, size_t count)
   76 {
   77     uint32_t head, size;
   78 
   79     if (count > sizeof(b->data)) {
   80         wl_log("Data too big for buffer (%d > %d).\n",
   81                count, sizeof(b->data));
   82         errno = E2BIG;
   83         return -1;
   84     }
   85 
   86     head = MASK(b->head);
   87     if (head + count <= sizeof b->data) {
   88         memcpy(b->data + head, data, count);
   89     } else {
   90         size = sizeof b->data - head;
   91         memcpy(b->data + head, data, size);
   92         memcpy(b->data, (const char *) data + size, count - size);
   93     }
   94 
   95     b->head += count;
   96 
   97     return 0;
   98 }
   99 
  100 static void
  101 wl_buffer_put_iov(struct wl_buffer *b, struct iovec *iov, int *count)
  102 {
  103     uint32_t head, tail;
  104 
  105     head = MASK(b->head);
  106     tail = MASK(b->tail);
  107     if (head < tail) {
  108         iov[0].iov_base = b->data + head;
  109         iov[0].iov_len = tail - head;
  110         *count = 1;
  111     } else if (tail == 0) {
  112         iov[0].iov_base = b->data + head;
  113         iov[0].iov_len = sizeof b->data - head;
  114         *count = 1;
  115     } else {
  116         iov[0].iov_base = b->data + head;
  117         iov[0].iov_len = sizeof b->data - head;
  118         iov[1].iov_base = b->data;
  119         iov[1].iov_len = tail;
  120         *count = 2;
  121     }
  122 }
  123 
  124 static void
  125 wl_buffer_get_iov(struct wl_buffer *b, struct iovec *iov, int *count)
  126 {
  127     uint32_t head, tail;
  128 
  129     head = MASK(b->head);
  130     tail = MASK(b->tail);
  131     if (tail < head) {
  132         iov[0].iov_base = b->data + tail;
  133         iov[0].iov_len = head - tail;
  134         *count = 1;
  135     } else if (head == 0) {
  136         iov[0].iov_base = b->data + tail;
  137         iov[0].iov_len = sizeof b->data - tail;
  138         *count = 1;
  139     } else {
  140         iov[0].iov_base = b->data + tail;
  141         iov[0].iov_len = sizeof b->data - tail;
  142         iov[1].iov_base = b->data;
  143         iov[1].iov_len = head;
  144         *count = 2;
  145     }
  146 }
  147 
  148 static void
  149 wl_buffer_copy(struct wl_buffer *b, void *data, size_t count)
  150 {
  151     uint32_t tail, size;
  152 
  153     tail = MASK(b->tail);
  154     if (tail + count <= sizeof b->data) {
  155         memcpy(data, b->data + tail, count);
  156     } else {
  157         size = sizeof b->data - tail;
  158         memcpy(data, b->data + tail, size);
  159         memcpy((char *) data + size, b->data, count - size);
  160     }
  161 }
  162 
  163 static uint32_t
  164 wl_buffer_size(struct wl_buffer *b)
  165 {
  166     return b->head - b->tail;
  167 }
  168 
  169 struct wl_connection *
  170 wl_connection_create(int fd)
  171 {
  172     struct wl_connection *connection;
  173 
  174     connection = zalloc(sizeof *connection);
  175     if (connection == NULL)
  176         return NULL;
  177 
  178     connection->fd = fd;
  179 
  180     return connection;
  181 }
  182 
  183 static void
  184 close_fds(struct wl_buffer *buffer, int max)
  185 {
  186     int32_t fds[sizeof(buffer->data) / sizeof(int32_t)], i, count;
  187     size_t size;
  188 
  189     size = wl_buffer_size(buffer);
  190     if (size == 0)
  191         return;
  192 
  193     wl_buffer_copy(buffer, fds, size);
  194     count = size / sizeof fds[0];
  195     if (max > 0 && max < count)
  196         count = max;
  197     size = count * sizeof fds[0];
  198     for (i = 0; i < count; i++)
  199         close(fds[i]);
  200     buffer->tail += size;
  201 }
  202 
  203 void
  204 wl_connection_close_fds_in(struct wl_connection *connection, int max)
  205 {
  206     close_fds(&connection->fds_in, max);
  207 }
  208 
  209 int
  210 wl_connection_destroy(struct wl_connection *connection)
  211 {
  212     int fd = connection->fd;
  213 
  214     close_fds(&connection->fds_out, -1);
  215     close_fds(&connection->fds_in, -1);
  216     free(connection);
  217 
  218     return fd;
  219 }
  220 
  221 void
  222 wl_connection_copy(struct wl_connection *connection, void *data, size_t size)
  223 {
  224     wl_buffer_copy(&connection->in, data, size);
  225 }
  226 
  227 void
  228 wl_connection_consume(struct wl_connection *connection, size_t size)
  229 {
  230     connection->in.tail += size;
  231 }
  232 
  233 static void
  234 build_cmsg(struct wl_buffer *buffer, char *data, int *clen)
  235 {
  236     struct cmsghdr *cmsg;
  237     size_t size;
  238 
  239     size = wl_buffer_size(buffer);
  240     if (size > MAX_FDS_OUT * sizeof(int32_t))
  241         size = MAX_FDS_OUT * sizeof(int32_t);
  242 
  243     if (size > 0) {
  244         cmsg = (struct cmsghdr *) data;
  245         cmsg->cmsg_level = SOL_SOCKET;
  246         cmsg->cmsg_type = SCM_RIGHTS;
  247         cmsg->cmsg_len = CMSG_LEN(size);
  248         wl_buffer_copy(buffer, CMSG_DATA(cmsg), size);
  249         *clen = cmsg->cmsg_len;
  250     } else {
  251         *clen = 0;
  252     }
  253 }
  254 
  255 static int
  256 decode_cmsg(struct wl_buffer *buffer, struct msghdr *msg)
  257 {
  258     struct cmsghdr *cmsg;
  259     size_t size, max, i;
  260     int overflow = 0;
  261 
  262     for (cmsg = CMSG_FIRSTHDR(msg); cmsg != NULL;
  263          cmsg = CMSG_NXTHDR(msg, cmsg)) {
  264         if (cmsg->cmsg_level != SOL_SOCKET ||
  265             cmsg->cmsg_type != SCM_RIGHTS)
  266             continue;
  267 
  268         size = cmsg->cmsg_len - CMSG_LEN(0);
  269         max = sizeof(buffer->data) - wl_buffer_size(buffer);
  270         if (size > max || overflow) {
  271             overflow = 1;
  272             size /= sizeof(int32_t);
  273             for (i = 0; i < size; i++)
  274                 close(((int*)CMSG_DATA(cmsg))[i]);
  275         } else if (wl_buffer_put(buffer, CMSG_DATA(cmsg), size) < 0) {
  276                 return -1;
  277         }
  278     }
  279 
  280     if (overflow) {
  281         errno = EOVERFLOW;
  282         return -1;
  283     }
  284 
  285     return 0;
  286 }
  287 
  288 int
  289 wl_connection_flush(struct wl_connection *connection)
  290 {
  291     struct iovec iov[2];
  292     struct msghdr msg;
  293     char cmsg[CLEN];
  294     int len = 0, count, clen;
  295     uint32_t tail;
  296 
  297     if (!connection->want_flush)
  298         return 0;
  299 
  300     tail = connection->out.tail;
  301     while (connection->out.head - connection->out.tail > 0) {
  302         wl_buffer_get_iov(&connection->out, iov, &count);
  303 
  304         build_cmsg(&connection->fds_out, cmsg, &clen);
  305 
  306         msg.msg_name = NULL;
  307         msg.msg_namelen = 0;
  308         msg.msg_iov = iov;
  309         msg.msg_iovlen = count;
  310         msg.msg_control = (clen > 0) ? cmsg : NULL;
  311         msg.msg_controllen = clen;
  312         msg.msg_flags = 0;
  313 
  314         do {
  315             len = sendmsg(connection->fd, &msg,
  316                       MSG_NOSIGNAL | MSG_DONTWAIT);
  317         } while (len == -1 && errno == EINTR);
  318 
  319         if (len == -1)
  320             return -1;
  321 
  322         close_fds(&connection->fds_out, MAX_FDS_OUT);
  323 
  324         connection->out.tail += len;
  325     }
  326 
  327     connection->want_flush = 0;
  328 
  329     return connection->out.head - tail;
  330 }
  331 
  332 uint32_t
  333 wl_connection_pending_input(struct wl_connection *connection)
  334 {
  335     return wl_buffer_size(&connection->in);
  336 }
  337 
  338 int
  339 wl_connection_read(struct wl_connection *connection)
  340 {
  341     struct iovec iov[2];
  342     struct msghdr msg;
  343     char cmsg[CLEN];
  344     int len, count, ret;
  345 
  346     if (wl_buffer_size(&connection->in) >= sizeof(connection->in.data)) {
  347         errno = EOVERFLOW;
  348         return -1;
  349     }
  350 
  351     wl_buffer_put_iov(&connection->in, iov, &count);
  352 
  353     msg.msg_name = NULL;
  354     msg.msg_namelen = 0;
  355     msg.msg_iov = iov;
  356     msg.msg_iovlen = count;
  357     msg.msg_control = cmsg;
  358     msg.msg_controllen = sizeof cmsg;
  359     msg.msg_flags = 0;
  360 
  361     do {
  362         len = wl_os_recvmsg_cloexec(connection->fd, &msg, MSG_DONTWAIT);
  363     } while (len < 0 && errno == EINTR);
  364 
  365     if (len <= 0)
  366         return len;
  367 
  368     ret = decode_cmsg(&connection->fds_in, &msg);
  369     if (ret)
  370         return -1;
  371 
  372     connection->in.head += len;
  373 
  374     return wl_connection_pending_input(connection);
  375 }
  376 
  377 int
  378 wl_connection_write(struct wl_connection *connection,
  379             const void *data, size_t count)
  380 {
  381     if (connection->out.head - connection->out.tail +
  382         count > ARRAY_LENGTH(connection->out.data)) {
  383         connection->want_flush = 1;
  384         if (wl_connection_flush(connection) < 0)
  385             return -1;
  386     }
  387 
  388     if (wl_buffer_put(&connection->out, data, count) < 0)
  389         return -1;
  390 
  391     connection->want_flush = 1;
  392 
  393     return 0;
  394 }
  395 
  396 int
  397 wl_connection_queue(struct wl_connection *connection,
  398             const void *data, size_t count)
  399 {
  400     if (connection->out.head - connection->out.tail +
  401         count > ARRAY_LENGTH(connection->out.data)) {
  402         connection->want_flush = 1;
  403         if (wl_connection_flush(connection) < 0)
  404             return -1;
  405     }
  406 
  407     return wl_buffer_put(&connection->out, data, count);
  408 }
  409 
  410 int
  411 wl_message_count_arrays(const struct wl_message *message)
  412 {
  413     int i, arrays;
  414 
  415     for (i = 0, arrays = 0; message->signature[i]; i++) {
  416         if (message->signature[i] == 'a')
  417             arrays++;
  418     }
  419 
  420     return arrays;
  421 }
  422 
  423 int
  424 wl_connection_get_fd(struct wl_connection *connection)
  425 {
  426     return connection->fd;
  427 }
  428 
  429 static int
  430 wl_connection_put_fd(struct wl_connection *connection, int32_t fd)
  431 {
  432     if (wl_buffer_size(&connection->fds_out) == MAX_FDS_OUT * sizeof fd) {
  433         connection->want_flush = 1;
  434         if (wl_connection_flush(connection) < 0)
  435             return -1;
  436     }
  437 
  438     return wl_buffer_put(&connection->fds_out, &fd, sizeof fd);
  439 }
  440 
  441 const char *
  442 get_next_argument(const char *signature, struct argument_details *details)
  443 {
  444     details->nullable = 0;
  445     for(; *signature; ++signature) {
  446         switch(*signature) {
  447         case 'i':
  448         case 'u':
  449         case 'f':
  450         case 's':
  451         case 'o':
  452         case 'n':
  453         case 'a':
  454         case 'h':
  455             details->type = *signature;
  456             return signature + 1;
  457         case '?':
  458             details->nullable = 1;
  459         }
  460     }
  461     details->type = '\0';
  462     return signature;
  463 }
  464 
  465 int
  466 arg_count_for_signature(const char *signature)
  467 {
  468     int count = 0;
  469     for(; *signature; ++signature) {
  470         switch(*signature) {
  471         case 'i':
  472         case 'u':
  473         case 'f':
  474         case 's':
  475         case 'o':
  476         case 'n':
  477         case 'a':
  478         case 'h':
  479             ++count;
  480         }
  481     }
  482     return count;
  483 }
  484 
  485 int
  486 wl_message_get_since(const struct wl_message *message)
  487 {
  488     int since;
  489 
  490     since = atoi(message->signature);
  491 
  492     if (since == 0)
  493         since = 1;
  494 
  495     return since;
  496 }
  497 
  498 void
  499 wl_argument_from_va_list(const char *signature, union wl_argument *args,
  500              int count, va_list ap)
  501 {
  502     int i;
  503     const char *sig_iter;
  504     struct argument_details arg;
  505 
  506     sig_iter = signature;
  507     for (i = 0; i < count; i++) {
  508         sig_iter = get_next_argument(sig_iter, &arg);
  509 
  510         switch(arg.type) {
  511         case 'i':
  512             args[i].i = va_arg(ap, int32_t);
  513             break;
  514         case 'u':
  515             args[i].u = va_arg(ap, uint32_t);
  516             break;
  517         case 'f':
  518             args[i].f = va_arg(ap, wl_fixed_t);
  519             break;
  520         case 's':
  521             args[i].s = va_arg(ap, const char *);
  522             break;
  523         case 'o':
  524             args[i].o = va_arg(ap, struct wl_object *);
  525             break;
  526         case 'n':
  527             args[i].o = va_arg(ap, struct wl_object *);
  528             break;
  529         case 'a':
  530             args[i].a = va_arg(ap, struct wl_array *);
  531             break;
  532         case 'h':
  533             args[i].h = va_arg(ap, int32_t);
  534             break;
  535         case '\0':
  536             return;
  537         }
  538     }
  539 }
  540 
  541 static void
  542 wl_closure_clear_fds(struct wl_closure *closure)
  543 {
  544     const char *signature = closure->message->signature;
  545     struct argument_details arg;
  546     int i;
  547 
  548     for (i = 0; i < closure->count; i++) {
  549         signature = get_next_argument(signature, &arg);
  550         if (arg.type == 'h')
  551             closure->args[i].h = -1;
  552     }
  553 }
  554 
  555 static struct wl_closure *
  556 wl_closure_init(const struct wl_message *message, uint32_t size,
  557                 int *num_arrays, union wl_argument *args)
  558 {
  559     struct wl_closure *closure;
  560     int count;
  561 
  562     count = arg_count_for_signature(message->signature);
  563     if (count > WL_CLOSURE_MAX_ARGS) {
  564         wl_log("too many args (%d)\n", count);
  565         errno = EINVAL;
  566         return NULL;
  567     }
  568 
  569     if (size) {
  570         *num_arrays = wl_message_count_arrays(message);
  571         closure = malloc(sizeof *closure + size +
  572                  *num_arrays * sizeof(struct wl_array));
  573     } else {
  574         closure = malloc(sizeof *closure);
  575     }
  576 
  577     if (!closure) {
  578         errno = ENOMEM;
  579         return NULL;
  580     }
  581 
  582     if (args)
  583         memcpy(closure->args, args, count * sizeof *args);
  584 
  585     closure->message = message;
  586     closure->count = count;
  587 
  588     /* Set these all to -1 so we can close any that have been
  589      * set to a real value during wl_closure_destroy().
  590      * We may have copied a bunch of fds into the closure with
  591      * memcpy previously, but those are undup()d client fds
  592      * that we would have replaced anyway.
  593      */
  594     wl_closure_clear_fds(closure);
  595 
  596     return closure;
  597 }
  598 
  599 struct wl_closure *
  600 wl_closure_marshal(struct wl_object *sender, uint32_t opcode,
  601            union wl_argument *args,
  602            const struct wl_message *message)
  603 {
  604     struct wl_closure *closure;
  605     struct wl_object *object;
  606     int i, count, fd, dup_fd;
  607     const char *signature;
  608     struct argument_details arg;
  609 
  610     closure = wl_closure_init(message, 0, NULL, args);
  611     if (closure == NULL)
  612         return NULL;
  613 
  614     count = closure->count;
  615 
  616     signature = message->signature;
  617     for (i = 0; i < count; i++) {
  618         signature = get_next_argument(signature, &arg);
  619 
  620         switch (arg.type) {
  621         case 'f':
  622         case 'u':
  623         case 'i':
  624             break;
  625         case 's':
  626             if (!arg.nullable && args[i].s == NULL)
  627                 goto err_null;
  628             break;
  629         case 'o':
  630             if (!arg.nullable && args[i].o == NULL)
  631                 goto err_null;
  632             break;
  633         case 'n':
  634             object = args[i].o;
  635             if (!arg.nullable && object == NULL)
  636                 goto err_null;
  637 
  638             closure->args[i].n = object ? object->id : 0;
  639             break;
  640         case 'a':
  641             if (!arg.nullable && args[i].a == NULL)
  642                 goto err_null;
  643             break;
  644         case 'h':
  645             fd = args[i].h;
  646             dup_fd = wl_os_dupfd_cloexec(fd, 0);
  647             if (dup_fd < 0) {
  648                 wl_closure_destroy(closure);
  649                 wl_log("error marshalling arguments for %s: dup failed: %s\n",
  650                        message->name, strerror(errno));
  651                 return NULL;
  652             }
  653             closure->args[i].h = dup_fd;
  654             break;
  655         default:
  656             wl_abort("unhandled format code: '%c'\n", arg.type);
  657             break;
  658         }
  659     }
  660 
  661     closure->sender_id = sender->id;
  662     closure->opcode = opcode;
  663 
  664     return closure;
  665 
  666 err_null:
  667     wl_closure_destroy(closure);
  668     wl_log("error marshalling arguments for %s (signature %s): "
  669            "null value passed for arg %i\n", message->name,
  670            message->signature, i);
  671     errno = EINVAL;
  672     return NULL;
  673 }
  674 
  675 struct wl_closure *
  676 wl_closure_vmarshal(struct wl_object *sender, uint32_t opcode, va_list ap,
  677             const struct wl_message *message)
  678 {
  679     union wl_argument args[WL_CLOSURE_MAX_ARGS];
  680 
  681     wl_argument_from_va_list(message->signature, args,
  682                  WL_CLOSURE_MAX_ARGS, ap);
  683 
  684     return wl_closure_marshal(sender, opcode, args, message);
  685 }
  686 
  687 struct wl_closure *
  688 wl_connection_demarshal(struct wl_connection *connection,
  689             uint32_t size,
  690             struct wl_map *objects,
  691             const struct wl_message *message)
  692 {
  693     uint32_t *p, *next, *end, length, length_in_u32, id;
  694     int fd;
  695     char *s;
  696     int i, count, num_arrays;
  697     const char *signature;
  698     struct argument_details arg;
  699     struct wl_closure *closure;
  700     struct wl_array *array_extra;
  701 
  702     /* Space for sender_id and opcode */
  703     if (size < 2 * sizeof *p) {
  704         wl_log("message too short, invalid header\n");
  705         wl_connection_consume(connection, size);
  706         errno = EINVAL;
  707         return NULL;
  708     }
  709 
  710     closure = wl_closure_init(message, size, &num_arrays, NULL);
  711     if (closure == NULL) {
  712         wl_connection_consume(connection, size);
  713         return NULL;
  714     }
  715 
  716     count = closure->count;
  717 
  718     array_extra = closure->extra;
  719     p = (uint32_t *)(closure->extra + num_arrays);
  720     end = p + size / sizeof *p;
  721 
  722     wl_connection_copy(connection, p, size);
  723     closure->sender_id = *p++;
  724     closure->opcode = *p++ & 0x0000ffff;
  725 
  726     signature = message->signature;
  727     for (i = 0; i < count; i++) {
  728         signature = get_next_argument(signature, &arg);
  729 
  730         if (arg.type != 'h' && p + 1 > end) {
  731             wl_log("message too short, "
  732                    "object (%d), message %s(%s)\n",
  733                    closure->sender_id, message->name,
  734                    message->signature);
  735             errno = EINVAL;
  736             goto err;
  737         }
  738 
  739         switch (arg.type) {
  740         case 'u':
  741             closure->args[i].u = *p++;
  742             break;
  743         case 'i':
  744             closure->args[i].i = *p++;
  745             break;
  746         case 'f':
  747             closure->args[i].f = *p++;
  748             break;
  749         case 's':
  750             length = *p++;
  751 
  752             if (length == 0) {
  753                 closure->args[i].s = NULL;
  754                 break;
  755             }
  756 
  757             length_in_u32 = div_roundup(length, sizeof *p);
  758             if ((uint32_t) (end - p) < length_in_u32) {
  759                 wl_log("message too short, "
  760                        "object (%d), message %s(%s)\n",
  761                        closure->sender_id, message->name,
  762                        message->signature);
  763                 errno = EINVAL;
  764                 goto err;
  765             }
  766             next = p + length_in_u32;
  767 
  768             s = (char *) p;
  769 
  770             if (length > 0 && s[length - 1] != '\0') {
  771                 wl_log("string not nul-terminated, "
  772                        "message %s(%s)\n",
  773                        message->name, message->signature);
  774                 errno = EINVAL;
  775                 goto err;
  776             }
  777 
  778             closure->args[i].s = s;
  779             p = next;
  780             break;
  781         case 'o':
  782             id = *p++;
  783             closure->args[i].n = id;
  784 
  785             if (id == 0 && !arg.nullable) {
  786                 wl_log("NULL object received on non-nullable "
  787                        "type, message %s(%s)\n", message->name,
  788                        message->signature);
  789                 errno = EINVAL;
  790                 goto err;
  791             }
  792             break;
  793         case 'n':
  794             id = *p++;
  795             closure->args[i].n = id;
  796 
  797             if (id == 0 && !arg.nullable) {
  798                 wl_log("NULL new ID received on non-nullable "
  799                        "type, message %s(%s)\n", message->name,
  800                        message->signature);
  801                 errno = EINVAL;
  802                 goto err;
  803             }
  804 
  805             if (wl_map_reserve_new(objects, id) < 0) {
  806                 wl_log("not a valid new object id (%u), "
  807                        "message %s(%s)\n",
  808                        id, message->name, message->signature);
  809                 errno = EINVAL;
  810                 goto err;
  811             }
  812 
  813             break;
  814         case 'a':
  815             length = *p++;
  816 
  817             length_in_u32 = div_roundup(length, sizeof *p);
  818             if ((uint32_t) (end - p) < length_in_u32) {
  819                 wl_log("message too short, "
  820                        "object (%d), message %s(%s)\n",
  821                        closure->sender_id, message->name,
  822                        message->signature);
  823                 errno = EINVAL;
  824                 goto err;
  825             }
  826             next = p + length_in_u32;
  827 
  828             array_extra->size = length;
  829             array_extra->alloc = 0;
  830             array_extra->data = p;
  831 
  832             closure->args[i].a = array_extra++;
  833             p = next;
  834             break;
  835         case 'h':
  836             if (connection->fds_in.tail == connection->fds_in.head) {
  837                 wl_log("file descriptor expected, "
  838                        "object (%d), message %s(%s)\n",
  839                        closure->sender_id, message->name,
  840                        message->signature);
  841                 errno = EINVAL;
  842                 goto err;
  843             }
  844 
  845             wl_buffer_copy(&connection->fds_in, &fd, sizeof fd);
  846             connection->fds_in.tail += sizeof fd;
  847             closure->args[i].h = fd;
  848             break;
  849         default:
  850             wl_abort("unknown type\n");
  851             break;
  852         }
  853     }
  854 
  855     wl_connection_consume(connection, size);
  856 
  857     return closure;
  858 
  859  err:
  860     wl_closure_destroy(closure);
  861     wl_connection_consume(connection, size);
  862 
  863     return NULL;
  864 }
  865 
  866 bool
  867 wl_object_is_zombie(struct wl_map *map, uint32_t id)
  868 {
  869     uint32_t flags;
  870 
  871     /* Zombie objects only exist on the client side. */
  872     if (map->side == WL_MAP_SERVER_SIDE)
  873         return false;
  874 
  875     /* Zombie objects can only have been created by the client. */
  876     if (id >= WL_SERVER_ID_START)
  877         return false;
  878 
  879     flags = wl_map_lookup_flags(map, id);
  880     return !!(flags & WL_MAP_ENTRY_ZOMBIE);
  881 }
  882 
  883 int
  884 wl_closure_lookup_objects(struct wl_closure *closure, struct wl_map *objects)
  885 {
  886     struct wl_object *object;
  887     const struct wl_message *message;
  888     const char *signature;
  889     struct argument_details arg;
  890     int i, count;
  891     uint32_t id;
  892 
  893     message = closure->message;
  894     signature = message->signature;
  895     count = arg_count_for_signature(signature);
  896     for (i = 0; i < count; i++) {
  897         signature = get_next_argument(signature, &arg);
  898         switch (arg.type) {
  899         case 'o':
  900             id = closure->args[i].n;
  901             closure->args[i].o = NULL;
  902 
  903             object = wl_map_lookup(objects, id);
  904             if (wl_object_is_zombie(objects, id)) {
  905                 /* references object we've already
  906                  * destroyed client side */
  907                 object = NULL;
  908             } else if (object == NULL && id != 0) {
  909                 wl_log("unknown object (%u), message %s(%s)\n",
  910                        id, message->name, message->signature);
  911                 errno = EINVAL;
  912                 return -1;
  913             }
  914 
  915             if (object != NULL && message->types[i] != NULL &&
  916                 !wl_interface_equal((object)->interface,
  917                         message->types[i])) {
  918                 wl_log("invalid object (%u), type (%s), "
  919                        "message %s(%s)\n",
  920                        id, (object)->interface->name,
  921                        message->name, message->signature);
  922                 errno = EINVAL;
  923                 return -1;
  924             }
  925             closure->args[i].o = object;
  926         }
  927     }
  928 
  929     return 0;
  930 }
  931 
  932 static void
  933 convert_arguments_to_ffi(const char *signature, uint32_t flags,
  934              union wl_argument *args,
  935              int count, ffi_type **ffi_types, void** ffi_args)
  936 {
  937     int i;
  938     const char *sig_iter;
  939     struct argument_details arg;
  940 
  941     sig_iter = signature;
  942     for (i = 0; i < count; i++) {
  943         sig_iter = get_next_argument(sig_iter, &arg);
  944 
  945         switch(arg.type) {
  946         case 'i':
  947             ffi_types[i] = &ffi_type_sint32;
  948             ffi_args[i] = &args[i].i;
  949             break;
  950         case 'u':
  951             ffi_types[i] = &ffi_type_uint32;
  952             ffi_args[i] = &args[i].u;
  953             break;
  954         case 'f':
  955             ffi_types[i] = &ffi_type_sint32;
  956             ffi_args[i] = &args[i].f;
  957             break;
  958         case 's':
  959             ffi_types[i] = &ffi_type_pointer;
  960             ffi_args[i] = &args[i].s;
  961             break;
  962         case 'o':
  963             ffi_types[i] = &ffi_type_pointer;
  964             ffi_args[i] = &args[i].o;
  965             break;
  966         case 'n':
  967             if (flags & WL_CLOSURE_INVOKE_CLIENT) {
  968                 ffi_types[i] = &ffi_type_pointer;
  969                 ffi_args[i] = &args[i].o;
  970             } else {
  971                 ffi_types[i] = &ffi_type_uint32;
  972                 ffi_args[i] = &args[i].n;
  973             }
  974             break;
  975         case 'a':
  976             ffi_types[i] = &ffi_type_pointer;
  977             ffi_args[i] = &args[i].a;
  978             break;
  979         case 'h':
  980             ffi_types[i] = &ffi_type_sint32;
  981             ffi_args[i] = &args[i].h;
  982             break;
  983         default:
  984             wl_abort("unknown type\n");
  985             break;
  986         }
  987     }
  988 }
  989 
  990 void
  991 wl_closure_invoke(struct wl_closure *closure, uint32_t flags,
  992           struct wl_object *target, uint32_t opcode, void *data)
  993 {
  994     int count;
  995     ffi_cif cif;
  996     ffi_type *ffi_types[WL_CLOSURE_MAX_ARGS + 2];
  997     void * ffi_args[WL_CLOSURE_MAX_ARGS + 2];
  998     void (* const *implementation)(void);
  999 
 1000     count = arg_count_for_signature(closure->message->signature);
 1001 
 1002     ffi_types[0] = &ffi_type_pointer;
 1003     ffi_args[0] = &data;
 1004     ffi_types[1] = &ffi_type_pointer;
 1005     ffi_args[1] = &target;
 1006 
 1007     convert_arguments_to_ffi(closure->message->signature, flags, closure->args,
 1008                  count, ffi_types + 2, ffi_args + 2);
 1009 
 1010     ffi_prep_cif(&cif, FFI_DEFAULT_ABI,
 1011              count + 2, &ffi_type_void, ffi_types);
 1012 
 1013     implementation = target->implementation;
 1014     if (!implementation[opcode]) {
 1015         wl_abort("listener function for opcode %u of %s is NULL\n",
 1016              opcode, target->interface->name);
 1017     }
 1018     ffi_call(&cif, implementation[opcode], NULL, ffi_args);
 1019 
 1020     wl_closure_clear_fds(closure);
 1021 }
 1022 
 1023 void
 1024 wl_closure_dispatch(struct wl_closure *closure, wl_dispatcher_func_t dispatcher,
 1025             struct wl_object *target, uint32_t opcode)
 1026 {
 1027     dispatcher(target->implementation, target, opcode, closure->message,
 1028            closure->args);
 1029 
 1030     wl_closure_clear_fds(closure);
 1031 }
 1032 
 1033 static int
 1034 copy_fds_to_connection(struct wl_closure *closure,
 1035                struct wl_connection *connection)
 1036 {
 1037     const struct wl_message *message = closure->message;
 1038     uint32_t i, count;
 1039     struct argument_details arg;
 1040     const char *signature = message->signature;
 1041     int fd;
 1042 
 1043     count = arg_count_for_signature(signature);
 1044     for (i = 0; i < count; i++) {
 1045         signature = get_next_argument(signature, &arg);
 1046         if (arg.type != 'h')
 1047             continue;
 1048 
 1049         fd = closure->args[i].h;
 1050         if (wl_connection_put_fd(connection, fd)) {
 1051             wl_log("request could not be marshaled: "
 1052                    "can't send file descriptor");
 1053             return -1;
 1054         }
 1055         closure->args[i].h = -1;
 1056     }
 1057 
 1058     return 0;
 1059 }
 1060 
 1061 
 1062 static uint32_t
 1063 buffer_size_for_closure(struct wl_closure *closure)
 1064 {
 1065     const struct wl_message *message = closure->message;
 1066     int i, count;
 1067     struct argument_details arg;
 1068     const char *signature;
 1069     uint32_t size, buffer_size = 0;
 1070 
 1071     signature = message->signature;
 1072     count = arg_count_for_signature(signature);
 1073     for (i = 0; i < count; i++) {
 1074         signature = get_next_argument(signature, &arg);
 1075 
 1076         switch (arg.type) {
 1077         case 'h':
 1078             break;
 1079         case 'u':
 1080         case 'i':
 1081         case 'f':
 1082         case 'o':
 1083         case 'n':
 1084             buffer_size++;
 1085             break;
 1086         case 's':
 1087             if (closure->args[i].s == NULL) {
 1088                 buffer_size++;
 1089                 break;
 1090             }
 1091 
 1092             size = strlen(closure->args[i].s) + 1;
 1093             buffer_size += 1 + div_roundup(size, sizeof(uint32_t));
 1094             break;
 1095         case 'a':
 1096             if (closure->args[i].a == NULL) {
 1097                 buffer_size++;
 1098                 break;
 1099             }
 1100 
 1101             size = closure->args[i].a->size;
 1102             buffer_size += (1 + div_roundup(size, sizeof(uint32_t)));
 1103             break;
 1104         default:
 1105             break;
 1106         }
 1107     }
 1108 
 1109     return buffer_size + 2;
 1110 }
 1111 
 1112 static int
 1113 serialize_closure(struct wl_closure *closure, uint32_t *buffer,
 1114           size_t buffer_count)
 1115 {
 1116     const struct wl_message *message = closure->message;
 1117     unsigned int i, count, size;
 1118     uint32_t *p, *end;
 1119     struct argument_details arg;
 1120     const char *signature;
 1121 
 1122     if (buffer_count < 2)
 1123         goto overflow;
 1124 
 1125     p = buffer + 2;
 1126     end = buffer + buffer_count;
 1127 
 1128     signature = message->signature;
 1129     count = arg_count_for_signature(signature);
 1130     for (i = 0; i < count; i++) {
 1131         signature = get_next_argument(signature, &arg);
 1132 
 1133         if (arg.type == 'h')
 1134             continue;
 1135 
 1136         if (p + 1 > end)
 1137             goto overflow;
 1138 
 1139         switch (arg.type) {
 1140         case 'u':
 1141             *p++ = closure->args[i].u;
 1142             break;
 1143         case 'i':
 1144             *p++ = closure->args[i].i;
 1145             break;
 1146         case 'f':
 1147             *p++ = closure->args[i].f;
 1148             break;
 1149         case 'o':
 1150             *p++ = closure->args[i].o ? closure->args[i].o->id : 0;
 1151             break;
 1152         case 'n':
 1153             *p++ = closure->args[i].n;
 1154             break;
 1155         case 's':
 1156             if (closure->args[i].s == NULL) {
 1157                 *p++ = 0;
 1158                 break;
 1159             }
 1160 
 1161             size = strlen(closure->args[i].s) + 1;
 1162             *p++ = size;
 1163 
 1164             if (p + div_roundup(size, sizeof *p) > end)
 1165                 goto overflow;
 1166 
 1167             memcpy(p, closure->args[i].s, size);
 1168             p += div_roundup(size, sizeof *p);
 1169             break;
 1170         case 'a':
 1171             if (closure->args[i].a == NULL) {
 1172                 *p++ = 0;
 1173                 break;
 1174             }
 1175 
 1176             size = closure->args[i].a->size;
 1177             *p++ = size;
 1178 
 1179             if (p + div_roundup(size, sizeof *p) > end)
 1180                 goto overflow;
 1181 
 1182             memcpy(p, closure->args[i].a->data, size);
 1183             p += div_roundup(size, sizeof *p);
 1184             break;
 1185         default:
 1186             break;
 1187         }
 1188     }
 1189 
 1190     size = (p - buffer) * sizeof *p;
 1191 
 1192     buffer[0] = closure->sender_id;
 1193     buffer[1] = size << 16 | (closure->opcode & 0x0000ffff);
 1194 
 1195     return size;
 1196 
 1197 overflow:
 1198     errno = ERANGE;
 1199     return -1;
 1200 }
 1201 
 1202 int
 1203 wl_closure_send(struct wl_closure *closure, struct wl_connection *connection)
 1204 {
 1205     int size;
 1206     uint32_t buffer_size;
 1207     uint32_t *buffer;
 1208     int result;
 1209 
 1210     if (copy_fds_to_connection(closure, connection))
 1211         return -1;
 1212 
 1213     buffer_size = buffer_size_for_closure(closure);
 1214     buffer = zalloc(buffer_size * sizeof buffer[0]);
 1215     if (buffer == NULL)
 1216         return -1;
 1217 
 1218     size = serialize_closure(closure, buffer, buffer_size);
 1219     if (size < 0) {
 1220         free(buffer);
 1221         return -1;
 1222     }
 1223 
 1224     result = wl_connection_write(connection, buffer, size);
 1225     free(buffer);
 1226 
 1227     return result;
 1228 }
 1229 
 1230 int
 1231 wl_closure_queue(struct wl_closure *closure, struct wl_connection *connection)
 1232 {
 1233     int size;
 1234     uint32_t buffer_size;
 1235     uint32_t *buffer;
 1236     int result;
 1237 
 1238     if (copy_fds_to_connection(closure, connection))
 1239         return -1;
 1240 
 1241     buffer_size = buffer_size_for_closure(closure);
 1242     buffer = malloc(buffer_size * sizeof buffer[0]);
 1243     if (buffer == NULL)
 1244         return -1;
 1245 
 1246     size = serialize_closure(closure, buffer, buffer_size);
 1247     if (size < 0) {
 1248         free(buffer);
 1249         return -1;
 1250     }
 1251 
 1252     result = wl_connection_queue(connection, buffer, size);
 1253     free(buffer);
 1254 
 1255     return result;
 1256 }
 1257 
 1258 void
 1259 wl_closure_print(struct wl_closure *closure, struct wl_object *target, int send)
 1260 {
 1261     int i;
 1262     struct argument_details arg;
 1263     const char *signature = closure->message->signature;
 1264     struct timespec tp;
 1265     unsigned int time;
 1266 
 1267     clock_gettime(CLOCK_REALTIME, &tp);
 1268     time = (tp.tv_sec * 1000000L) + (tp.tv_nsec / 1000);
 1269 
 1270     fprintf(stderr, "[%10.3f] %s%s@%u.%s(",
 1271         time / 1000.0,
 1272         send ? " -> " : "",
 1273         target->interface->name, target->id,
 1274         closure->message->name);
 1275 
 1276     for (i = 0; i < closure->count; i++) {
 1277         signature = get_next_argument(signature, &arg);
 1278         if (i > 0)
 1279             fprintf(stderr, ", ");
 1280 
 1281         switch (arg.type) {
 1282         case 'u':
 1283             fprintf(stderr, "%u", closure->args[i].u);
 1284             break;
 1285         case 'i':
 1286             fprintf(stderr, "%d", closure->args[i].i);
 1287             break;
 1288         case 'f':
 1289             fprintf(stderr, "%f",
 1290                 wl_fixed_to_double(closure->args[i].f));
 1291             break;
 1292         case 's':
 1293             if (closure->args[i].s)
 1294                 fprintf(stderr, "\"%s\"", closure->args[i].s);
 1295             else
 1296                 fprintf(stderr, "nil");
 1297             break;
 1298         case 'o':
 1299             if (closure->args[i].o)
 1300                 fprintf(stderr, "%s@%u",
 1301                     closure->args[i].o->interface->name,
 1302                     closure->args[i].o->id);
 1303             else
 1304                 fprintf(stderr, "nil");
 1305             break;
 1306         case 'n':
 1307             fprintf(stderr, "new id %s@",
 1308                 (closure->message->types[i]) ?
 1309                  closure->message->types[i]->name :
 1310                   "[unknown]");
 1311             if (closure->args[i].n != 0)
 1312                 fprintf(stderr, "%u", closure->args[i].n);
 1313             else
 1314                 fprintf(stderr, "nil");
 1315             break;
 1316         case 'a':
 1317             fprintf(stderr, "array");
 1318             break;
 1319         case 'h':
 1320             fprintf(stderr, "fd %d", closure->args[i].h);
 1321             break;
 1322         }
 1323     }
 1324 
 1325     fprintf(stderr, ")\n");
 1326 }
 1327 
 1328 static int
 1329 wl_closure_close_fds(struct wl_closure *closure)
 1330 {
 1331     int i;
 1332     struct argument_details arg;
 1333     const char *signature = closure->message->signature;
 1334 
 1335     for (i = 0; i < closure->count; i++) {
 1336         signature = get_next_argument(signature, &arg);
 1337         if (arg.type == 'h' && closure->args[i].h != -1)
 1338             close(closure->args[i].h);
 1339     }
 1340 
 1341     return 0;
 1342 }
 1343 
 1344 void
 1345 wl_closure_destroy(struct wl_closure *closure)
 1346 {
 1347     /* wl_closure_destroy has free() semantics */
 1348     if (!closure)
 1349         return;
 1350 
 1351     wl_closure_close_fds(closure);
 1352     free(closure);
 1353 }