int wl_connection_read(struct wl_connection *connection) { struct iovec iov[2]; struct msghdr msg; char cmsg[CLEN]; int len, count, ret; if (wl_buffer_size(&connection->in) >= sizeof(connection->in.data)) { errno = EOVERFLOW; return -1; } wl_buffer_put_iov(&connection->in, iov, &count); msg.msg_name = NULL; msg.msg_namelen = 0; msg.msg_iov = iov; msg.msg_iovlen = count; msg.msg_control = cmsg; msg.msg_controllen = sizeof cmsg; msg.msg_flags = 0; do { len = wl_os_recvmsg_cloexec(connection->fd, &msg, MSG_DONTWAIT); } while (len < 0 && errno == EINTR); if (len <= 0) return len; ret = decode_cmsg(&connection->fds_in, &msg); if (ret) return -1; connection->in.head += len; return wl_connection_pending_input(connection); }
int wl_connection_data(struct wl_connection *connection, uint32_t mask) { struct iovec iov[2]; struct msghdr msg; char cmsg[CLEN]; int len, count, clen; if (mask & WL_CONNECTION_WRITABLE) { wl_buffer_get_iov(&connection->out, iov, &count); build_cmsg(&connection->fds_out, cmsg, &clen); msg.msg_name = NULL; msg.msg_namelen = 0; msg.msg_iov = iov; msg.msg_iovlen = count; msg.msg_control = cmsg; msg.msg_controllen = clen; msg.msg_flags = 0; do { len = sendmsg(connection->fd, &msg, MSG_NOSIGNAL | MSG_DONTWAIT); } while (len < 0 && errno == EINTR); if (len == -1 && errno == EPIPE) { return -1; } else if (len < 0) { fprintf(stderr, "write error for connection %p, fd %d: %m\n", connection, connection->fd); return -1; } close_fds(&connection->fds_out); connection->out.tail += len; if (connection->out.tail == connection->out.head && connection->write_signalled) { connection->update(connection, WL_CONNECTION_READABLE, connection->data); connection->write_signalled = 0; } } if (mask & WL_CONNECTION_READABLE) { wl_buffer_put_iov(&connection->in, iov, &count); msg.msg_name = NULL; msg.msg_namelen = 0; msg.msg_iov = iov; msg.msg_iovlen = count; msg.msg_control = cmsg; msg.msg_controllen = sizeof cmsg; msg.msg_flags = 0; do { len = wl_os_recvmsg_cloexec(connection->fd, &msg, 0); } while (len < 0 && errno == EINTR); if (len < 0) { fprintf(stderr, "read error from connection %p: %m (%d)\n", connection, errno); return -1; } else if (len == 0) { /* FIXME: Handle this better? */ return -1; } decode_cmsg(&connection->fds_in, &msg); connection->in.head += len; } return connection->in.head - connection->in.tail; }