~kennylevinsen/seatd

45bab8b258b1cb0ba68eff3bfc3913e1e5d84b7d — Kenny Levinsen a month ago b1f7ec1
client: Replace pending_disable with state enum

This simplifies logic in seat handling.
3 files changed, 30 insertions(+), 22 deletions(-)

M include/client.h
M seatd/client.c
M seatd/seat.c
M include/client.h => include/client.h +9 -1
@@ 10,6 10,14 @@

struct server;

enum client_state {
	CLIENT_NEW,
	CLIENT_ACTIVE,
	CLIENT_PENDING_DISABLE,
	CLIENT_DISABLED,
	CLIENT_CLOSED
};

struct client {
	struct linked_list link; // seat::clients
	struct server *server;


@@ 22,7 30,7 @@ struct client {

	struct seat *seat;
	int session;
	bool pending_disable;
	enum client_state state;

	struct linked_list devices;
};

M seatd/client.c => seatd/client.c +1 -0
@@ 73,6 73,7 @@ struct client *client_create(struct server *server, int client_fd) {
	client->session = -1;
	client->server = server;
	client->connection.fd = client_fd;
	client->state = CLIENT_NEW;
	linked_list_init(&client->devices);
	linked_list_insert(&server->idle_clients, &client->link);
	return client;

M seatd/seat.c => seatd/seat.c +20 -21
@@ 200,15 200,12 @@ struct seat_device *seat_open_device(struct client *client, const char *path) {
	assert(strlen(path) > 0);
	struct seat *seat = client->seat;

	if (client != seat->active_client) {
		errno = EPERM;
		return NULL;
	}

	if (client->pending_disable) {
	if (client->state != CLIENT_ACTIVE) {
		log_error("client is not active");
		errno = EPERM;
		return NULL;
	}
	assert(seat->active_client == client);

	char sanitized_path[PATH_MAX];
	if (realpath(path, sanitized_path) == NULL) {


@@ 419,10 416,15 @@ done:
int seat_open_client(struct seat *seat, struct client *client) {
	assert(seat);
	assert(client);
	assert(!client->pending_disable);

	if (client->state != CLIENT_NEW && client->state != CLIENT_DISABLED) {
		log_error("client is not new or disabled");
		errno = EALREADY;
		return -1;
	}

	if (seat->active_client != NULL) {
		log_error("client already active");
		log_error("seat already has active client");
		errno = EBUSY;
		return -1;
	}


@@ 439,6 441,7 @@ int seat_open_client(struct seat *seat, struct client *client) {
		}
	}

	client->state = CLIENT_ACTIVE;
	seat->active_client = client;
	if (client_send_enable_seat(client) == -1) {
		log_error("could not send enable signal");


@@ 474,7 477,7 @@ int seat_close_client(struct client *client) {
		}
	}

	client->pending_disable = false;
	client->state = CLIENT_CLOSED;
	seat->active_client = NULL;
	log_debug("closed client");



@@ 491,17 494,12 @@ static int seat_disable_client(struct client *client) {

	struct seat *seat = client->seat;

	if (seat->active_client != client) {
	if (client->state != CLIENT_ACTIVE) {
		log_error("client not active");
		errno = EBUSY;
		return -1;
	}

	if (client->pending_disable) {
		log_error("client already pending disable");
		errno = EBUSY;
		return -1;
	}
	assert(seat->active_client = client);

	// We *deactivate* all remaining fds. These may later be reactivated.
	// The reason we cannot just close them is that certain device fds, such


@@ 515,7 513,7 @@ static int seat_disable_client(struct client *client) {
		}
	}

	client->pending_disable = true;
	client->state = CLIENT_PENDING_DISABLE;
	if (client_send_disable_seat(seat->active_client) == -1) {
		log_error("could not send disable event");
		return -1;


@@ 530,13 528,13 @@ int seat_ack_disable_client(struct client *client) {
	assert(client->seat);

	struct seat *seat = client->seat;
	if (!client->pending_disable) {
	if (client->state != CLIENT_PENDING_DISABLE) {
		log_error("client not pending disable");
		errno = EBUSY;
		return -1;
	}

	client->pending_disable = false;
	client->state = CLIENT_DISABLED;
	log_debug("disabled client");

	if (seat->active_client != client) {


@@ 558,11 556,12 @@ int seat_set_next_session(struct client *client, int session) {

	struct seat *seat = client->seat;

	if (seat->active_client != client || client->pending_disable) {
		log_error("client not active or pending disable");
	if (client->state != CLIENT_ACTIVE) {
		log_error("client is not active");
		errno = EPERM;
		return -1;
	}
	assert(seat->active_client == client);

	if (session <= 0) {
		log_errorf("invalid session value: %d", session);