wayland-server.c 58.1 KB
Newer Older
1 2 3
/*
 * Copyright © 2008 Kristian Høgsberg
 *
4 5 6 7 8 9 10
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
11
 *
12 13 14 15 16 17 18 19 20 21 22 23
 * The above copyright notice and this permission notice (including the
 * next paragraph) shall be included in all copies or substantial
 * portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
24 25
 */

26 27
#define _GNU_SOURCE

Kristian Høgsberg's avatar
Kristian Høgsberg committed
28 29 30 31
#include <stdlib.h>
#include <stdint.h>
#include <stddef.h>
#include <stdio.h>
32
#include <stdarg.h>
33
#include <stdbool.h>
Kristian Høgsberg's avatar
Kristian Høgsberg committed
34 35 36 37 38
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>
39
#include <dlfcn.h>
40
#include <assert.h>
41
#include <sys/time.h>
42
#include <fcntl.h>
43 44
#include <sys/file.h>
#include <sys/stat.h>
45

46
#include "wayland-util.h"
47
#include "wayland-private.h"
48
#include "wayland-server.h"
49
#include "wayland-os.h"
Kristian Høgsberg's avatar
Kristian Høgsberg committed
50

51
/* This is the size of the char array in struct sock_addr_un.
52 53 54
 * No Wayland socket can be created with a path longer than this,
 * including the null terminator.
 */
55 56 57 58 59 60 61
#ifndef UNIX_PATH_MAX
#define UNIX_PATH_MAX	108
#endif

#define LOCK_SUFFIX	".lock"
#define LOCK_SUFFIXLEN	5

62 63
struct wl_socket {
	int fd;
64
	int fd_lock;
65
	struct sockaddr_un addr;
66
	char lock_addr[UNIX_PATH_MAX + LOCK_SUFFIXLEN];
67
	struct wl_list link;
68
	struct wl_event_source *source;
69
	char *display_name;
70 71
};

Kristian Høgsberg's avatar
Kristian Høgsberg committed
72
struct wl_client {
73
	struct wl_connection *connection;
Kristian Høgsberg's avatar
Kristian Høgsberg committed
74 75
	struct wl_event_source *source;
	struct wl_display *display;
76
	struct wl_resource *display_resource;
77
	struct wl_list link;
78
	struct wl_map objects;
79
	struct wl_priv_signal destroy_signal;
80
	struct ucred ucred;
81
	int error;
82
	struct wl_priv_signal resource_created_signal;
Kristian Høgsberg's avatar
Kristian Høgsberg committed
83 84 85 86
};

struct wl_display {
	struct wl_event_loop *loop;
87
	int run;
88

89
	uint32_t id;
90
	uint32_t serial;
91

92
	struct wl_list registry_resource_list;
93
	struct wl_list global_list;
94
	struct wl_list socket_list;
95
	struct wl_list client_list;
96
	struct wl_list protocol_loggers;
97

98 99
	struct wl_priv_signal destroy_signal;
	struct wl_priv_signal create_client_signal;
100 101

	struct wl_array additional_shm_formats;
102 103 104

	wl_display_global_filter_func_t global_filter;
	void *global_filter_data;
Kristian Høgsberg's avatar
Kristian Høgsberg committed
105 106
};

107
struct wl_global {
108
	struct wl_display *display;
109 110
	const struct wl_interface *interface;
	uint32_t name;
111
	uint32_t version;
112
	void *data;
113
	wl_global_bind_func_t bind;
114 115 116
	struct wl_list link;
};

117 118 119 120
struct wl_resource {
	struct wl_object object;
	wl_resource_destroy_func_t destroy;
	struct wl_list link;
121 122 123 124 125
	/* Unfortunately some users of libwayland (e.g. mesa) still use the
	 * deprecated wl_resource struct, even if creating it with the new
	 * wl_resource_create(). So we cannot change the layout of the struct
	 * unless after the data field. */
	struct wl_signal deprecated_destroy_signal;
126 127
	struct wl_client *client;
	void *data;
128
	int version;
129
	wl_dispatcher_func_t dispatcher;
130
	struct wl_priv_signal destroy_signal;
131 132
};

133 134 135 136 137 138
struct wl_protocol_logger {
	struct wl_list link;
	wl_protocol_logger_func_t func;
	void *user_data;
};

139
static int debug_server = 0;
140

141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
static void
log_closure(struct wl_resource *resource,
	    struct wl_closure *closure, int send)
{
	struct wl_object *object = &resource->object;
	struct wl_display *display = resource->client->display;
	struct wl_protocol_logger *protocol_logger;
	struct wl_protocol_logger_message message;

	if (debug_server)
		wl_closure_print(closure, object, send);

	if (!wl_list_empty(&display->protocol_loggers)) {
		message.resource = resource;
		message.message_opcode = closure->opcode;
		message.message = closure->message;
		message.arguments_count = closure->count;
		message.arguments = closure->args;
		wl_list_for_each(protocol_logger,
				 &display->protocol_loggers, link) {
			protocol_logger->func(protocol_logger->user_data,
					      send ? WL_PROTOCOL_LOGGER_EVENT :
						     WL_PROTOCOL_LOGGER_REQUEST,
					      &message);
		}
	}
}

169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198
static bool
verify_objects(struct wl_resource *resource, uint32_t opcode,
	       union wl_argument *args)
{
	struct wl_object *object = &resource->object;
	const char *signature = object->interface->events[opcode].signature;
	struct argument_details arg;
	struct wl_resource *res;
	int count, i;

