1818c5d8cc721053be659c92b577217914905883Lloyd Pique/* 2818c5d8cc721053be659c92b577217914905883Lloyd Pique * Copyright © 2012 Intel Corporation 3818c5d8cc721053be659c92b577217914905883Lloyd Pique * 4818c5d8cc721053be659c92b577217914905883Lloyd Pique * Permission is hereby granted, free of charge, to any person obtaining 5818c5d8cc721053be659c92b577217914905883Lloyd Pique * a copy of this software and associated documentation files (the 6818c5d8cc721053be659c92b577217914905883Lloyd Pique * "Software"), to deal in the Software without restriction, including 7818c5d8cc721053be659c92b577217914905883Lloyd Pique * without limitation the rights to use, copy, modify, merge, publish, 8818c5d8cc721053be659c92b577217914905883Lloyd Pique * distribute, sublicense, and/or sell copies of the Software, and to 9818c5d8cc721053be659c92b577217914905883Lloyd Pique * permit persons to whom the Software is furnished to do so, subject to 10818c5d8cc721053be659c92b577217914905883Lloyd Pique * the following conditions: 11818c5d8cc721053be659c92b577217914905883Lloyd Pique * 12818c5d8cc721053be659c92b577217914905883Lloyd Pique * The above copyright notice and this permission notice (including the 13818c5d8cc721053be659c92b577217914905883Lloyd Pique * next paragraph) shall be included in all copies or substantial 14818c5d8cc721053be659c92b577217914905883Lloyd Pique * portions of the Software. 15818c5d8cc721053be659c92b577217914905883Lloyd Pique * 16818c5d8cc721053be659c92b577217914905883Lloyd Pique * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17818c5d8cc721053be659c92b577217914905883Lloyd Pique * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18818c5d8cc721053be659c92b577217914905883Lloyd Pique * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19818c5d8cc721053be659c92b577217914905883Lloyd Pique * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 20818c5d8cc721053be659c92b577217914905883Lloyd Pique * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 21818c5d8cc721053be659c92b577217914905883Lloyd Pique * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22818c5d8cc721053be659c92b577217914905883Lloyd Pique * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23818c5d8cc721053be659c92b577217914905883Lloyd Pique * SOFTWARE. 24818c5d8cc721053be659c92b577217914905883Lloyd Pique */ 25818c5d8cc721053be659c92b577217914905883Lloyd Pique 26818c5d8cc721053be659c92b577217914905883Lloyd Pique#include <math.h> 27818c5d8cc721053be659c92b577217914905883Lloyd Pique#include <stdio.h> 28818c5d8cc721053be659c92b577217914905883Lloyd Pique#include <stdlib.h> 29818c5d8cc721053be659c92b577217914905883Lloyd Pique#include <stdarg.h> 30293a0fb21eafd159514a0ac98d687669f9bb55b1Dennis Kempin#include <stdint.h> 31818c5d8cc721053be659c92b577217914905883Lloyd Pique#include <string.h> 32818c5d8cc721053be659c92b577217914905883Lloyd Pique#include <assert.h> 33818c5d8cc721053be659c92b577217914905883Lloyd Pique#include <sys/socket.h> 34818c5d8cc721053be659c92b577217914905883Lloyd Pique#include <unistd.h> 35818c5d8cc721053be659c92b577217914905883Lloyd Pique#include <errno.h> 36818c5d8cc721053be659c92b577217914905883Lloyd Pique#include <sys/types.h> 37818c5d8cc721053be659c92b577217914905883Lloyd Pique#include <sys/stat.h> 38818c5d8cc721053be659c92b577217914905883Lloyd Pique#include <poll.h> 39818c5d8cc721053be659c92b577217914905883Lloyd Pique 40818c5d8cc721053be659c92b577217914905883Lloyd Pique#include "wayland-private.h" 41818c5d8cc721053be659c92b577217914905883Lloyd Pique#include "test-runner.h" 42818c5d8cc721053be659c92b577217914905883Lloyd Pique#include "test-compositor.h" 43818c5d8cc721053be659c92b577217914905883Lloyd Pique 44818c5d8cc721053be659c92b577217914905883Lloyd Piquestatic const char message[] = "Hello, world"; 45818c5d8cc721053be659c92b577217914905883Lloyd Pique 46818c5d8cc721053be659c92b577217914905883Lloyd Piquestatic struct wl_connection * 47818c5d8cc721053be659c92b577217914905883Lloyd Piquesetup(int *s) 48818c5d8cc721053be659c92b577217914905883Lloyd Pique{ 49818c5d8cc721053be659c92b577217914905883Lloyd Pique struct wl_connection *connection; 50818c5d8cc721053be659c92b577217914905883Lloyd Pique 51818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, s) == 0); 52818c5d8cc721053be659c92b577217914905883Lloyd Pique 53818c5d8cc721053be659c92b577217914905883Lloyd Pique connection = wl_connection_create(s[0]); 54818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(connection); 55818c5d8cc721053be659c92b577217914905883Lloyd Pique 56818c5d8cc721053be659c92b577217914905883Lloyd Pique return connection; 57818c5d8cc721053be659c92b577217914905883Lloyd Pique} 58818c5d8cc721053be659c92b577217914905883Lloyd Pique 59818c5d8cc721053be659c92b577217914905883Lloyd PiqueTEST(connection_create) 60818c5d8cc721053be659c92b577217914905883Lloyd Pique{ 61818c5d8cc721053be659c92b577217914905883Lloyd Pique struct wl_connection *connection; 62818c5d8cc721053be659c92b577217914905883Lloyd Pique int s[2]; 63818c5d8cc721053be659c92b577217914905883Lloyd Pique 64818c5d8cc721053be659c92b577217914905883Lloyd Pique connection = setup(s); 65818c5d8cc721053be659c92b577217914905883Lloyd Pique wl_connection_destroy(connection); 66818c5d8cc721053be659c92b577217914905883Lloyd Pique close(s[0]); 67818c5d8cc721053be659c92b577217914905883Lloyd Pique close(s[1]); 68818c5d8cc721053be659c92b577217914905883Lloyd Pique} 69818c5d8cc721053be659c92b577217914905883Lloyd Pique 70818c5d8cc721053be659c92b577217914905883Lloyd PiqueTEST(connection_write) 71818c5d8cc721053be659c92b577217914905883Lloyd Pique{ 72818c5d8cc721053be659c92b577217914905883Lloyd Pique struct wl_connection *connection; 73818c5d8cc721053be659c92b577217914905883Lloyd Pique int s[2]; 74818c5d8cc721053be659c92b577217914905883Lloyd Pique char buffer[64]; 75818c5d8cc721053be659c92b577217914905883Lloyd Pique 76818c5d8cc721053be659c92b577217914905883Lloyd Pique connection = setup(s); 77818c5d8cc721053be659c92b577217914905883Lloyd Pique 78818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(wl_connection_write(connection, message, sizeof message) == 0); 79818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(wl_connection_flush(connection) == sizeof message); 80818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(read(s[1], buffer, sizeof buffer) == sizeof message); 81818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(memcmp(message, buffer, sizeof message) == 0); 82818c5d8cc721053be659c92b577217914905883Lloyd Pique 83818c5d8cc721053be659c92b577217914905883Lloyd Pique wl_connection_destroy(connection); 84818c5d8cc721053be659c92b577217914905883Lloyd Pique close(s[0]); 85818c5d8cc721053be659c92b577217914905883Lloyd Pique close(s[1]); 86818c5d8cc721053be659c92b577217914905883Lloyd Pique} 87818c5d8cc721053be659c92b577217914905883Lloyd Pique 88818c5d8cc721053be659c92b577217914905883Lloyd PiqueTEST(connection_data) 89818c5d8cc721053be659c92b577217914905883Lloyd Pique{ 90818c5d8cc721053be659c92b577217914905883Lloyd Pique struct wl_connection *connection; 91818c5d8cc721053be659c92b577217914905883Lloyd Pique int s[2]; 92818c5d8cc721053be659c92b577217914905883Lloyd Pique char buffer[64]; 93818c5d8cc721053be659c92b577217914905883Lloyd Pique 94818c5d8cc721053be659c92b577217914905883Lloyd Pique connection = setup(s); 95818c5d8cc721053be659c92b577217914905883Lloyd Pique 96818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(write(s[1], message, sizeof message) == sizeof message); 97818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(wl_connection_read(connection) == sizeof message); 98818c5d8cc721053be659c92b577217914905883Lloyd Pique wl_connection_copy(connection, buffer, sizeof message); 99818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(memcmp(message, buffer, sizeof message) == 0); 100818c5d8cc721053be659c92b577217914905883Lloyd Pique wl_connection_consume(connection, sizeof message); 101818c5d8cc721053be659c92b577217914905883Lloyd Pique 102818c5d8cc721053be659c92b577217914905883Lloyd Pique wl_connection_destroy(connection); 103818c5d8cc721053be659c92b577217914905883Lloyd Pique close(s[0]); 104818c5d8cc721053be659c92b577217914905883Lloyd Pique close(s[1]); 105818c5d8cc721053be659c92b577217914905883Lloyd Pique} 106818c5d8cc721053be659c92b577217914905883Lloyd Pique 107818c5d8cc721053be659c92b577217914905883Lloyd PiqueTEST(connection_queue) 108818c5d8cc721053be659c92b577217914905883Lloyd Pique{ 109818c5d8cc721053be659c92b577217914905883Lloyd Pique struct wl_connection *connection; 110818c5d8cc721053be659c92b577217914905883Lloyd Pique int s[2]; 111818c5d8cc721053be659c92b577217914905883Lloyd Pique char buffer[64]; 112818c5d8cc721053be659c92b577217914905883Lloyd Pique 113818c5d8cc721053be659c92b577217914905883Lloyd Pique connection = setup(s); 114818c5d8cc721053be659c92b577217914905883Lloyd Pique 115818c5d8cc721053be659c92b577217914905883Lloyd Pique /* Test that wl_connection_queue() puts data in the output 116818c5d8cc721053be659c92b577217914905883Lloyd Pique * buffer without flush it. Verify that the data did get in 117818c5d8cc721053be659c92b577217914905883Lloyd Pique * the buffer by writing another message and making sure that 118818c5d8cc721053be659c92b577217914905883Lloyd Pique * we receive the two messages on the other fd. */ 119818c5d8cc721053be659c92b577217914905883Lloyd Pique 120818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(wl_connection_queue(connection, message, sizeof message) == 0); 121818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(wl_connection_flush(connection) == 0); 122818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(wl_connection_write(connection, message, sizeof message) == 0); 123818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(wl_connection_flush(connection) == 2 * sizeof message); 124818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(read(s[1], buffer, sizeof buffer) == 2 * sizeof message); 125818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(memcmp(message, buffer, sizeof message) == 0); 126818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(memcmp(message, buffer + sizeof message, sizeof message) == 0); 127818c5d8cc721053be659c92b577217914905883Lloyd Pique 128818c5d8cc721053be659c92b577217914905883Lloyd Pique wl_connection_destroy(connection); 129818c5d8cc721053be659c92b577217914905883Lloyd Pique close(s[0]); 130818c5d8cc721053be659c92b577217914905883Lloyd Pique close(s[1]); 131818c5d8cc721053be659c92b577217914905883Lloyd Pique} 132818c5d8cc721053be659c92b577217914905883Lloyd Pique 133818c5d8cc721053be659c92b577217914905883Lloyd Piquestruct marshal_data { 134818c5d8cc721053be659c92b577217914905883Lloyd Pique struct wl_connection *read_connection; 135818c5d8cc721053be659c92b577217914905883Lloyd Pique struct wl_connection *write_connection; 136818c5d8cc721053be659c92b577217914905883Lloyd Pique int s[2]; 137818c5d8cc721053be659c92b577217914905883Lloyd Pique uint32_t buffer[10]; 138818c5d8cc721053be659c92b577217914905883Lloyd Pique union { 139818c5d8cc721053be659c92b577217914905883Lloyd Pique uint32_t u; 140818c5d8cc721053be659c92b577217914905883Lloyd Pique int32_t i; 141818c5d8cc721053be659c92b577217914905883Lloyd Pique const char *s; 142818c5d8cc721053be659c92b577217914905883Lloyd Pique int h; 143818c5d8cc721053be659c92b577217914905883Lloyd Pique } value; 144818c5d8cc721053be659c92b577217914905883Lloyd Pique}; 145818c5d8cc721053be659c92b577217914905883Lloyd Pique 146818c5d8cc721053be659c92b577217914905883Lloyd Piquestatic void 147818c5d8cc721053be659c92b577217914905883Lloyd Piquesetup_marshal_data(struct marshal_data *data) 148818c5d8cc721053be659c92b577217914905883Lloyd Pique{ 149818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(socketpair(AF_UNIX, 150818c5d8cc721053be659c92b577217914905883Lloyd Pique SOCK_STREAM | SOCK_CLOEXEC, 0, data->s) == 0); 151818c5d8cc721053be659c92b577217914905883Lloyd Pique data->read_connection = wl_connection_create(data->s[0]); 152818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(data->read_connection); 153818c5d8cc721053be659c92b577217914905883Lloyd Pique data->write_connection = wl_connection_create(data->s[1]); 154818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(data->write_connection); 155818c5d8cc721053be659c92b577217914905883Lloyd Pique} 156818c5d8cc721053be659c92b577217914905883Lloyd Pique 157818c5d8cc721053be659c92b577217914905883Lloyd Piquestatic void 158818c5d8cc721053be659c92b577217914905883Lloyd Piquerelease_marshal_data(struct marshal_data *data) 159818c5d8cc721053be659c92b577217914905883Lloyd Pique{ 160818c5d8cc721053be659c92b577217914905883Lloyd Pique close(wl_connection_destroy(data->read_connection)); 161818c5d8cc721053be659c92b577217914905883Lloyd Pique close(wl_connection_destroy(data->write_connection)); 162818c5d8cc721053be659c92b577217914905883Lloyd Pique} 163818c5d8cc721053be659c92b577217914905883Lloyd Pique 164818c5d8cc721053be659c92b577217914905883Lloyd Piquestatic void 165818c5d8cc721053be659c92b577217914905883Lloyd Piquemarshal(struct marshal_data *data, const char *format, int size, ...) 166818c5d8cc721053be659c92b577217914905883Lloyd Pique{ 167818c5d8cc721053be659c92b577217914905883Lloyd Pique struct wl_closure *closure; 168818c5d8cc721053be659c92b577217914905883Lloyd Pique static const uint32_t opcode = 4444; 169818c5d8cc721053be659c92b577217914905883Lloyd Pique static struct wl_object sender = { NULL, NULL, 1234 }; 170818c5d8cc721053be659c92b577217914905883Lloyd Pique struct wl_message message = { "test", format, NULL }; 171818c5d8cc721053be659c92b577217914905883Lloyd Pique va_list ap; 172818c5d8cc721053be659c92b577217914905883Lloyd Pique 173818c5d8cc721053be659c92b577217914905883Lloyd Pique va_start(ap, size); 174818c5d8cc721053be659c92b577217914905883Lloyd Pique closure = wl_closure_vmarshal(&sender, opcode, ap, &message); 175818c5d8cc721053be659c92b577217914905883Lloyd Pique va_end(ap); 176818c5d8cc721053be659c92b577217914905883Lloyd Pique 177818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(closure); 178818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(wl_closure_send(closure, data->write_connection) == 0); 179818c5d8cc721053be659c92b577217914905883Lloyd Pique wl_closure_destroy(closure); 180818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(wl_connection_flush(data->write_connection) == size); 181818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(read(data->s[0], data->buffer, sizeof data->buffer) == size); 182818c5d8cc721053be659c92b577217914905883Lloyd Pique 183818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(data->buffer[0] == sender.id); 184818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(data->buffer[1] == (opcode | (size << 16))); 185818c5d8cc721053be659c92b577217914905883Lloyd Pique} 186818c5d8cc721053be659c92b577217914905883Lloyd Pique 187818c5d8cc721053be659c92b577217914905883Lloyd PiqueTEST(connection_marshal) 188818c5d8cc721053be659c92b577217914905883Lloyd Pique{ 189818c5d8cc721053be659c92b577217914905883Lloyd Pique struct marshal_data data; 190818c5d8cc721053be659c92b577217914905883Lloyd Pique struct wl_object object; 191818c5d8cc721053be659c92b577217914905883Lloyd Pique struct wl_array array; 192818c5d8cc721053be659c92b577217914905883Lloyd Pique static const char text[] = "curry"; 193818c5d8cc721053be659c92b577217914905883Lloyd Pique 194818c5d8cc721053be659c92b577217914905883Lloyd Pique setup_marshal_data(&data); 195818c5d8cc721053be659c92b577217914905883Lloyd Pique 196818c5d8cc721053be659c92b577217914905883Lloyd Pique marshal(&data, "i", 12, 42); 197818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(data.buffer[2] == 42); 198818c5d8cc721053be659c92b577217914905883Lloyd Pique 199818c5d8cc721053be659c92b577217914905883Lloyd Pique marshal(&data, "u", 12, 55); 200818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(data.buffer[2] == 55); 201818c5d8cc721053be659c92b577217914905883Lloyd Pique 202818c5d8cc721053be659c92b577217914905883Lloyd Pique marshal(&data, "s", 20, "frappo"); 203818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(data.buffer[2] == 7); 204818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(strcmp((char *) &data.buffer[3], "frappo") == 0); 205818c5d8cc721053be659c92b577217914905883Lloyd Pique 206818c5d8cc721053be659c92b577217914905883Lloyd Pique object.id = 557799; 207818c5d8cc721053be659c92b577217914905883Lloyd Pique marshal(&data, "o", 12, &object); 208818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(data.buffer[2] == object.id); 209818c5d8cc721053be659c92b577217914905883Lloyd Pique 210818c5d8cc721053be659c92b577217914905883Lloyd Pique marshal(&data, "n", 12, &object); 211818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(data.buffer[2] == object.id); 212818c5d8cc721053be659c92b577217914905883Lloyd Pique 213818c5d8cc721053be659c92b577217914905883Lloyd Pique marshal(&data, "?n", 12, NULL); 214818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(data.buffer[2] == 0); 215818c5d8cc721053be659c92b577217914905883Lloyd Pique 216818c5d8cc721053be659c92b577217914905883Lloyd Pique array.data = (void *) text; 217818c5d8cc721053be659c92b577217914905883Lloyd Pique array.size = sizeof text; 218818c5d8cc721053be659c92b577217914905883Lloyd Pique marshal(&data, "a", 20, &array); 219818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(data.buffer[2] == array.size); 220818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(memcmp(&data.buffer[3], text, array.size) == 0); 221818c5d8cc721053be659c92b577217914905883Lloyd Pique 222818c5d8cc721053be659c92b577217914905883Lloyd Pique release_marshal_data(&data); 223818c5d8cc721053be659c92b577217914905883Lloyd Pique} 224818c5d8cc721053be659c92b577217914905883Lloyd Pique 225818c5d8cc721053be659c92b577217914905883Lloyd Piquestatic void 226818c5d8cc721053be659c92b577217914905883Lloyd Piqueexpected_fail_marshal(int expected_error, const char *format, ...) 227818c5d8cc721053be659c92b577217914905883Lloyd Pique{ 228818c5d8cc721053be659c92b577217914905883Lloyd Pique struct wl_closure *closure; 229818c5d8cc721053be659c92b577217914905883Lloyd Pique static const uint32_t opcode = 4444; 230818c5d8cc721053be659c92b577217914905883Lloyd Pique static const struct wl_interface test_interface = { 231818c5d8cc721053be659c92b577217914905883Lloyd Pique .name = "test_object" 232818c5d8cc721053be659c92b577217914905883Lloyd Pique }; 233818c5d8cc721053be659c92b577217914905883Lloyd Pique static struct wl_object sender = { 0 }; 234818c5d8cc721053be659c92b577217914905883Lloyd Pique struct wl_message message = { "test", format, NULL }; 235818c5d8cc721053be659c92b577217914905883Lloyd Pique 236818c5d8cc721053be659c92b577217914905883Lloyd Pique sender.interface = &test_interface; 237818c5d8cc721053be659c92b577217914905883Lloyd Pique sender.id = 1234; 238818c5d8cc721053be659c92b577217914905883Lloyd Pique va_list ap; 239818c5d8cc721053be659c92b577217914905883Lloyd Pique 240818c5d8cc721053be659c92b577217914905883Lloyd Pique va_start(ap, format); 241818c5d8cc721053be659c92b577217914905883Lloyd Pique closure = wl_closure_vmarshal(&sender, opcode, ap, &message); 242818c5d8cc721053be659c92b577217914905883Lloyd Pique va_end(ap); 243818c5d8cc721053be659c92b577217914905883Lloyd Pique 244818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(closure == NULL); 245818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(errno == expected_error); 246818c5d8cc721053be659c92b577217914905883Lloyd Pique} 247818c5d8cc721053be659c92b577217914905883Lloyd Pique 248818c5d8cc721053be659c92b577217914905883Lloyd Piquestatic void 249818c5d8cc721053be659c92b577217914905883Lloyd Piqueexpected_fail_marshal_send(struct marshal_data *data, int expected_error, 250818c5d8cc721053be659c92b577217914905883Lloyd Pique const char *format, ...) 251818c5d8cc721053be659c92b577217914905883Lloyd Pique{ 252818c5d8cc721053be659c92b577217914905883Lloyd Pique struct wl_closure *closure; 253818c5d8cc721053be659c92b577217914905883Lloyd Pique static const uint32_t opcode = 4444; 254818c5d8cc721053be659c92b577217914905883Lloyd Pique static struct wl_object sender = { NULL, NULL, 1234 }; 255818c5d8cc721053be659c92b577217914905883Lloyd Pique struct wl_message message = { "test", format, NULL }; 256818c5d8cc721053be659c92b577217914905883Lloyd Pique va_list ap; 257818c5d8cc721053be659c92b577217914905883Lloyd Pique 258818c5d8cc721053be659c92b577217914905883Lloyd Pique va_start(ap, format); 259818c5d8cc721053be659c92b577217914905883Lloyd Pique closure = wl_closure_vmarshal(&sender, opcode, ap, &message); 260818c5d8cc721053be659c92b577217914905883Lloyd Pique va_end(ap); 261818c5d8cc721053be659c92b577217914905883Lloyd Pique 262818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(closure); 263818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(wl_closure_send(closure, data->write_connection) < 0); 264818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(errno == expected_error); 265818c5d8cc721053be659c92b577217914905883Lloyd Pique 266818c5d8cc721053be659c92b577217914905883Lloyd Pique wl_closure_destroy(closure); 267818c5d8cc721053be659c92b577217914905883Lloyd Pique} 268818c5d8cc721053be659c92b577217914905883Lloyd Pique 269818c5d8cc721053be659c92b577217914905883Lloyd PiqueTEST(connection_marshal_nullables) 270818c5d8cc721053be659c92b577217914905883Lloyd Pique{ 271818c5d8cc721053be659c92b577217914905883Lloyd Pique struct marshal_data data; 272818c5d8cc721053be659c92b577217914905883Lloyd Pique struct wl_object object; 273818c5d8cc721053be659c92b577217914905883Lloyd Pique struct wl_array array; 274818c5d8cc721053be659c92b577217914905883Lloyd Pique const char text[] = "curry"; 275818c5d8cc721053be659c92b577217914905883Lloyd Pique 276818c5d8cc721053be659c92b577217914905883Lloyd Pique setup_marshal_data(&data); 277818c5d8cc721053be659c92b577217914905883Lloyd Pique 278818c5d8cc721053be659c92b577217914905883Lloyd Pique expected_fail_marshal(EINVAL, "o", NULL); 279818c5d8cc721053be659c92b577217914905883Lloyd Pique expected_fail_marshal(EINVAL, "s", NULL); 280818c5d8cc721053be659c92b577217914905883Lloyd Pique expected_fail_marshal(EINVAL, "a", NULL); 281818c5d8cc721053be659c92b577217914905883Lloyd Pique 282818c5d8cc721053be659c92b577217914905883Lloyd Pique marshal(&data, "?o", 12, NULL); 283818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(data.buffer[2] == 0); 284818c5d8cc721053be659c92b577217914905883Lloyd Pique 285818c5d8cc721053be659c92b577217914905883Lloyd Pique marshal(&data, "?a", 12, NULL); 286818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(data.buffer[2] == 0); 287818c5d8cc721053be659c92b577217914905883Lloyd Pique 288818c5d8cc721053be659c92b577217914905883Lloyd Pique marshal(&data, "?s", 12, NULL); 289818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(data.buffer[2] == 0); 290818c5d8cc721053be659c92b577217914905883Lloyd Pique 291818c5d8cc721053be659c92b577217914905883Lloyd Pique object.id = 55293; 292818c5d8cc721053be659c92b577217914905883Lloyd Pique marshal(&data, "?o", 12, &object); 293818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(data.buffer[2] == object.id); 294818c5d8cc721053be659c92b577217914905883Lloyd Pique 295818c5d8cc721053be659c92b577217914905883Lloyd Pique array.data = (void *) text; 296818c5d8cc721053be659c92b577217914905883Lloyd Pique array.size = sizeof text; 297818c5d8cc721053be659c92b577217914905883Lloyd Pique marshal(&data, "?a", 20, &array); 298818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(data.buffer[2] == array.size); 299818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(memcmp(&data.buffer[3], text, array.size) == 0); 300818c5d8cc721053be659c92b577217914905883Lloyd Pique 301818c5d8cc721053be659c92b577217914905883Lloyd Pique marshal(&data, "?s", 20, text); 302818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(data.buffer[2] == sizeof text); 303818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(strcmp((char *) &data.buffer[3], text) == 0); 304818c5d8cc721053be659c92b577217914905883Lloyd Pique 305818c5d8cc721053be659c92b577217914905883Lloyd Pique release_marshal_data(&data); 306818c5d8cc721053be659c92b577217914905883Lloyd Pique} 307818c5d8cc721053be659c92b577217914905883Lloyd Pique 308818c5d8cc721053be659c92b577217914905883Lloyd Piquestatic void 309818c5d8cc721053be659c92b577217914905883Lloyd Piquevalidate_demarshal_u(struct marshal_data *data, 310818c5d8cc721053be659c92b577217914905883Lloyd Pique struct wl_object *object, uint32_t u) 311818c5d8cc721053be659c92b577217914905883Lloyd Pique{ 312818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(data->value.u == u); 313818c5d8cc721053be659c92b577217914905883Lloyd Pique} 314818c5d8cc721053be659c92b577217914905883Lloyd Pique 315818c5d8cc721053be659c92b577217914905883Lloyd Piquestatic void 316818c5d8cc721053be659c92b577217914905883Lloyd Piquevalidate_demarshal_i(struct marshal_data *data, 317818c5d8cc721053be659c92b577217914905883Lloyd Pique struct wl_object *object, int32_t i) 318818c5d8cc721053be659c92b577217914905883Lloyd Pique{ 319818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(data->value.i == i); 320818c5d8cc721053be659c92b577217914905883Lloyd Pique} 321818c5d8cc721053be659c92b577217914905883Lloyd Pique 322818c5d8cc721053be659c92b577217914905883Lloyd Piquestatic void 323818c5d8cc721053be659c92b577217914905883Lloyd Piquevalidate_demarshal_s(struct marshal_data *data, 324818c5d8cc721053be659c92b577217914905883Lloyd Pique struct wl_object *object, const char *s) 325818c5d8cc721053be659c92b577217914905883Lloyd Pique{ 326818c5d8cc721053be659c92b577217914905883Lloyd Pique if (data->value.s != NULL) 327818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(strcmp(data->value.s, s) == 0); 328818c5d8cc721053be659c92b577217914905883Lloyd Pique else 329818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(s == NULL); 330818c5d8cc721053be659c92b577217914905883Lloyd Pique} 331818c5d8cc721053be659c92b577217914905883Lloyd Pique 332818c5d8cc721053be659c92b577217914905883Lloyd Piquestatic void 333818c5d8cc721053be659c92b577217914905883Lloyd Piquevalidate_demarshal_h(struct marshal_data *data, 334818c5d8cc721053be659c92b577217914905883Lloyd Pique struct wl_object *object, int fd) 335818c5d8cc721053be659c92b577217914905883Lloyd Pique{ 336818c5d8cc721053be659c92b577217914905883Lloyd Pique struct stat buf1, buf2; 337818c5d8cc721053be659c92b577217914905883Lloyd Pique 338818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(fd != data->value.h); 339818c5d8cc721053be659c92b577217914905883Lloyd Pique fstat(fd, &buf1); 340818c5d8cc721053be659c92b577217914905883Lloyd Pique fstat(data->value.h, &buf2); 341818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(buf1.st_dev == buf2.st_dev); 342818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(buf1.st_ino == buf2.st_ino); 343818c5d8cc721053be659c92b577217914905883Lloyd Pique close(fd); 344818c5d8cc721053be659c92b577217914905883Lloyd Pique close(data->value.h); 345818c5d8cc721053be659c92b577217914905883Lloyd Pique} 346818c5d8cc721053be659c92b577217914905883Lloyd Pique 347818c5d8cc721053be659c92b577217914905883Lloyd Piquestatic void 348818c5d8cc721053be659c92b577217914905883Lloyd Piquevalidate_demarshal_f(struct marshal_data *data, 349818c5d8cc721053be659c92b577217914905883Lloyd Pique struct wl_object *object, wl_fixed_t f) 350818c5d8cc721053be659c92b577217914905883Lloyd Pique{ 351818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(data->value.i == f); 352818c5d8cc721053be659c92b577217914905883Lloyd Pique} 353818c5d8cc721053be659c92b577217914905883Lloyd Pique 354818c5d8cc721053be659c92b577217914905883Lloyd Piquestatic void 355818c5d8cc721053be659c92b577217914905883Lloyd Piquedemarshal(struct marshal_data *data, const char *format, 356818c5d8cc721053be659c92b577217914905883Lloyd Pique uint32_t *msg, void (*func)(void)) 357818c5d8cc721053be659c92b577217914905883Lloyd Pique{ 358818c5d8cc721053be659c92b577217914905883Lloyd Pique struct wl_message message = { "test", format, NULL }; 359818c5d8cc721053be659c92b577217914905883Lloyd Pique struct wl_closure *closure; 360818c5d8cc721053be659c92b577217914905883Lloyd Pique struct wl_map objects; 361818c5d8cc721053be659c92b577217914905883Lloyd Pique struct wl_object object = { NULL, &func, 0 }; 362818c5d8cc721053be659c92b577217914905883Lloyd Pique int size = msg[1]; 363818c5d8cc721053be659c92b577217914905883Lloyd Pique 364818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(write(data->s[1], msg, size) == size); 365818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(wl_connection_read(data->read_connection) == size); 366818c5d8cc721053be659c92b577217914905883Lloyd Pique 367818c5d8cc721053be659c92b577217914905883Lloyd Pique wl_map_init(&objects, WL_MAP_SERVER_SIDE); 368818c5d8cc721053be659c92b577217914905883Lloyd Pique object.id = msg[0]; 369818c5d8cc721053be659c92b577217914905883Lloyd Pique closure = wl_connection_demarshal(data->read_connection, 370818c5d8cc721053be659c92b577217914905883Lloyd Pique size, &objects, &message); 371818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(closure); 372818c5d8cc721053be659c92b577217914905883Lloyd Pique wl_closure_invoke(closure, WL_CLOSURE_INVOKE_SERVER, &object, 0, data); 373818c5d8cc721053be659c92b577217914905883Lloyd Pique wl_closure_destroy(closure); 374818c5d8cc721053be659c92b577217914905883Lloyd Pique} 375818c5d8cc721053be659c92b577217914905883Lloyd Pique 376818c5d8cc721053be659c92b577217914905883Lloyd PiqueTEST(connection_demarshal) 377818c5d8cc721053be659c92b577217914905883Lloyd Pique{ 378818c5d8cc721053be659c92b577217914905883Lloyd Pique struct marshal_data data; 379818c5d8cc721053be659c92b577217914905883Lloyd Pique uint32_t msg[10]; 380818c5d8cc721053be659c92b577217914905883Lloyd Pique 381818c5d8cc721053be659c92b577217914905883Lloyd Pique setup_marshal_data(&data); 382818c5d8cc721053be659c92b577217914905883Lloyd Pique 383818c5d8cc721053be659c92b577217914905883Lloyd Pique data.value.u = 8000; 384818c5d8cc721053be659c92b577217914905883Lloyd Pique msg[0] = 400200; /* object id */ 385818c5d8cc721053be659c92b577217914905883Lloyd Pique msg[1] = 12; /* size = 12, opcode = 0 */ 386818c5d8cc721053be659c92b577217914905883Lloyd Pique msg[2] = data.value.u; 387818c5d8cc721053be659c92b577217914905883Lloyd Pique demarshal(&data, "u", msg, (void *) validate_demarshal_u); 388818c5d8cc721053be659c92b577217914905883Lloyd Pique 389818c5d8cc721053be659c92b577217914905883Lloyd Pique data.value.i = -557799; 390818c5d8cc721053be659c92b577217914905883Lloyd Pique msg[0] = 400200; 391818c5d8cc721053be659c92b577217914905883Lloyd Pique msg[1] = 12; 392818c5d8cc721053be659c92b577217914905883Lloyd Pique msg[2] = data.value.i; 393818c5d8cc721053be659c92b577217914905883Lloyd Pique demarshal(&data, "i", msg, (void *) validate_demarshal_i); 394818c5d8cc721053be659c92b577217914905883Lloyd Pique 395818c5d8cc721053be659c92b577217914905883Lloyd Pique data.value.s = "superdude"; 396818c5d8cc721053be659c92b577217914905883Lloyd Pique msg[0] = 400200; 397818c5d8cc721053be659c92b577217914905883Lloyd Pique msg[1] = 24; 398818c5d8cc721053be659c92b577217914905883Lloyd Pique msg[2] = 10; 399818c5d8cc721053be659c92b577217914905883Lloyd Pique memcpy(&msg[3], data.value.s, msg[2]); 400818c5d8cc721053be659c92b577217914905883Lloyd Pique demarshal(&data, "s", msg, (void *) validate_demarshal_s); 401818c5d8cc721053be659c92b577217914905883Lloyd Pique 402818c5d8cc721053be659c92b577217914905883Lloyd Pique data.value.s = "superdude"; 403818c5d8cc721053be659c92b577217914905883Lloyd Pique msg[0] = 400200; 404818c5d8cc721053be659c92b577217914905883Lloyd Pique msg[1] = 24; 405818c5d8cc721053be659c92b577217914905883Lloyd Pique msg[2] = 10; 406818c5d8cc721053be659c92b577217914905883Lloyd Pique memcpy(&msg[3], data.value.s, msg[2]); 407818c5d8cc721053be659c92b577217914905883Lloyd Pique demarshal(&data, "?s", msg, (void *) validate_demarshal_s); 408818c5d8cc721053be659c92b577217914905883Lloyd Pique 409818c5d8cc721053be659c92b577217914905883Lloyd Pique data.value.i = wl_fixed_from_double(-90000.2390); 410818c5d8cc721053be659c92b577217914905883Lloyd Pique msg[0] = 400200; 411818c5d8cc721053be659c92b577217914905883Lloyd Pique msg[1] = 12; 412818c5d8cc721053be659c92b577217914905883Lloyd Pique msg[2] = data.value.i; 413818c5d8cc721053be659c92b577217914905883Lloyd Pique demarshal(&data, "f", msg, (void *) validate_demarshal_f); 414818c5d8cc721053be659c92b577217914905883Lloyd Pique 415818c5d8cc721053be659c92b577217914905883Lloyd Pique data.value.s = NULL; 416818c5d8cc721053be659c92b577217914905883Lloyd Pique msg[0] = 400200; 417818c5d8cc721053be659c92b577217914905883Lloyd Pique msg[1] = 12; 418818c5d8cc721053be659c92b577217914905883Lloyd Pique msg[2] = 0; 419818c5d8cc721053be659c92b577217914905883Lloyd Pique demarshal(&data, "?s", msg, (void *) validate_demarshal_s); 420818c5d8cc721053be659c92b577217914905883Lloyd Pique 421818c5d8cc721053be659c92b577217914905883Lloyd Pique release_marshal_data(&data); 422818c5d8cc721053be659c92b577217914905883Lloyd Pique} 423818c5d8cc721053be659c92b577217914905883Lloyd Pique 424818c5d8cc721053be659c92b577217914905883Lloyd Piquestatic void 425818c5d8cc721053be659c92b577217914905883Lloyd Piquemarshal_demarshal(struct marshal_data *data, 426818c5d8cc721053be659c92b577217914905883Lloyd Pique void (*func)(void), int size, const char *format, ...) 427818c5d8cc721053be659c92b577217914905883Lloyd Pique{ 428818c5d8cc721053be659c92b577217914905883Lloyd Pique struct wl_closure *closure; 429818c5d8cc721053be659c92b577217914905883Lloyd Pique static const int opcode = 4444; 430818c5d8cc721053be659c92b577217914905883Lloyd Pique static struct wl_object sender = { NULL, NULL, 1234 }; 431818c5d8cc721053be659c92b577217914905883Lloyd Pique struct wl_message message = { "test", format, NULL }; 432818c5d8cc721053be659c92b577217914905883Lloyd Pique struct wl_map objects; 433818c5d8cc721053be659c92b577217914905883Lloyd Pique struct wl_object object = { NULL, &func, 0 }; 434818c5d8cc721053be659c92b577217914905883Lloyd Pique va_list ap; 435818c5d8cc721053be659c92b577217914905883Lloyd Pique uint32_t msg[1] = { 1234 }; 436818c5d8cc721053be659c92b577217914905883Lloyd Pique 437818c5d8cc721053be659c92b577217914905883Lloyd Pique va_start(ap, format); 438818c5d8cc721053be659c92b577217914905883Lloyd Pique closure = wl_closure_vmarshal(&sender, opcode, ap, &message); 439818c5d8cc721053be659c92b577217914905883Lloyd Pique va_end(ap); 440818c5d8cc721053be659c92b577217914905883Lloyd Pique 441818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(closure); 442818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(wl_closure_send(closure, data->write_connection) == 0); 443818c5d8cc721053be659c92b577217914905883Lloyd Pique wl_closure_destroy(closure); 444818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(wl_connection_flush(data->write_connection) == size); 445818c5d8cc721053be659c92b577217914905883Lloyd Pique 446818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(wl_connection_read(data->read_connection) == size); 447818c5d8cc721053be659c92b577217914905883Lloyd Pique 448818c5d8cc721053be659c92b577217914905883Lloyd Pique wl_map_init(&objects, WL_MAP_SERVER_SIDE); 449818c5d8cc721053be659c92b577217914905883Lloyd Pique object.id = msg[0]; 450818c5d8cc721053be659c92b577217914905883Lloyd Pique closure = wl_connection_demarshal(data->read_connection, 451818c5d8cc721053be659c92b577217914905883Lloyd Pique size, &objects, &message); 452818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(closure); 453818c5d8cc721053be659c92b577217914905883Lloyd Pique wl_closure_invoke(closure, WL_CLOSURE_INVOKE_SERVER, &object, 0, data); 454818c5d8cc721053be659c92b577217914905883Lloyd Pique wl_closure_destroy(closure); 455818c5d8cc721053be659c92b577217914905883Lloyd Pique} 456818c5d8cc721053be659c92b577217914905883Lloyd Pique 457818c5d8cc721053be659c92b577217914905883Lloyd PiqueTEST(connection_marshal_demarshal) 458818c5d8cc721053be659c92b577217914905883Lloyd Pique{ 459818c5d8cc721053be659c92b577217914905883Lloyd Pique struct marshal_data data; 460818c5d8cc721053be659c92b577217914905883Lloyd Pique char f[] = "/tmp/wayland-tests-XXXXXX"; 461818c5d8cc721053be659c92b577217914905883Lloyd Pique 462818c5d8cc721053be659c92b577217914905883Lloyd Pique setup_marshal_data(&data); 463818c5d8cc721053be659c92b577217914905883Lloyd Pique 464818c5d8cc721053be659c92b577217914905883Lloyd Pique data.value.u = 889911; 465818c5d8cc721053be659c92b577217914905883Lloyd Pique marshal_demarshal(&data, (void *) validate_demarshal_u, 466818c5d8cc721053be659c92b577217914905883Lloyd Pique 12, "u", data.value.u); 467818c5d8cc721053be659c92b577217914905883Lloyd Pique 468818c5d8cc721053be659c92b577217914905883Lloyd Pique data.value.i = -13; 469818c5d8cc721053be659c92b577217914905883Lloyd Pique marshal_demarshal(&data, (void *) validate_demarshal_i, 470818c5d8cc721053be659c92b577217914905883Lloyd Pique 12, "i", data.value.i); 471818c5d8cc721053be659c92b577217914905883Lloyd Pique 472818c5d8cc721053be659c92b577217914905883Lloyd Pique data.value.s = "cookie robots"; 473818c5d8cc721053be659c92b577217914905883Lloyd Pique marshal_demarshal(&data, (void *) validate_demarshal_s, 474818c5d8cc721053be659c92b577217914905883Lloyd Pique 28, "s", data.value.s); 475818c5d8cc721053be659c92b577217914905883Lloyd Pique 476818c5d8cc721053be659c92b577217914905883Lloyd Pique data.value.s = "cookie robots"; 477818c5d8cc721053be659c92b577217914905883Lloyd Pique marshal_demarshal(&data, (void *) validate_demarshal_s, 478818c5d8cc721053be659c92b577217914905883Lloyd Pique 28, "?s", data.value.s); 479818c5d8cc721053be659c92b577217914905883Lloyd Pique 480818c5d8cc721053be659c92b577217914905883Lloyd Pique data.value.h = mkstemp(f); 481818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(data.value.h >= 0); 482818c5d8cc721053be659c92b577217914905883Lloyd Pique unlink(f); 483818c5d8cc721053be659c92b577217914905883Lloyd Pique marshal_demarshal(&data, (void *) validate_demarshal_h, 484818c5d8cc721053be659c92b577217914905883Lloyd Pique 8, "h", data.value.h); 485818c5d8cc721053be659c92b577217914905883Lloyd Pique 486818c5d8cc721053be659c92b577217914905883Lloyd Pique data.value.i = wl_fixed_from_double(1234.5678); 487818c5d8cc721053be659c92b577217914905883Lloyd Pique marshal_demarshal(&data, (void *) validate_demarshal_f, 488818c5d8cc721053be659c92b577217914905883Lloyd Pique 12, "f", data.value.i); 489818c5d8cc721053be659c92b577217914905883Lloyd Pique 490818c5d8cc721053be659c92b577217914905883Lloyd Pique data.value.i = wl_fixed_from_double(-90000.2390); 491818c5d8cc721053be659c92b577217914905883Lloyd Pique marshal_demarshal(&data, (void *) validate_demarshal_f, 492818c5d8cc721053be659c92b577217914905883Lloyd Pique 12, "f", data.value.i); 493818c5d8cc721053be659c92b577217914905883Lloyd Pique 494818c5d8cc721053be659c92b577217914905883Lloyd Pique data.value.i = wl_fixed_from_double((1 << 23) - 1 + 0.0941); 495818c5d8cc721053be659c92b577217914905883Lloyd Pique marshal_demarshal(&data, (void *) validate_demarshal_f, 496818c5d8cc721053be659c92b577217914905883Lloyd Pique 12, "f", data.value.i); 497818c5d8cc721053be659c92b577217914905883Lloyd Pique 498818c5d8cc721053be659c92b577217914905883Lloyd Pique release_marshal_data(&data); 499818c5d8cc721053be659c92b577217914905883Lloyd Pique} 500818c5d8cc721053be659c92b577217914905883Lloyd Pique 501818c5d8cc721053be659c92b577217914905883Lloyd PiqueTEST(connection_marshal_alot) 502818c5d8cc721053be659c92b577217914905883Lloyd Pique{ 503818c5d8cc721053be659c92b577217914905883Lloyd Pique struct marshal_data data; 504818c5d8cc721053be659c92b577217914905883Lloyd Pique char f[64]; 505818c5d8cc721053be659c92b577217914905883Lloyd Pique int i; 506818c5d8cc721053be659c92b577217914905883Lloyd Pique 507818c5d8cc721053be659c92b577217914905883Lloyd Pique setup_marshal_data(&data); 508818c5d8cc721053be659c92b577217914905883Lloyd Pique 509818c5d8cc721053be659c92b577217914905883Lloyd Pique /* We iterate enough to make sure we wrap the circular buffers 510818c5d8cc721053be659c92b577217914905883Lloyd Pique * for both regular data an fds. */ 511818c5d8cc721053be659c92b577217914905883Lloyd Pique 512818c5d8cc721053be659c92b577217914905883Lloyd Pique for (i = 0; i < 2000; i++) { 513818c5d8cc721053be659c92b577217914905883Lloyd Pique strcpy(f, "/tmp/wayland-tests-XXXXXX"); 514818c5d8cc721053be659c92b577217914905883Lloyd Pique data.value.h = mkstemp(f); 515818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(data.value.h >= 0); 516818c5d8cc721053be659c92b577217914905883Lloyd Pique unlink(f); 517818c5d8cc721053be659c92b577217914905883Lloyd Pique marshal_demarshal(&data, (void *) validate_demarshal_h, 518818c5d8cc721053be659c92b577217914905883Lloyd Pique 8, "h", data.value.h); 519818c5d8cc721053be659c92b577217914905883Lloyd Pique } 520818c5d8cc721053be659c92b577217914905883Lloyd Pique 521818c5d8cc721053be659c92b577217914905883Lloyd Pique release_marshal_data(&data); 522818c5d8cc721053be659c92b577217914905883Lloyd Pique} 523818c5d8cc721053be659c92b577217914905883Lloyd Pique 524818c5d8cc721053be659c92b577217914905883Lloyd PiqueTEST(connection_marshal_too_big) 525818c5d8cc721053be659c92b577217914905883Lloyd Pique{ 526818c5d8cc721053be659c92b577217914905883Lloyd Pique struct marshal_data data; 527818c5d8cc721053be659c92b577217914905883Lloyd Pique char *big_string = malloc(5000); 528818c5d8cc721053be659c92b577217914905883Lloyd Pique 529818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(big_string); 530818c5d8cc721053be659c92b577217914905883Lloyd Pique 531818c5d8cc721053be659c92b577217914905883Lloyd Pique memset(big_string, ' ', 4999); 532818c5d8cc721053be659c92b577217914905883Lloyd Pique big_string[4999] = '\0'; 533818c5d8cc721053be659c92b577217914905883Lloyd Pique 534818c5d8cc721053be659c92b577217914905883Lloyd Pique setup_marshal_data(&data); 535818c5d8cc721053be659c92b577217914905883Lloyd Pique 536818c5d8cc721053be659c92b577217914905883Lloyd Pique expected_fail_marshal_send(&data, E2BIG, "s", big_string); 537818c5d8cc721053be659c92b577217914905883Lloyd Pique 538818c5d8cc721053be659c92b577217914905883Lloyd Pique release_marshal_data(&data); 539818c5d8cc721053be659c92b577217914905883Lloyd Pique free(big_string); 540818c5d8cc721053be659c92b577217914905883Lloyd Pique} 541818c5d8cc721053be659c92b577217914905883Lloyd Pique 542818c5d8cc721053be659c92b577217914905883Lloyd Piquestatic void 543818c5d8cc721053be659c92b577217914905883Lloyd Piquemarshal_helper(const char *format, void *handler, ...) 544818c5d8cc721053be659c92b577217914905883Lloyd Pique{ 545818c5d8cc721053be659c92b577217914905883Lloyd Pique struct wl_closure *closure; 546818c5d8cc721053be659c92b577217914905883Lloyd Pique static struct wl_object sender = { NULL, NULL, 1234 }; 547818c5d8cc721053be659c92b577217914905883Lloyd Pique struct wl_object object = { NULL, &handler, 0 }; 548818c5d8cc721053be659c92b577217914905883Lloyd Pique static const int opcode = 4444; 549818c5d8cc721053be659c92b577217914905883Lloyd Pique struct wl_message message = { "test", format, NULL }; 550818c5d8cc721053be659c92b577217914905883Lloyd Pique va_list ap; 551818c5d8cc721053be659c92b577217914905883Lloyd Pique int done; 552818c5d8cc721053be659c92b577217914905883Lloyd Pique 553818c5d8cc721053be659c92b577217914905883Lloyd Pique va_start(ap, handler); 554818c5d8cc721053be659c92b577217914905883Lloyd Pique closure = wl_closure_vmarshal(&sender, opcode, ap, &message); 555818c5d8cc721053be659c92b577217914905883Lloyd Pique va_end(ap); 556818c5d8cc721053be659c92b577217914905883Lloyd Pique 557818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(closure); 558818c5d8cc721053be659c92b577217914905883Lloyd Pique done = 0; 559818c5d8cc721053be659c92b577217914905883Lloyd Pique wl_closure_invoke(closure, WL_CLOSURE_INVOKE_SERVER, &object, 0, &done); 560818c5d8cc721053be659c92b577217914905883Lloyd Pique wl_closure_destroy(closure); 561818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(done); 562818c5d8cc721053be659c92b577217914905883Lloyd Pique} 563818c5d8cc721053be659c92b577217914905883Lloyd Pique 564818c5d8cc721053be659c92b577217914905883Lloyd Piquestatic void 565818c5d8cc721053be659c92b577217914905883Lloyd Piquesuu_handler(void *data, struct wl_object *object, 566818c5d8cc721053be659c92b577217914905883Lloyd Pique const char *s, uint32_t u1, uint32_t u2) 567818c5d8cc721053be659c92b577217914905883Lloyd Pique{ 568818c5d8cc721053be659c92b577217914905883Lloyd Pique int *done = data; 569818c5d8cc721053be659c92b577217914905883Lloyd Pique 570818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(strcmp(s, "foo") == 0); 571818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(u1 = 500); 572818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(u2 = 404040); 573818c5d8cc721053be659c92b577217914905883Lloyd Pique *done = 1; 574818c5d8cc721053be659c92b577217914905883Lloyd Pique} 575818c5d8cc721053be659c92b577217914905883Lloyd Pique 576818c5d8cc721053be659c92b577217914905883Lloyd PiqueTEST(invoke_closure) 577818c5d8cc721053be659c92b577217914905883Lloyd Pique{ 578818c5d8cc721053be659c92b577217914905883Lloyd Pique marshal_helper("suu", suu_handler, "foo", 500, 404040); 579818c5d8cc721053be659c92b577217914905883Lloyd Pique} 580818c5d8cc721053be659c92b577217914905883Lloyd Pique 581818c5d8cc721053be659c92b577217914905883Lloyd Piquestatic void 582818c5d8cc721053be659c92b577217914905883Lloyd Piqueleak_closure(void) 583818c5d8cc721053be659c92b577217914905883Lloyd Pique{ 584818c5d8cc721053be659c92b577217914905883Lloyd Pique struct wl_callback *cb; 585818c5d8cc721053be659c92b577217914905883Lloyd Pique struct pollfd pfd; 586818c5d8cc721053be659c92b577217914905883Lloyd Pique struct client *c = client_connect(); 587818c5d8cc721053be659c92b577217914905883Lloyd Pique 588818c5d8cc721053be659c92b577217914905883Lloyd Pique cb = wl_display_sync(c->wl_display); 589818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(cb); 590818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(wl_display_flush(c->wl_display) > 0); 591818c5d8cc721053be659c92b577217914905883Lloyd Pique 592818c5d8cc721053be659c92b577217914905883Lloyd Pique /* we don't need it, it is referenced */ 593818c5d8cc721053be659c92b577217914905883Lloyd Pique wl_callback_destroy(cb); 594818c5d8cc721053be659c92b577217914905883Lloyd Pique 595818c5d8cc721053be659c92b577217914905883Lloyd Pique pfd.fd = wl_display_get_fd(c->wl_display); 596818c5d8cc721053be659c92b577217914905883Lloyd Pique pfd.events = POLLIN; 597818c5d8cc721053be659c92b577217914905883Lloyd Pique 598818c5d8cc721053be659c92b577217914905883Lloyd Pique test_set_timeout(2); 599818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(poll(&pfd, 1, -1) == 1); 600818c5d8cc721053be659c92b577217914905883Lloyd Pique 601818c5d8cc721053be659c92b577217914905883Lloyd Pique /* read events, but do not dispatch them */ 602818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(wl_display_prepare_read(c->wl_display) == 0); 603818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(wl_display_read_events(c->wl_display) == 0); 604818c5d8cc721053be659c92b577217914905883Lloyd Pique 605818c5d8cc721053be659c92b577217914905883Lloyd Pique /* 606818c5d8cc721053be659c92b577217914905883Lloyd Pique * now we have wl_callback.done and wl_display.delete_id queued; 607818c5d8cc721053be659c92b577217914905883Lloyd Pique * if we now release the queue (in wl_display_disconnect()) 608818c5d8cc721053be659c92b577217914905883Lloyd Pique * we should not leak memory 609818c5d8cc721053be659c92b577217914905883Lloyd Pique */ 610818c5d8cc721053be659c92b577217914905883Lloyd Pique 611818c5d8cc721053be659c92b577217914905883Lloyd Pique client_disconnect(c); 612818c5d8cc721053be659c92b577217914905883Lloyd Pique} 613818c5d8cc721053be659c92b577217914905883Lloyd Pique 614818c5d8cc721053be659c92b577217914905883Lloyd PiqueTEST(closure_leaks) 615818c5d8cc721053be659c92b577217914905883Lloyd Pique{ 616818c5d8cc721053be659c92b577217914905883Lloyd Pique struct display *d = display_create(); 617818c5d8cc721053be659c92b577217914905883Lloyd Pique 618eed3fcdc3cd245a2acfa4bb72ac4dac683c4cf62Dennis Kempin client_create_noarg(d, leak_closure); 619818c5d8cc721053be659c92b577217914905883Lloyd Pique display_run(d); 620818c5d8cc721053be659c92b577217914905883Lloyd Pique 621818c5d8cc721053be659c92b577217914905883Lloyd Pique display_destroy(d); 622818c5d8cc721053be659c92b577217914905883Lloyd Pique} 623818c5d8cc721053be659c92b577217914905883Lloyd Pique 624818c5d8cc721053be659c92b577217914905883Lloyd Piquestatic void 625818c5d8cc721053be659c92b577217914905883Lloyd Piqueleak_after_error(void) 626818c5d8cc721053be659c92b577217914905883Lloyd Pique{ 627818c5d8cc721053be659c92b577217914905883Lloyd Pique struct client *c = client_connect(); 628818c5d8cc721053be659c92b577217914905883Lloyd Pique 629818c5d8cc721053be659c92b577217914905883Lloyd Pique /* this should return -1, because we'll send error 630818c5d8cc721053be659c92b577217914905883Lloyd Pique * from server. */ 631818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(stop_display(c, 1) == -1); 632818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(wl_display_dispatch_pending(c->wl_display) == -1); 633818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(wl_display_get_error(c->wl_display) == ENOMEM); 634818c5d8cc721053be659c92b577217914905883Lloyd Pique 635818c5d8cc721053be659c92b577217914905883Lloyd Pique /* after we got error, we have display_resume event 636818c5d8cc721053be659c92b577217914905883Lloyd Pique * in the queue. It should be freed in wl_display_disconnect(). 637818c5d8cc721053be659c92b577217914905883Lloyd Pique * Let's see! */ 638818c5d8cc721053be659c92b577217914905883Lloyd Pique 639818c5d8cc721053be659c92b577217914905883Lloyd Pique wl_proxy_destroy((struct wl_proxy *) c->tc); 640818c5d8cc721053be659c92b577217914905883Lloyd Pique wl_display_disconnect(c->wl_display); 641818c5d8cc721053be659c92b577217914905883Lloyd Pique free(c); 642818c5d8cc721053be659c92b577217914905883Lloyd Pique} 643818c5d8cc721053be659c92b577217914905883Lloyd Pique 644818c5d8cc721053be659c92b577217914905883Lloyd PiqueTEST(closure_leaks_after_error) 645818c5d8cc721053be659c92b577217914905883Lloyd Pique{ 646818c5d8cc721053be659c92b577217914905883Lloyd Pique struct display *d = display_create(); 647818c5d8cc721053be659c92b577217914905883Lloyd Pique struct client_info *cl; 648818c5d8cc721053be659c92b577217914905883Lloyd Pique 649eed3fcdc3cd245a2acfa4bb72ac4dac683c4cf62Dennis Kempin cl = client_create_noarg(d, leak_after_error); 650818c5d8cc721053be659c92b577217914905883Lloyd Pique display_run(d); 651818c5d8cc721053be659c92b577217914905883Lloyd Pique 652818c5d8cc721053be659c92b577217914905883Lloyd Pique wl_client_post_no_memory(cl->wl_client); 653818c5d8cc721053be659c92b577217914905883Lloyd Pique display_resume(d); 654818c5d8cc721053be659c92b577217914905883Lloyd Pique 655818c5d8cc721053be659c92b577217914905883Lloyd Pique display_destroy(d); 656818c5d8cc721053be659c92b577217914905883Lloyd Pique} 657