mirror of
				https://gitlab.freedesktop.org/wayland/wayland.git
				synced 2025-11-03 09:01:42 -05:00 
			
		
		
		
	This adds functionality to allow system-level control over handing out file descriptors for sockets, to allow tighter security when running a Wayland compositor under a Wayland session server. Allows writing socket activated Wayland servers. Signed-off-by: Bryce Harrington <bryce@osg.samsung.com> Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Cc: Sung-Jin Park <sj76.park@samsung.com> Cc: Sangjin Lee <lsj119@samsung.com>
		
			
				
	
	
		
			486 lines
		
	
	
	
		
			13 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			486 lines
		
	
	
	
		
			13 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*
 | 
						|
 * Copyright © 2008 Kristian Høgsberg
 | 
						|
 *
 | 
						|
 * 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:
 | 
						|
 *
 | 
						|
 * 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.
 | 
						|
 */
 | 
						|
 | 
						|
#ifndef WAYLAND_SERVER_CORE_H
 | 
						|
#define WAYLAND_SERVER_CORE_H
 | 
						|
 | 
						|
#ifdef  __cplusplus
 | 
						|
extern "C" {
 | 
						|
#endif
 | 
						|
 | 
						|
#include <sys/types.h>
 | 
						|
#include <stdint.h>
 | 
						|
#include "wayland-util.h"
 | 
						|
#include "wayland-version.h"
 | 
						|
 | 
						|
enum {
 | 
						|
	WL_EVENT_READABLE = 0x01,
 | 
						|
	WL_EVENT_WRITABLE = 0x02,
 | 
						|
	WL_EVENT_HANGUP   = 0x04,
 | 
						|
	WL_EVENT_ERROR    = 0x08
 | 
						|
};
 | 
						|
 | 
						|
struct wl_event_loop;
 | 
						|
struct wl_event_source;
 | 
						|
typedef int (*wl_event_loop_fd_func_t)(int fd, uint32_t mask, void *data);
 | 
						|
typedef int (*wl_event_loop_timer_func_t)(void *data);
 | 
						|
typedef int (*wl_event_loop_signal_func_t)(int signal_number, void *data);
 | 
						|
typedef void (*wl_event_loop_idle_func_t)(void *data);
 | 
						|
 | 
						|
struct wl_event_loop *
 | 
						|
wl_event_loop_create(void);
 | 
						|
 | 
						|
void
 | 
						|
wl_event_loop_destroy(struct wl_event_loop *loop);
 | 
						|
 | 
						|
struct wl_event_source *
 | 
						|
wl_event_loop_add_fd(struct wl_event_loop *loop,
 | 
						|
		     int fd, uint32_t mask,
 | 
						|
		     wl_event_loop_fd_func_t func,
 | 
						|
		     void *data);
 | 
						|
 | 
						|
int
 | 
						|
wl_event_source_fd_update(struct wl_event_source *source, uint32_t mask);
 | 
						|
 | 
						|
struct wl_event_source *
 | 
						|
wl_event_loop_add_timer(struct wl_event_loop *loop,
 | 
						|
			wl_event_loop_timer_func_t func,
 | 
						|
			void *data);
 | 
						|
 | 
						|
struct wl_event_source *
 | 
						|
wl_event_loop_add_signal(struct wl_event_loop *loop,
 | 
						|
			int signal_number,
 | 
						|
			wl_event_loop_signal_func_t func,
 | 
						|
			void *data);
 | 
						|
 | 
						|
int
 | 
						|
wl_event_source_timer_update(struct wl_event_source *source,
 | 
						|
			     int ms_delay);
 | 
						|
 | 
						|
int
 | 
						|
wl_event_source_remove(struct wl_event_source *source);
 | 
						|
 | 
						|
void
 | 
						|
wl_event_source_check(struct wl_event_source *source);
 | 
						|
 | 
						|
 | 
						|
int
 | 
						|
wl_event_loop_dispatch(struct wl_event_loop *loop, int timeout);
 | 
						|
 | 
						|
void
 | 
						|
wl_event_loop_dispatch_idle(struct wl_event_loop *loop);
 | 
						|
 | 
						|
struct wl_event_source *
 | 
						|
wl_event_loop_add_idle(struct wl_event_loop *loop,
 | 
						|
		       wl_event_loop_idle_func_t func,
 | 
						|
		       void *data);
 | 
						|
 | 
						|
int
 | 
						|
wl_event_loop_get_fd(struct wl_event_loop *loop);
 | 
						|
 | 
						|
struct wl_client;
 | 
						|
struct wl_display;
 | 
						|
struct wl_listener;
 | 
						|
struct wl_resource;
 | 
						|
struct wl_global;
 | 
						|
typedef void (*wl_notify_func_t)(struct wl_listener *listener, void *data);
 | 
						|
 | 
						|
void
 | 
						|
wl_event_loop_add_destroy_listener(struct wl_event_loop *loop,
 | 
						|
				   struct wl_listener * listener);
 | 
						|
 | 
						|
struct wl_listener *
 | 
						|
wl_event_loop_get_destroy_listener(
 | 
						|
				   struct wl_event_loop *loop,
 | 
						|
				   wl_notify_func_t notify);
 | 
						|
 | 
						|
struct wl_display *
 | 
						|
wl_display_create(void);
 | 
						|
 | 
						|
void
 | 
						|
wl_display_destroy(struct wl_display *display);
 | 
						|
 | 
						|
struct wl_event_loop *
 | 
						|
wl_display_get_event_loop(struct wl_display *display);
 | 
						|
 | 
						|
int
 | 
						|
wl_display_add_socket(struct wl_display *display, const char *name);
 | 
						|
 | 
						|
const char *
 | 
						|
wl_display_add_socket_auto(struct wl_display *display);
 | 
						|
 | 
						|
int
 | 
						|
wl_display_add_socket_fd(struct wl_display *display, int sock_fd);
 | 
						|
 | 
						|
void
 | 
						|
wl_display_terminate(struct wl_display *display);
 | 
						|
 | 
						|
void
 | 
						|
wl_display_run(struct wl_display *display);
 | 
						|
 | 
						|
void
 | 
						|
wl_display_flush_clients(struct wl_display *display);
 | 
						|
 | 
						|
typedef void (*wl_global_bind_func_t)(struct wl_client *client, void *data,
 | 
						|
				      uint32_t version, uint32_t id);
 | 
						|
 | 
						|
uint32_t
 | 
						|
wl_display_get_serial(struct wl_display *display);
 | 
						|
 | 
						|
uint32_t
 | 
						|
wl_display_next_serial(struct wl_display *display);
 | 
						|
 | 
						|
void
 | 
						|
wl_display_add_destroy_listener(struct wl_display *display,
 | 
						|
				struct wl_listener *listener);
 | 
						|
 | 
						|
struct wl_listener *
 | 
						|
wl_display_get_destroy_listener(struct wl_display *display,
 | 
						|
				wl_notify_func_t notify);
 | 
						|
 | 
						|
struct wl_global *
 | 
						|
wl_global_create(struct wl_display *display,
 | 
						|
		 const struct wl_interface *interface,
 | 
						|
		 int version,
 | 
						|
		 void *data, wl_global_bind_func_t bind);
 | 
						|
 | 
						|
void
 | 
						|
wl_global_destroy(struct wl_global *global);
 | 
						|
 | 
						|
struct wl_client *
 | 
						|
wl_client_create(struct wl_display *display, int fd);
 | 
						|
 | 
						|
void
 | 
						|
wl_client_destroy(struct wl_client *client);
 | 
						|
 | 
						|
void
 | 
						|
wl_client_flush(struct wl_client *client);
 | 
						|
 | 
						|
void
 | 
						|
wl_client_get_credentials(struct wl_client *client,
 | 
						|
			  pid_t *pid, uid_t *uid, gid_t *gid);
 | 
						|
 | 
						|
void
 | 
						|
wl_client_add_destroy_listener(struct wl_client *client,
 | 
						|
			       struct wl_listener *listener);
 | 
						|
 | 
						|
struct wl_listener *
 | 
						|
wl_client_get_destroy_listener(struct wl_client *client,
 | 
						|
			       wl_notify_func_t notify);
 | 
						|
 | 
						|
struct wl_resource *
 | 
						|
wl_client_get_object(struct wl_client *client, uint32_t id);
 | 
						|
 | 
						|
void
 | 
						|
wl_client_post_no_memory(struct wl_client *client);
 | 
						|
 | 
						|
/** \class wl_listener
 | 
						|
 *
 | 
						|
 * \brief A single listener for Wayland signals
 | 
						|
 *
 | 
						|
 * wl_listener provides the means to listen for wl_signal notifications. Many
 | 
						|
 * Wayland objects use wl_listener for notification of significant events like
 | 
						|
 * object destruction.
 | 
						|
 *
 | 
						|
 * Clients should create wl_listener objects manually and can register them as
 | 
						|
 * listeners to signals using #wl_signal_add, assuming the signal is
 | 
						|
 * directly accessible. For opaque structs like wl_event_loop, adding a
 | 
						|
 * listener should be done through provided accessor methods. A listener can
 | 
						|
 * only listen to one signal at a time.
 | 
						|
 *
 | 
						|
 * \code
 | 
						|
 * struct wl_listener your_listener;
 | 
						|
 *
 | 
						|
 * your_listener.notify = your_callback_method;
 | 
						|
 *
 | 
						|
 * // Direct access
 | 
						|
 * wl_signal_add(&some_object->destroy_signal, &your_listener);
 | 
						|
 *
 | 
						|
 * // Accessor access
 | 
						|
 * wl_event_loop *loop = ...;
 | 
						|
 * wl_event_loop_add_destroy_listener(loop, &your_listener);
 | 
						|
 * \endcode
 | 
						|
 *
 | 
						|
 * If the listener is part of a larger struct, #wl_container_of can be used
 | 
						|
 * to retrieve a pointer to it:
 | 
						|
 *
 | 
						|
 * \code
 | 
						|
 * void your_listener(struct wl_listener *listener, void *data)
 | 
						|
 * {
 | 
						|
 * 	struct your_data *data;
 | 
						|
 *
 | 
						|
 * 	your_data = wl_container_of(listener, data, your_member_name);
 | 
						|
 * }
 | 
						|
 * \endcode
 | 
						|
 *
 | 
						|
 * If you need to remove a listener from a signal, use wl_list_remove().
 | 
						|
 *
 | 
						|
 * \code
 | 
						|
 * wl_list_remove(&your_listener.link);
 | 
						|
 * \endcode
 | 
						|
 *
 | 
						|
 * \sa wl_signal
 | 
						|
 */
 | 
						|
struct wl_listener {
 | 
						|
	struct wl_list link;
 | 
						|
	wl_notify_func_t notify;
 | 
						|
};
 | 
						|
 | 
						|
/** \class wl_signal
 | 
						|
 *
 | 
						|
 * \brief A source of a type of observable event
 | 
						|
 *
 | 
						|
 * Signals are recognized points where significant events can be observed.
 | 
						|
 * Compositors as well as the server can provide signals. Observers are
 | 
						|
 * wl_listener's that are added through #wl_signal_add. Signals are emitted
 | 
						|
 * using #wl_signal_emit, which will invoke all listeners until that
 | 
						|
 * listener is removed by wl_list_remove() (or whenever the signal is
 | 
						|
 * destroyed).
 | 
						|
 *
 | 
						|
 * \sa wl_listener for more information on using wl_signal
 | 
						|
 */
 | 
						|
struct wl_signal {
 | 
						|
	struct wl_list listener_list;
 | 
						|
};
 | 
						|
 | 
						|
/** Initialize a new \ref wl_signal for use.
 | 
						|
 *
 | 
						|
 * \param signal The signal that will be initialized
 | 
						|
 *
 | 
						|
 * \memberof wl_signal
 | 
						|
 */
 | 
						|
static inline void
 | 
						|
wl_signal_init(struct wl_signal *signal)
 | 
						|
{
 | 
						|
	wl_list_init(&signal->listener_list);
 | 
						|
}
 | 
						|
 | 
						|
/** Add the specified listener to this signal.
 | 
						|
 *
 | 
						|
 * \param signal The signal that will emit events to the listener
 | 
						|
 * \param listener The listener to add
 | 
						|
 *
 | 
						|
 * \memberof wl_signal
 | 
						|
 */
 | 
						|
static inline void
 | 
						|
wl_signal_add(struct wl_signal *signal, struct wl_listener *listener)
 | 
						|
{
 | 
						|
	wl_list_insert(signal->listener_list.prev, &listener->link);
 | 
						|
}
 | 
						|
 | 
						|
/** Gets the listener struct for the specified callback.
 | 
						|
 *
 | 
						|
 * \param signal The signal that contains the specified listener
 | 
						|
 * \param notify The listener that is the target of this search
 | 
						|
 * \return the list item that corresponds to the specified listener, or NULL
 | 
						|
 * if none was found
 | 
						|
 *
 | 
						|
 * \memberof wl_signal
 | 
						|
 */
 | 
						|
static inline struct wl_listener *
 | 
						|
wl_signal_get(struct wl_signal *signal, wl_notify_func_t notify)
 | 
						|
{
 | 
						|
	struct wl_listener *l;
 | 
						|
 | 
						|
	wl_list_for_each(l, &signal->listener_list, link)
 | 
						|
		if (l->notify == notify)
 | 
						|
			return l;
 | 
						|
 | 
						|
	return NULL;
 | 
						|
}
 | 
						|
 | 
						|
/** Emits this signal, notifying all registered listeners.
 | 
						|
 *
 | 
						|
 * \param signal The signal object that will emit the signal
 | 
						|
 * \param data The data that will be emitted with the signal
 | 
						|
 *
 | 
						|
 * \memberof wl_signal
 | 
						|
 */
 | 
						|
static inline void
 | 
						|
wl_signal_emit(struct wl_signal *signal, void *data)
 | 
						|
{
 | 
						|
	struct wl_listener *l, *next;
 | 
						|
 | 
						|
	wl_list_for_each_safe(l, next, &signal->listener_list, link)
 | 
						|
		l->notify(l, data);
 | 
						|
}
 | 
						|
 | 
						|
typedef void (*wl_resource_destroy_func_t)(struct wl_resource *resource);
 | 
						|
 | 
						|
/*
 | 
						|
 * Post an event to the client's object referred to by 'resource'.
 | 
						|
 * 'opcode' is the event number generated from the protocol XML
 | 
						|
 * description (the event name). The variable arguments are the event
 | 
						|
 * parameters, in the order they appear in the protocol XML specification.
 | 
						|
 *
 | 
						|
 * The variable arguments' types are:
 | 
						|
 * - type=uint:	uint32_t
 | 
						|
 * - type=int:		int32_t
 | 
						|
 * - type=fixed:	wl_fixed_t
 | 
						|
 * - type=string:	(const char *) to a nil-terminated string
 | 
						|
 * - type=array:	(struct wl_array *)
 | 
						|
 * - type=fd:		int, that is an open file descriptor
 | 
						|
 * - type=new_id:	(struct wl_object *) or (struct wl_resource *)
 | 
						|
 * - type=object:	(struct wl_object *) or (struct wl_resource *)
 | 
						|
 */
 | 
						|
void
 | 
						|
wl_resource_post_event(struct wl_resource *resource,
 | 
						|
		       uint32_t opcode, ...);
 | 
						|
 | 
						|
void
 | 
						|
wl_resource_post_event_array(struct wl_resource *resource,
 | 
						|
			     uint32_t opcode, union wl_argument *args);
 | 
						|
 | 
						|
void
 | 
						|
wl_resource_queue_event(struct wl_resource *resource,
 | 
						|
			uint32_t opcode, ...);
 | 
						|
 | 
						|
void wl_resource_queue_event_array(struct wl_resource *resource,
 | 
						|
				   uint32_t opcode, union wl_argument *args);
 | 
						|
 | 
						|
/* msg is a printf format string, variable args are its args. */
 | 
						|
void
 | 
						|
wl_resource_post_error(struct wl_resource *resource,
 | 
						|
		       uint32_t code, const char *msg, ...)
 | 
						|
	__attribute__ ((format (printf, 3, 4)));
 | 
						|
 | 
						|
void wl_resource_post_no_memory(struct wl_resource *resource);
 | 
						|
 | 
						|
struct wl_display *
 | 
						|
wl_client_get_display(struct wl_client *client);
 | 
						|
 | 
						|
struct wl_resource *
 | 
						|
wl_resource_create(struct wl_client *client,
 | 
						|
		   const struct wl_interface *interface,
 | 
						|
		   int version, uint32_t id);
 | 
						|
void
 | 
						|
wl_resource_set_implementation(struct wl_resource *resource,
 | 
						|
			       const void *implementation,
 | 
						|
			       void *data,
 | 
						|
			       wl_resource_destroy_func_t destroy);
 | 
						|
void
 | 
						|
wl_resource_set_dispatcher(struct wl_resource *resource,
 | 
						|
			   wl_dispatcher_func_t dispatcher,
 | 
						|
			   const void *implementation,
 | 
						|
			   void *data,
 | 
						|
			   wl_resource_destroy_func_t destroy);
 | 
						|
 | 
						|
void
 | 
						|
wl_resource_destroy(struct wl_resource *resource);
 | 
						|
uint32_t
 | 
						|
wl_resource_get_id(struct wl_resource *resource);
 | 
						|
struct wl_list *
 | 
						|
wl_resource_get_link(struct wl_resource *resource);
 | 
						|
struct wl_resource *
 | 
						|
wl_resource_from_link(struct wl_list *resource);
 | 
						|
struct wl_resource *
 | 
						|
wl_resource_find_for_client(struct wl_list *list, struct wl_client *client);
 | 
						|
struct wl_client *
 | 
						|
wl_resource_get_client(struct wl_resource *resource);
 | 
						|
void
 | 
						|
wl_resource_set_user_data(struct wl_resource *resource, void *data);
 | 
						|
void *
 | 
						|
wl_resource_get_user_data(struct wl_resource *resource);
 | 
						|
int
 | 
						|
wl_resource_get_version(struct wl_resource *resource);
 | 
						|
void
 | 
						|
wl_resource_set_destructor(struct wl_resource *resource,
 | 
						|
			   wl_resource_destroy_func_t destroy);
 | 
						|
int
 | 
						|
wl_resource_instance_of(struct wl_resource *resource,
 | 
						|
			const struct wl_interface *interface,
 | 
						|
			const void *implementation);
 | 
						|
 | 
						|
void
 | 
						|
wl_resource_add_destroy_listener(struct wl_resource *resource,
 | 
						|
				 struct wl_listener * listener);
 | 
						|
struct wl_listener *
 | 
						|
wl_resource_get_destroy_listener(struct wl_resource *resource,
 | 
						|
				 wl_notify_func_t notify);
 | 
						|
 | 
						|
#define wl_resource_for_each(resource, list)					\
 | 
						|
	for (resource = 0, resource = wl_resource_from_link((list)->next);	\
 | 
						|
	     wl_resource_get_link(resource) != (list);				\
 | 
						|
	     resource = wl_resource_from_link(wl_resource_get_link(resource)->next))
 | 
						|
 | 
						|
#define wl_resource_for_each_safe(resource, tmp, list)					\
 | 
						|
	for (resource = 0, tmp = 0,							\
 | 
						|
	     resource = wl_resource_from_link((list)->next),	\
 | 
						|
	     tmp = wl_resource_from_link((list)->next->next);	\
 | 
						|
	     wl_resource_get_link(resource) != (list);				\
 | 
						|
	     resource = tmp,							\
 | 
						|
	     tmp = wl_resource_from_link(wl_resource_get_link(resource)->next))
 | 
						|
 | 
						|
struct wl_shm_pool;
 | 
						|
struct wl_shm_buffer;
 | 
						|
 | 
						|
void
 | 
						|
wl_shm_buffer_begin_access(struct wl_shm_buffer *buffer);
 | 
						|
 | 
						|
void
 | 
						|
wl_shm_buffer_end_access(struct wl_shm_buffer *buffer);
 | 
						|
 | 
						|
struct wl_shm_buffer *
 | 
						|
wl_shm_buffer_get(struct wl_resource *resource);
 | 
						|
 | 
						|
void *
 | 
						|
wl_shm_buffer_get_data(struct wl_shm_buffer *buffer);
 | 
						|
 | 
						|
int32_t
 | 
						|
wl_shm_buffer_get_stride(struct wl_shm_buffer *buffer);
 | 
						|
 | 
						|
uint32_t
 | 
						|
wl_shm_buffer_get_format(struct wl_shm_buffer *buffer);
 | 
						|
 | 
						|
int32_t
 | 
						|
wl_shm_buffer_get_width(struct wl_shm_buffer *buffer);
 | 
						|
 | 
						|
int32_t
 | 
						|
wl_shm_buffer_get_height(struct wl_shm_buffer *buffer);
 | 
						|
 | 
						|
struct wl_shm_pool *
 | 
						|
wl_shm_buffer_ref_pool(struct wl_shm_buffer *buffer);
 | 
						|
 | 
						|
void
 | 
						|
wl_shm_pool_unref(struct wl_shm_pool *pool);
 | 
						|
 | 
						|
int
 | 
						|
wl_display_init_shm(struct wl_display *display);
 | 
						|
 | 
						|
uint32_t *
 | 
						|
wl_display_add_shm_format(struct wl_display *display, uint32_t format);
 | 
						|
 | 
						|
struct wl_shm_buffer *
 | 
						|
wl_shm_buffer_create(struct wl_client *client,
 | 
						|
		     uint32_t id, int32_t width, int32_t height,
 | 
						|
		     int32_t stride, uint32_t format) WL_DEPRECATED;
 | 
						|
 | 
						|
void wl_log_set_handler_server(wl_log_func_t handler);
 | 
						|
 | 
						|
#ifdef  __cplusplus
 | 
						|
}
 | 
						|
#endif
 | 
						|
 | 
						|
#endif
 |