	count = arg_count_for_signature(signature);
	for (i = 0; i < count; i++) {
		signature = get_next_argument(signature, &arg);
		switch (arg.type) {
		case 'n':
		case 'o':
			res = (struct wl_resource *) (args[i].o);
			if (res && res->client != resource->client) {
				wl_log("compositor bug: The compositor "
				       "tried to use an object from one "
				       "client in a '%s.%s' for a different "
				       "client.\n", object->interface->name,
				       object->interface->events[opcode].name);
				return false;
			}
		}
	}
	return true;
}

199 200 201 202
static void
handle_array(struct wl_resource *resource, uint32_t opcode,
	     union wl_argument *args,
	     int (*send_func)(struct wl_closure *, struct wl_connection *))
203
{
204
	struct wl_closure *closure;
205
	struct wl_object *object = &resource->object;
206

207 208 209
	if (resource->client->error)
		return;

210 211 212 213 214
	if (!verify_objects(resource, opcode, args)) {
		resource->client->error = 1;
		return;
	}

215 216
	closure = wl_closure_marshal(object, opcode, args,
				     &object->interface->events[opcode]);
217

218
	if (closure == NULL) {
219
		resource->client->error = 1;
220
		return;
221
	}
222

223 224
	log_closure(resource, closure, true);

225
	if (send_func(closure, resource->client->connection))
226
		resource->client->error = 1;
227

228
	wl_closure_destroy(closure);
229 230
}

231 232 233 234 235 236 237
WL_EXPORT void
wl_resource_post_event_array(struct wl_resource *resource, uint32_t opcode,
			     union wl_argument *args)
{
	handle_array(resource, opcode, args, wl_closure_send);
}

238
WL_EXPORT void
239
wl_resource_post_event(struct wl_resource *resource, uint32_t opcode, ...)
240
{
241
	union wl_argument args[WL_CLOSURE_MAX_ARGS];
242 243 244 245
	struct wl_object *object = &resource->object;
	va_list ap;

	va_start(ap, opcode);
246 247
	wl_argument_from_va_list(object->interface->events[opcode].signature,
				 args, WL_CLOSURE_MAX_ARGS, ap);
248 249
	va_end(ap);

250 251 252 253 254 255 256 257
	wl_resource_post_event_array(resource, opcode, args);
}


WL_EXPORT void
wl_resource_queue_event_array(struct wl_resource *resource, uint32_t opcode,
			      union wl_argument *args)
{
258
	handle_array(resource, opcode, args, wl_closure_queue);
259 260
}

261 262 263 264 265 266 267 268 269 270 271 272 273 274 275
WL_EXPORT void
wl_resource_queue_event(struct wl_resource *resource, uint32_t opcode, ...)
{
	union wl_argument args[WL_CLOSURE_MAX_ARGS];
	struct wl_object *object = &resource->object;
	va_list ap;

	va_start(ap, opcode);
	wl_argument_from_va_list(object->interface->events[opcode].signature,
				 args, WL_CLOSURE_MAX_ARGS, ap);
	va_end(ap);

	wl_resource_queue_event_array(resource, opcode, args);
}

276 277 278
static void
wl_resource_post_error_vargs(struct wl_resource *resource,
			     uint32_t code, const char *msg, va_list argp)
279
{
280
	struct wl_client *client = resource->client;
281 282
	char buffer[128];

283
	vsnprintf(buffer, sizeof buffer, msg, argp);
284

285 286 287 288 289 290 291
	/*
	 * When a client aborts, its resources are destroyed in id order,
	 * which means the display resource is destroyed first. If destruction
	 * of any later resources results in a protocol error, we end up here
	 * with a NULL display_resource. Do not try to send errors to an
	 * already dead client.
	 */
292
	if (client->error || !client->display_resource)
293 294
		return;

295
	wl_resource_post_event(client->display_resource,
296
			       WL_DISPLAY_ERROR, resource, code, buffer);
297
	client->error = 1;
298 299 300 301 302 303 304 305 306 307 308 309

}

WL_EXPORT void
wl_resource_post_error(struct wl_resource *resource,
		       uint32_t code, const char *msg, ...)
{
	va_list ap;

	va_start(ap, msg);
	wl_resource_post_error_vargs(resource, code, msg, ap);
	va_end(ap);
310 311
}

312 313 314 315 316 317 318
static void
destroy_client_with_error(struct wl_client *client, const char *reason)
{
	wl_log("%s (pid %u)\n", reason, client->ucred.pid);
	wl_client_destroy(client);
}

319
static int
320
wl_client_connection_data(int fd, uint32_t mask, void *data)
321
{
322 323
	struct wl_client *client = data;
	struct wl_connection *connection = client->connection;
324
	struct wl_resource *resource;
325
	struct wl_object *object;
326
	struct wl_closure *closure;
327
	const struct wl_message *message;
328
	uint32_t p[2];
329
	uint32_t resource_flags;
330
	int opcode, size, since;
331
	int len;
332

333
	if (mask & WL_EVENT_HANGUP) {
334
		wl_client_destroy(client);
335
		return 1;
336
	}
337

338 339 340 341 342
	if (mask & WL_EVENT_ERROR) {
		destroy_client_with_error(client, "socket error");
		return 1;
	}

343 344 345
	if (mask & WL_EVENT_WRITABLE) {
		len = wl_connection_flush(connection);
		if (len < 0 && errno != EAGAIN) {
346 347
			destroy_client_with_error(
			    client, "failed to flush client connection");
348 349 350 351 352 353 354 355 356 357
			return 1;
		} else if (len >= 0) {
			wl_event_source_fd_update(client->source,
						  WL_EVENT_READABLE);
		}
	}

	len = 0;
	if (mask & WL_EVENT_READABLE) {
		len = wl_connection_read(connection);
358
		if (len == 0 || (len < 0 && errno != EAGAIN)) {
359 360
			destroy_client_with_error(
			    client, "failed to read client connection");
361 362 363 364
			return 1;
		}
	}

365
	while (len >= 0 && (size_t) len >= sizeof p) {
366
		wl_connection_copy(connection, p, sizeof p);
367 368
		opcode = p[1] & 0xffff;
		size = p[1] >> 16;
369
		if (len < size)
370 371
			break;

372
		resource = wl_map_lookup(&client->objects, p[0]);
373
		resource_flags = wl_map_lookup_flags(&client->objects, p[0]);
374
		if (resource == NULL) {
375
			wl_resource_post_error(client->display_resource,
376
					       WL_DISPLAY_ERROR_INVALID_OBJECT,
377
					       "invalid object %u", p[0]);
378
			break;
379
		}
380

381
		object = &resource->object;
382
		if (opcode >= object->interface->method_count) {
383
			wl_resource_post_error(client->display_resource,
384
					       WL_DISPLAY_ERROR_INVALID_METHOD,
385
					       "invalid method %d, object %s@%u",
386
					       opcode,
387
					       object->interface->name,
388
					       object->id);
389
			break;
390
		}
391

392
		message = &object->interface->methods[opcode];
393
		since = wl_message_get_since(message);
394
		if (!(resource_flags & WL_MAP_ENTRY_LEGACY) &&
395
		    resource->version > 0 && resource->version < since) {
396 397
			wl_resource_post_error(client->display_resource,
					       WL_DISPLAY_ERROR_INVALID_METHOD,
398 399 400
					       "invalid method %d (since %d < %d)"
					       ", object %s@%u",
					       opcode, resource->version, since,
401 402 403 404 405 406
					       object->interface->name,
					       object->id);
			break;
		}


407 408
		closure = wl_connection_demarshal(client->connection, size,
						  &client->objects, message);
409

410 411 412
		if (closure == NULL && errno == ENOMEM) {
			wl_resource_post_no_memory(resource);
			break;
413
		} else if (closure == NULL ||
414
			   wl_closure_lookup_objects(closure, &client->objects) < 0) {
415
			wl_resource_post_error(client->display_resource,
416
					       WL_DISPLAY_ERROR_INVALID_METHOD,
417
					       "invalid arguments for %s@%u.%s",
418 419 420
					       object->interface->name,
					       object->id,
					       message->name);
421
			wl_closure_destroy(closure);
422
			break;
423 424
		}

425
		log_closure(resource, closure, false);
426

427 428 429 430 431 432 433 434
		if ((resource_flags & WL_MAP_ENTRY_LEGACY) ||
		    resource->dispatcher == NULL) {
			wl_closure_invoke(closure, WL_CLOSURE_INVOKE_SERVER,
					  object, opcode, client);
		} else {
			wl_closure_dispatch(closure, resource->dispatcher,
					    object, opcode);
		}
435

436
		wl_closure_destroy(closure);
437 438 439

		if (client->error)
			break;
440 441

		len = wl_connection_pending_input(connection);
442
	}
443

444 445 446 447
	if (client->error) {
		destroy_client_with_error(client,
					  "error in client communication");
	}
448

449
	return 1;
450 451
}

452 453 454 455 456 457 458 459
/** Flush pending events to the client
 *
 * \param client The client object
 *
 * Events sent to clients are queued in a buffer and written to the
 * socket later - typically when the compositor has handled all
 * requests and goes back to block in the event loop.  This function
 * flushes all queued up events for a client immediately.
460
 *
461 462
 * \memberof wl_client
 */
463 464 465
WL_EXPORT void
wl_client_flush(struct wl_client *client)
{
466
	wl_connection_flush(client->connection);
467 468
}

469 470 471 472
/** Get the display object for the given client
 *
 * \param client The client object
 * \return The display object the client is associated with.
473
 *
474 475
 * \memberof wl_client
 */
476 477 478 479 480 481
WL_EXPORT struct wl_display *
wl_client_get_display(struct wl_client *client)
{
	return client->display;
}

482 483
static int
bind_display(struct wl_client *client, struct wl_display *display);
484

485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502
/** Create a client for the given file descriptor
 *
 * \param display The display object
 * \param fd The file descriptor for the socket to the client
 * \return The new client object or NULL on failure.
 *
 * Given a file descriptor corresponding to one end of a socket, this
 * function will create a wl_client struct and add the new client to
 * the compositors client list.  At that point, the client is
 * initialized and ready to run, as if the client had connected to the
 * servers listening socket.  When the client eventually sends
 * requests to the compositor, the wl_client argument to the request
 * handler will be the wl_client returned from this function.
 *
 * The other end of the socket can be passed to
 * wl_display_connect_to_fd() on the client side or used with the
 * WAYLAND_SOCKET environment variable on the client side.
 *
503 504 505
 * Listeners added with wl_display_add_client_created_listener() will
 * be notified by this function after the client is fully constructed.
 *
506
 * On failure this function sets errno accordingly and returns NULL.
507
 *
508 509
 * \memberof wl_display
 */
510
WL_EXPORT struct wl_client *
511 512 513
wl_client_create(struct wl_display *display, int fd)
{
	struct wl_client *client;
514
	socklen_t len;
515

516
	client = zalloc(sizeof *client);
517 518 519
	if (client == NULL)
		return NULL;

520
	wl_priv_signal_init(&client->resource_created_signal);
521 522 523 524
	client->display = display;
	client->source = wl_event_loop_add_fd(display->loop, fd,
					      WL_EVENT_READABLE,
					      wl_client_connection_data, client);
525

526 527 528
	if (!client->source)
		goto err_client;

529 530
	len = sizeof client->ucred;
	if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED,
531 532
		       &client->ucred, &len) < 0)
		goto err_source;
533

534
	client->connection = wl_connection_create(fd);
535 536
	if (client->connection == NULL)
		goto err_source;
537

538
	wl_map_init(&client->objects, WL_MAP_SERVER_SIDE);
539

540
	if (wl_map_insert_at(&client->objects, 0, 0, NULL) < 0)
541
		goto err_map;
542

543
	wl_priv_signal_init(&client->destroy_signal);
544
	if (bind_display(client, display) < 0)
545 546
		goto err_map;

547 548
	wl_list_insert(display->client_list.prev, &client->link);

549
	wl_priv_signal_emit(&display->create_client_signal, client);
550

551
	return client;
552 553 554 555 556 557 558 559 560

err_map:
	wl_map_release(&client->objects);
	wl_connection_destroy(client->connection);
err_source:
	wl_event_source_remove(client->source);
err_client:
	free(client);
	return NULL;
561 562
}

563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578
/** Return Unix credentials for the client
 *
 * \param client The display object
 * \param pid Returns the process ID
 * \param uid Returns the user ID
 * \param gid Returns the group ID
 *
 * This function returns the process ID, the user ID and the group ID
 * for the given client.  The credentials come from getsockopt() with
 * SO_PEERCRED, on the client socket fd.  All the pointers can be
 * NULL, if the caller is not interested in a particular ID.
 *
 * Be aware that for clients that a compositor forks and execs and
 * then connects using socketpair(), this function will return the
 * credentials for the compositor.  The credentials for the socketpair
 * are set at creation time in the compositor.
579
 *
580 581
 * \memberof wl_client
 */
582 583 584 585 586 587 588 589 590 591 592 593
WL_EXPORT void
wl_client_get_credentials(struct wl_client *client,
			  pid_t *pid, uid_t *uid, gid_t *gid)
{
	if (pid)
		*pid = client->ucred.pid;
	if (uid)
		*uid = client->ucred.uid;
	if (gid)
		*gid = client->ucred.gid;
}

594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628
/** Get the file descriptor for the client
 *
 * \param client The display object
 * \return The file descriptor to use for the connection
 *
 * This function returns the file descriptor for the given client.
 *
 * Be sure to use the file descriptor from the client for inspection only.
 * If the caller does anything to the file descriptor that changes its state,
 * it will likely cause problems.
 *
 * See also wl_client_get_credentials().
 * It is recommended that you evaluate whether wl_client_get_credentials()
 * can be applied to your use case instead of this function.
 *
 * If you would like to distinguish just between the client and the compositor
 * itself from the client's request, it can be done by getting the client
 * credentials and by checking the PID of the client and the compositor's PID.
 * Regarding the case in which the socketpair() is being used, you need to be
 * careful. Please note the documentation for wl_client_get_credentials().
 *
 * This function can be used for a compositor to validate a request from
 * a client if there are additional information provided from the client's
 * file descriptor. For instance, suppose you can get the security contexts
 * from the client's file descriptor. The compositor can validate the client's
 * request with the contexts and make a decision whether it permits or deny it.
 *
 * \memberof wl_client
 */
WL_EXPORT int
wl_client_get_fd(struct wl_client *client)
{
	return wl_connection_get_fd(client->connection);
}

629 630 631 632 633 634 635
/** Look up an object in the client name space
 *
 * \param client The client object
 * \param id The object id
 * \return The object or NULL if there is not object for the given ID
 *
 * This looks up an object in the client object name space by its
636 637
 * object ID.
 *
638 639
 * \memberof wl_client
 */
640 641 642 643 644 645
WL_EXPORT struct wl_resource *
wl_client_get_object(struct wl_client *client, uint32_t id)
{
	return wl_map_lookup(&client->objects, id);
}

646 647 648 649 650 651 652
WL_EXPORT void
wl_client_post_no_memory(struct wl_client *client)
{
	wl_resource_post_error(client->display_resource,
			       WL_DISPLAY_ERROR_NO_MEMORY, "no memory");
}

653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676
/** Report an internal server error
 *
 * \param client The client object
 * \param msg A printf-style format string
 * \param ... Format string arguments
 *
 * Report an unspecified internal implementation error and disconnect
 * the client.
 *
 * \memberof wl_client
 */
WL_EXPORT void
wl_client_post_implementation_error(struct wl_client *client,
				    char const *msg, ...)
{
	va_list ap;

	va_start(ap, msg);
	wl_resource_post_error_vargs(client->display_resource,
				     WL_DISPLAY_ERROR_IMPLEMENTATION,
				     msg, ap);
	va_end(ap);
}

677
WL_EXPORT void
678
wl_resource_post_no_memory(struct wl_resource *resource)
679
{
680 681
	wl_resource_post_error(resource->client->display_resource,
			       WL_DISPLAY_ERROR_NO_MEMORY, "no memory");
682 683
}

684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708
/** Detect if a wl_resource uses the deprecated public definition.
 *
 * Before Wayland 1.2.0, the definition of struct wl_resource was public.
 * It was made opaque just before 1.2.0, and later new fields were added.
 * The new fields cannot be accessed if a program is using the deprecated
 * defition, as there would not be memory allocated for them.
 *
 * The creation pattern for the deprecated definition was wl_resource_init()
 * followed by wl_client_add_resource(). wl_resource_init() was an inline
 * function and no longer exists, but binaries might still carry it.
 * wl_client_add_resource() still exists for ABI compatiblity.
 */
static bool
resource_is_deprecated(struct wl_resource *resource)
{
	struct wl_map *map = &resource->client->objects;
	int id = resource->object.id;

	/* wl_client_add_resource() marks deprecated resources with the flag. */
	if (wl_map_lookup_flags(map, id) & WL_MAP_ENTRY_LEGACY)
		return true;

	return false;
}

709
static enum wl_iterator_result
710
destroy_resource(void *element, void *data, uint32_t flags)
711 712 713
{
	struct wl_resource *resource = element;

714 715 716 717
	wl_signal_emit(&resource->deprecated_destroy_signal, resource);
	/* Don't emit the new signal for deprecated resources, as that would
	 * access memory outside the bounds of the deprecated struct */
	if (!resource_is_deprecated(resource))
718
		wl_priv_signal_final_emit(&resource->destroy_signal, resource);
719 720 721

	if (resource->destroy)
		resource->destroy(resource);
722 723 724

	if (!(flags & WL_MAP_ENTRY_LEGACY))
		free(resource);
725 726

	return WL_ITERATOR_CONTINUE;
727 728
}

729
WL_EXPORT void
730
wl_resource_destroy(struct wl_resource *resource)
731
{
732
	struct wl_client *client = resource->client;
733
	uint32_t id;
734
	uint32_t flags;
735 736

	id = resource->object.id;
737 738
	flags = wl_map_lookup_flags(&client->objects, id);
	destroy_resource(resource, NULL, flags);
739

740
	if (id < WL_SERVER_ID_START) {
741 742
		if (client->display_resource) {
			wl_resource_queue_event(client->display_resource,
743
						WL_DISPLAY_DELETE_ID, id);
744
		}
745
		wl_map_insert_at(&client->objects, 0, id, NULL);
746
	} else {
747
		wl_map_remove(&client->objects, id);
748
	}
749 750
}

751 752 753 754 755 756
WL_EXPORT uint32_t
wl_resource_get_id(struct wl_resource *resource)
{
	return resource->object.id;
}

757 758 759 760 761 762
WL_EXPORT struct wl_list *
wl_resource_get_link(struct wl_resource *resource)
{
	return &resource->link;
}

763 764 765
WL_EXPORT struct wl_resource *
wl_resource_from_link(struct wl_list *link)
{
766
	struct wl_resource *resource;
767 768 769 770 771 772 773 774 775 776 777 778

	return wl_container_of(link, resource, link);
}

WL_EXPORT struct wl_resource *
wl_resource_find_for_client(struct wl_list *list, struct wl_client *client)
{
	struct wl_resource *resource;

	if (client == NULL)
		return NULL;

779 780 781 782
	wl_list_for_each(resource, list, link) {
		if (resource->client == client)
			return resource;
	}
783

784
	return NULL;
785 786
}

787 788 789 790 791 792
WL_EXPORT struct wl_client *
wl_resource_get_client(struct wl_resource *resource)
{
	return resource->client;
}

793 794 795 796 797 798
WL_EXPORT void
wl_resource_set_user_data(struct wl_resource *resource, void *data)
{
	resource->data = data;
}

799 800 801 802 803 804
WL_EXPORT void *
wl_resource_get_user_data(struct wl_resource *resource)
{
	return resource->data;
}

805 806 807 808 809 810
WL_EXPORT int
wl_resource_get_version(struct wl_resource *resource)
{
	return resource->version;
}

811 812 813 814 815 816 817
WL_EXPORT void
wl_resource_set_destructor(struct wl_resource *resource,
			   wl_resource_destroy_func_t destroy)
{
	resource->destroy = destroy;
}

818 819 820 821 822 823 824 825 826
WL_EXPORT int
wl_resource_instance_of(struct wl_resource *resource,
			const struct wl_interface *interface,
			const void *implementation)
{
	return wl_interface_equal(resource->object.interface, interface) &&
		resource->object.implementation == implementation;
}

827 828 829 830
WL_EXPORT void
wl_resource_add_destroy_listener(struct wl_resource *resource,
				 struct wl_listener * listener)
{
831 832 833 834
	if (resource_is_deprecated(resource))
		wl_signal_add(&resource->deprecated_destroy_signal, listener);
	else
		wl_priv_signal_add(&resource->destroy_signal, listener);
835 836 837 838 839 840
}

WL_EXPORT struct wl_listener *
wl_resource_get_destroy_listener(struct wl_resource *resource,
				 wl_notify_func_t notify)
{
841 842 843
	if (resource_is_deprecated(resource))
		return wl_signal_get(&resource->deprecated_destroy_signal, notify);
	return wl_priv_signal_get(&resource->destroy_signal, notify);
844 845
}

846 847 848 849 850 851 852 853 854 855 856 857
/** Retrieve the interface name (class) of a resource object.
 *
 * \param resource The resource object
 *
 * \memberof wl_resource
 */
WL_EXPORT const char *
wl_resource_get_class(struct wl_resource *resource)
{
	return resource->object.interface->name;
}

858 859 860 861
WL_EXPORT void
wl_client_add_destroy_listener(struct wl_client *client,
			       struct wl_listener *listener)
{
862
	wl_priv_signal_add(&client->destroy_signal, listener);
863 864 865 866 867 868
}

WL_EXPORT struct wl_listener *
wl_client_get_destroy_listener(struct wl_client *client,
			       wl_notify_func_t notify)
{
869
	return wl_priv_signal_get(&client->destroy_signal, notify);
870 871
}

872
WL_EXPORT void
873 874
wl_client_destroy(struct wl_client *client)
{
875
	uint32_t serial = 0;
876

877
	wl_priv_signal_final_emit(&client->destroy_signal, client);
878

879
	wl_client_flush(client);
880
	wl_map_for_each(&client->objects, destroy_resource, &serial);
881
	wl_map_release(&client->objects);
882
	wl_event_source_remove(client->source);
883
	close(wl_connection_destroy(client->connection));
884
	wl_list_remove(&client->link);
885
	wl_list_remove(&client->resource_created_signal.listener_list);
886
	free(client);
Kristian Høgsberg's avatar
Kristian Høgsberg committed
887 888
}

889 890 891 892 893 894 895 896 897 898 899 900 901 902 903
/* Check if a global filter is registered and use it if any.
 *
 * If no wl_global filter has been registered, this funtion will
 * return true, allowing the wl_global to be visible to the wl_client
 */
static bool
wl_global_is_visible(const struct wl_client *client,
	      const struct wl_global *global)
{
	struct wl_display *display = client->display;

	return (display->global_filter == NULL ||
		display->global_filter(client, global, display->global_filter_data));
}

904
static void
905 906 907
registry_bind(struct wl_client *client,
	      struct wl_resource *resource, uint32_t name,
	      const char *interface, uint32_t version, uint32_t id)
908 909
{
	struct wl_global *global;
910
	struct wl_display *display = resource->data;
911 912

	wl_list_for_each(global, &display->global_list, link)
913
		if (global->name == name)
914 915
			break;

916
	if (&global->link == &display->global_list)
917 918
		wl_resource_post_error(resource,
				       WL_DISPLAY_ERROR_INVALID_OBJECT,
919
				       "invalid global %s (%d)", interface, name);
920 921 922 923 924
	else if (version == 0)
		wl_resource_post_error(resource,
				       WL_DISPLAY_ERROR_INVALID_OBJECT,
				       "invalid version for global %s (%d): 0 is not a valid version",
				       interface, name);
925 926 927 928 929
	else if (global->version < version)
		wl_resource_post_error(resource,
				       WL_DISPLAY_ERROR_INVALID_OBJECT,
				       "invalid version for global %s (%d): have %d, wanted %d",
				       interface, name, global->version, version);
930 931 932 933
	else if (!wl_global_is_visible(client, global))
		wl_resource_post_error(resource,
				       WL_DISPLAY_ERROR_INVALID_OBJECT,
				       "invalid global %s (%d)", interface, name);
934 935
	else
		global->bind(client, global->data, version, id);
936 937
}

938 939 940 941
static const struct wl_registry_interface registry_interface = {
	registry_bind
};

942 943
static void
display_sync(struct wl_client *client,
944
	     struct wl_resource *resource, uint32_t id)
945
{
946
	struct wl_resource *callback;
947
	uint32_t serial;
948

949
	callback = wl_resource_create(client, &wl_callback_interface, 1, id);
950 951 952 953 954
	if (callback == NULL) {
		wl_client_post_no_memory(client);
		return;
	}

955 956 957
	serial = wl_display_get_serial(client->display);
	wl_callback_send_done(callback, serial);
	wl_resource_destroy(callback);
958 959
}

960 961 962 963 964 965 966 967 968 969 970 971 972 973 974
static void
unbind_resource(struct wl_resource *resource)
{
	wl_list_remove(&resource->link);
}

static void
display_get_registry(struct wl_client *client,
		     struct wl_resource *resource, uint32_t id)
{
	struct wl_display *display = resource->data;
	struct wl_resource *registry_resource;
	struct wl_global *global;

	registry_resource =
975
		wl_resource_create(client, &wl_registry_interface, 1, id);
976 977 978 979 980
	if (registry_resource == NULL) {
		wl_client_post_no_memory(client);
		return;
	}

981 982 983
	wl_resource_set_implementation(registry_resource,
				       &registry_interface,
				       display, unbind_resource);
984 985 986 987 988

	wl_list_insert(&display->registry_resource_list,
		       &registry_resource->link);

	wl_list_for_each(global, &display->global_list, link)
989 990 991 992 993 994
		if (wl_global_is_visible(client, global))
			wl_resource_post_event(registry_resource,
					       WL_REGISTRY_GLOBAL,
					       global->name,
					       global->interface->name,
					       global->version);
995 996 997
}

static const struct wl_display_interface display_interface = {
998
	display_sync,
999
	display_get_registry
1000 1001
};

1002 1003 1004 1005 1006 1007
static void
destroy_client_display_resource(struct wl_resource *resource)
{
	resource->client->display_resource = NULL;
}

1008 1009
static int
bind_display(struct wl_client *client, struct wl_display *display)
1010 1011
{
	client->display_resource =
1012
		wl_resource_create(client, &wl_display_interface, 1, 1);
1013
	if (client->display_resource == NULL) {
1014 1015
		/* DON'T send no-memory error to client - it has no
		 * resource to which it could post the event */
1016
		return -1;
1017 1018
	}

1019 1020 1021
	wl_resource_set_implementation(client->display_resource,
				       &display_interface, display,
				       destroy_client_display_resource);
1022
	return 0;
1023
}
1024

1025 1026 1027 1028 1029 1030 1031 1032
/** Create Wayland display object.
 *
 * \return The Wayland display object. Null if failed to create
 *
 * This creates the wl_display object.
 *
 * \memberof wl_display
 */
1033
WL_EXPORT struct wl_display *
Kristian Høgsberg's avatar
Kristian Høgsberg committed
1034 1035 1036
wl_display_create(void)
{
	struct wl_display *display;
1037 1038 1039
	const char *debug;

	debug = getenv("WAYLAND_DEBUG");
1040
	if (debug && (strstr(debug, "server") || strstr(debug, "1")))
1041
		debug_server = 1;
Kristian Høgsberg's avatar
Kristian Høgsberg committed
1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052

	display = malloc(sizeof *display);
	if (display == NULL)
		return NULL;

	display->loop = wl_event_loop_create();
	if (display->loop == NULL) {
		free(display);
		return NULL;
	}

1053
	wl_list_init(&display->global_list);
1054
	wl_list_init(&display->socket_list);
1055
	wl_list_init(&display->client_list);
1056
	wl_list_init(&display->registry_resource_list);
1057
	wl_list_init(&display->protocol_loggers);
1058

1059 1060
	wl_priv_signal_init(&display->destroy_signal);
	wl_priv_signal_init(&display->create_client_signal);
1061

1062
	display->id = 1;
1063
	display->serial = 0;
1064

1065 1066 1067
	display->global_filter = NULL;
	display->global_filter_data = NULL;

1068 1069
	wl_array_init(&display->additional_shm_formats);

1070
	return display;
Kristian Høgsberg's avatar
Kristian Høgsberg committed
1071 1072
}

1073 1074 1075 1076 1077 1078 1079
static void
wl_socket_destroy(struct wl_socket *s)
{
	if (s->source)
		wl_event_source_remove(s->source);
	if (s->addr.sun_path[0])
		unlink(s->addr.sun_path);
1080
	if (s->fd >= 0)
1081 1082 1083
		close(s->fd);
	if (s->lock_addr[0])
		unlink(s->lock_addr);
1084
	if (s->fd_lock >= 0)
1085 1086 1087 1088 1089
		close(s->fd_lock);

	free(s);
}

1090 1091 1092 1093 1094
static struct wl_socket *
wl_socket_alloc(void)
{
	struct wl_socket *s;

1095
	s = zalloc(sizeof *s);
1096 1097 1098 1099 1100 1101 1102 1103 1104
	if (!s)
		return NULL;

	s->fd = -1;
	s->fd_lock = -1;

	return s;
}

1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118
/** Destroy Wayland display object.
 *
 * \param display The Wayland display object which should be destroyed.
 * \return None.
 *
 * This function emits the wl_display destroy signal, releases
 * all the sockets added to this display, free's all the globals associated
 * with this display, free's memory of additional shared memory formats and
 * destroy the display object.
 *
 * \sa wl_display_add_destroy_listener
 *
 * \memberof wl_display
 */
1119 1120 1121 1122
WL_EXPORT void
wl_display_destroy(struct wl_display *display)
{
	struct wl_socket *s, *next;
1123
	struct wl_global *global, *gnext;
1124

1125
	wl_priv_signal_final_emit(&display->destroy_signal, display);
1126

1127
	wl_list_for_each_safe(s, next, &display->socket_list, link) {
1128
		wl_socket_destroy(s);
1129
	}
1130
	wl_event_loop_destroy(display->loop);
1131

1132 1133 1134
	wl_list_for_each_safe(global, gnext, &display->global_list, link)
		free(global);

1135 1136
	wl_array_release(&display->additional_shm_formats);

1137 1138
	wl_list_remove(&display->protocol_loggers);

1139 1140 1141
	free(display);
}

1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172
/** Set a filter function for global objects
 *
 * \param display The Wayland display object.
 * \param filter  The global filter funtion.
 * \param data User data to be associated with the global filter.
 * \return None.
 *
 * Set a filter for the wl_display to advertise or hide global objects
 * to clients.
 * The set filter will be used during wl_global advertisment to
 * determine whether a global object should be advertised to a
 * given client, and during wl_global binding to determine whether
 * a given client should be allowed to bind to a global.
 *
 * Clients that try to bind to a global that was filtered out will
 * have an error raised.
 *
 * Setting the filter NULL will result in all globals being
 * advertised to all clients. The default is no filter.
 *
 * \memberof wl_display
 */
WL_EXPORT void
wl_display_set_global_filter(struct wl_display *display,
			     wl_display_global_filter_func_t filter,
			     void *data)
{
	display->global_filter = filter;
	display->global_filter_data = data;
}

1173
WL_EXPORT struct wl_global *
1174 1175 1176
wl_global_create(struct wl_display *display,
		 const struct wl_interface *interface, int version,
		 void *data, wl_global_bind_func_t bind)
1177
{
1178
	struct wl_global *global;
1179
	struct wl_resource *resource;
1180

1181 1182 1183 1184 1185 1186 1187
	if (version < 1) {
		wl_log("wl_global_create: failing to create interface "
		       "'%s' with version %d because it is less than 1\n",
			interface->name, version);
		return NULL;
	}

1188 1189 1190 1191
	if (version > interface->version) {
		wl_log("wl_global_create: implemented version for '%s' "
		       "higher than interface version (%d > %d)\n",
		       interface->name, version, interface->version);
1192 1193 1194
		return NULL;
	}

1195 1196
	global = malloc(sizeof *global);
	if (global == NULL)
1197
		return NULL;
1198

1199
	global->display = display;
1200 1201
	global->name = display->id++;
	global->interface = interface;
1202
	global->version = version;
1203
	global->data = data;
1204
	global->bind = bind;
1205
	wl_list_insert(display->global_list.prev, &global->link);
1206

1207 1208 1209
	wl_list_for_each(resource, &display->registry_resource_list, link)
		wl_resource_post_event(resource,
				       WL_REGISTRY_GLOBAL,
1210 1211
				       global->name,
				       global->interface->name,
1212
				       global->version);
1213

1214
	return global;
1215 1216
}

1217
WL_EXPORT void
1218
wl_global_destroy(struct wl_global *global)
1219
{
1220
	struct wl_display *display = global->display;
1221
	struct wl_resource *resource;
1222

1223 1224 1225
	wl_list_for_each(resource, &display->registry_resource_list, link)
		wl_resource_post_event(resource, WL_REGISTRY_GLOBAL_REMOVE,
				       global->name);
1226 1227 1228 1229
	wl_list_remove(&global->link);
	free(global);
}

1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241
WL_EXPORT const struct wl_interface *
wl_global_get_interface(const struct wl_global *global)
{
	return global->interface;
}

WL_EXPORT void *
wl_global_get_user_data(const struct wl_global *global)
{
	return global->data;
}

1242 1243 1244 1245 1246 1247
/** Get the current serial number
 *
 * \param display The display object
 *
 * This function returns the most recent serial number, but does not
 * increment it.
1248
 *
1249 1250
 * \memberof wl_display
 */
1251 1252 1253 1254 1255 1256
WL_EXPORT uint32_t
wl_display_get_serial(struct wl_display *display)
{
	return display->serial;
}

1257 1258 1259 1260 1261 1262
/** Get the next serial number
 *
 * \param display The display object
 *
 * This function increments the display serial number and returns the
 * new value.
1263
 *
1264 1265
 * \memberof wl_display
 */
1266 1267 1268 1269 1270 1271 1272 1273
WL_EXPORT uint32_t
wl_display_next_serial(struct wl_display *display)
{
	display->serial++;

	return display->serial;
}

1274
WL_EXPORT struct wl_event_loop *
1275 1276 1277 1278 1279
wl_display_get_event_loop(struct wl_display *display)
{
	return display->loop;
}

1280 1281 1282 1283 1284 1285
WL_EXPORT void
wl_display_terminate(struct wl_display *display)
{
	display->run = 0;
}

1286
WL_EXPORT void
Kristian Høgsberg's avatar
Kristian Høgsberg committed
1287 1288
wl_display_run(struct wl_display *display)
{
1289 1290
	display->run = 1;

1291 1292
	while (display->run) {
		wl_display_flush_clients(display);
1293
		wl_event_loop_dispatch(display->loop, -1);
1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312
	}
}

WL_EXPORT void
wl_display_flush_clients(struct wl_display *display)
{
	struct wl_client *client, *next;
	int ret;

	wl_list_for_each_safe(client, next, &display->client_list, link) {
		ret = wl_connection_flush(client->connection);
		if (ret < 0 && errno == EAGAIN) {
			wl_event_source_fd_update(client->source,
						  WL_EVENT_WRITABLE |
						  WL_EVENT_READABLE);
		} else if (ret < 0) {
			wl_client_destroy(client);
		}
	}
Kristian Høgsberg's avatar
Kristian Høgsberg committed
1313 1314
}

1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352
/** Destroy all clients connected to the display
 *
 * \param display The display object
 *
 * This function should be called right before wl_display_destroy() to ensure
 * all client resources are closed properly. Destroying a client from within
 * wl_display_destroy_clients() is safe, but creating one will leak resources
 * and raise a warning.
 *
 * \memberof wl_display
 */
WL_EXPORT void
wl_display_destroy_clients(struct wl_display *display)
{
	struct wl_list tmp_client_list, *pos;
	struct wl_client *client;

	/* Move the whole client list to a temporary head because some new clients
	 * might be added to the original head. */
	wl_list_init(&tmp_client_list);
	wl_list_insert_list(&tmp_client_list, &display->client_list);
	wl_list_init(&display->client_list);

	/* wl_list_for_each_safe isn't enough here: it fails if the next client is
	 * destroyed by the destroy handler of the current one. */
	while (!wl_list_empty(&tmp_client_list)) {
		pos = tmp_client_list.next;
		client = wl_container_of(pos, client, link);

		wl_client_destroy(client);
	}

	if (!wl_list_empty(&display->client_list)) {
		wl_log("wl_display_destroy_clients: cannot destroy all clients because "
			   "new ones were created by destroy callbacks\n");
	}
}

1353
static int
Kristian Høgsberg's avatar
Kristian Høgsberg committed
1354 1355 1356 1357 1358 1359 1360 1361
socket_data(int fd, uint32_t mask, void *data)
{
	struct wl_display *display = data;
	struct sockaddr_un name;
	socklen_t length;
	int client_fd;

	length = sizeof name;
1362 1363
	client_fd = wl_os_accept_cloexec(fd, (struct sockaddr *) &name,
					 &length);
Kristian Høgsberg's avatar
Kristian Høgsberg committed
1364
	if (client_fd < 0)
1365
		wl_log("failed to accept: %m\n");
1366
	else
1367 1368
		if (!wl_client_create(display, client_fd))
			close(client_fd);
1369 1370

	return 1;
Kristian Høgsberg's avatar
Kristian Høgsberg committed
1371 1372
}

1373
static int
1374
wl_socket_lock(struct wl_socket *socket)
1375 1376 1377
{
	struct stat socket_stat;

1378 1379
	snprintf(socket->lock_addr, sizeof socket->lock_addr,
		 "%s%s", socket->addr.sun_path, LOCK_SUFFIX);
1380

1381 1382
	socket->fd_lock = open(socket->lock_addr, O_CREAT | O_CLOEXEC,
			       (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP));
1383

1384
	if (socket->fd_lock < 0) {
1385
		wl_log("unable to open lockfile %s check permissions\n",
1386
			socket->lock_addr);
1387
		goto err;
1388 1389
	}

1390
	if (flock(socket->fd_lock, LOCK_EX | LOCK_NB) < 0) {
1391
		wl_log("unable to lock lockfile %s, maybe another compositor is running\n",
1392
			socket->lock_addr);
1393
		goto err_fd;
1394 1395 1396 1397
	}

	if (stat(socket->addr.sun_path, &socket_stat) < 0 ) {
		if (errno != ENOENT) {
1398
			wl_log("did not manage to stat file %s\n",
1399
				socket->