Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package seatd for openSUSE:Factory checked in at 2026-03-03 15:31:03 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/seatd (Old) and /work/SRC/openSUSE:Factory/.seatd.new.29461 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "seatd" Tue Mar 3 15:31:03 2026 rev:13 rq:1335908 version:0.9.3 Changes: -------- --- /work/SRC/openSUSE:Factory/seatd/seatd.changes 2026-01-20 21:03:53.726443943 +0100 +++ /work/SRC/openSUSE:Factory/.seatd.new.29461/seatd.changes 2026-03-03 15:31:51.771349747 +0100 @@ -1,0 +2,24 @@ +Mon Mar 02 20:04:24 UTC 2026 - Michael Vetter <[email protected]> + +- Update to version 0.9.3: + * Bump version to 0.9.3 + * seatd: Fix some typos + * seatd: Improve error handling for failed seat open + * seatd: Reuse session numbers for non-VT-bound + * seatd: Return the correct device on duplicate open + * libseat: Remove bogus NULL check + * libseat/logind: Handle strdup allocation errors + * libseat/logind: Avoid shadowing ret + * libseat/logind: Do not record PauseDeviceComplete reply + * seatd: Check the right variable for accept failure + * libseat/seatd: Retain errno in set_error for convenience + * libseat/seatd: Ensure errno is not clobbered + * libseat/seatd: Do not attempt destroy on alloc error + * logind: Minor error simplification + * logind: Ensure errno is set from sd_bus error + * seatd: Explicitly set ENOMEM in seat_open_device + * seatd: Remove silly goto error handling + * seatd: Ensure seat_close_device cannot clobber errno + * seatd: Clarify that seat_close_device cannot fail + +------------------------------------------------------------------- Old: ---- seatd-0.9.2.obscpio New: ---- seatd-0.9.3.obscpio ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ seatd.spec ++++++ --- /var/tmp/diff_new_pack.b2pkQo/_old 2026-03-03 15:31:52.459378120 +0100 +++ /var/tmp/diff_new_pack.b2pkQo/_new 2026-03-03 15:31:52.467378450 +0100 @@ -17,7 +17,7 @@ Name: seatd -Version: 0.9.2 +Version: 0.9.3 Release: 0 Summary: Seat management daemon License: MIT ++++++ _service ++++++ --- /var/tmp/diff_new_pack.b2pkQo/_old 2026-03-03 15:31:52.503379935 +0100 +++ /var/tmp/diff_new_pack.b2pkQo/_new 2026-03-03 15:31:52.507380100 +0100 @@ -3,10 +3,11 @@ <service name="obs_scm" mode="disabled"> <param name="url">https://git.sr.ht/~kennylevinsen/seatd</param> <param name="scm">git</param> - <param name="revision">0.9.2</param> + <param name="revision">0.9.3</param> <param name="versionformat">@PARENT_TAG@+@TAG_OFFSET@</param> <param name="versionrewrite-pattern">(.*)\+0</param> <param name="versionrewrite-replacement">\1</param> + <param name="changesgenerate">enable</param> </service> <service mode="disabled" name="set_version"/> <service name="tar" mode="buildtime"/> ++++++ seatd-0.9.2.obscpio -> seatd-0.9.3.obscpio ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/seatd-0.9.2/include/seat.h new/seatd-0.9.3/include/seat.h --- old/seatd-0.9.2/include/seat.h 2026-01-05 10:44:28.000000000 +0100 +++ new/seatd-0.9.3/include/seat.h 2026-02-28 22:04:33.000000000 +0100 @@ -36,7 +36,6 @@ bool vt_bound; int cur_vt; - int session_cnt; }; struct seat *seat_create(const char *name, bool vt_bound); @@ -48,7 +47,7 @@ int seat_ack_disable_client(struct client *client); struct seat_device *seat_open_device(struct client *client, const char *path); -int seat_close_device(struct client *client, struct seat_device *seat_device); +void seat_close_device(struct client *client, struct seat_device *seat_device); struct seat_device *seat_find_device(struct client *client, int device_id); int seat_set_next_session(struct client *client, int session); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/seatd-0.9.2/libseat/backend/logind.c new/seatd-0.9.3/libseat/backend/logind.c --- old/seatd-0.9.2/libseat/backend/logind.c 2026-01-05 10:44:28.000000000 +0100 +++ new/seatd-0.9.3/libseat/backend/logind.c 2026-02-28 22:04:33.000000000 +0100 @@ -77,10 +77,7 @@ int ret = sd_bus_call_method_async(backend->bus, NULL, "org.freedesktop.login1", "/org/freedesktop/login1", "org.freedesktop.DBus.Peer", "Ping", ping_handler, backend, ""); - if (ret < 0) { - return ret; - } - return 0; + return ret < 0 ? ret : 0; } static void check_pending_events(struct backend_logind *backend) { @@ -122,7 +119,6 @@ major(st.st_rdev), minor(st.st_rdev)); if (ret < 0) { log_errorf("Could not take device: %s", error.message); - tmpfd = -1; goto out; } @@ -130,7 +126,6 @@ ret = sd_bus_message_read(msg, "hb", &tmpfd, &paused); if (ret < 0) { log_errorf("Could not parse D-Bus response: %s", strerror(-ret)); - tmpfd = -1; goto out; } @@ -138,8 +133,8 @@ // so we just clone it. tmpfd = fcntl(tmpfd, F_DUPFD_CLOEXEC, 0); if (tmpfd < 0) { - log_errorf("Could not duplicate fd: %s", strerror(errno)); - tmpfd = -1; + ret = -errno; + log_errorf("Could not duplicate fd: %s", strerror(-ret)); goto out; } @@ -149,6 +144,10 @@ sd_bus_error_free(&error); sd_bus_message_unref(msg); check_pending_events(session); + if (ret < 0) { + errno = -ret; + return -1; + } return tmpfd; } @@ -179,7 +178,11 @@ sd_bus_error_free(&error); sd_bus_message_unref(msg); check_pending_events(session); - return ret < 0 ? -1 : 0; + if (ret < 0) { + errno = -ret; + return -1; + } + return 0; } static int switch_session(struct libseat *base, int s) { @@ -202,7 +205,11 @@ sd_bus_error_free(&error); sd_bus_message_unref(msg); check_pending_events(session); - return ret < 0 ? -1 : 0; + if (ret < 0) { + errno = -ret; + return -1; + } + return 0; } static int disable_seat(struct libseat *base) { @@ -388,7 +395,7 @@ set_active(session, false); ret = sd_bus_call_method(session->bus, "org.freedesktop.login1", session->path, "org.freedesktop.login1.Session", "PauseDeviceComplete", - ret_error, &msg, "uu", major, minor); + ret_error, NULL, "uu", major, minor); if (ret < 0) { log_errorf("Could not send PauseDeviceComplete signal: %s", ret_error->message); @@ -428,7 +435,6 @@ goto error; } if (strcmp(s, "Active") == 0) { - int ret; const char *field = "Active"; ret = sd_bus_message_enter_container(msg, 'v', "b"); if (ret < 0) { @@ -555,6 +561,9 @@ } free(*session_path); *session_path = strdup(path); + if (*session_path == NULL) { + ret = -ENOMEM; + } out: sd_bus_error_free(&error); @@ -584,6 +593,9 @@ } free(*seat_path); *seat_path = strdup(path); + if (*seat_path == NULL) { + ret = -ENOMEM; + } out: sd_bus_error_free(&error); @@ -605,6 +617,10 @@ goto error; } *session_id = strdup(xdg_session_id); + if (*session_id == NULL) { + ret = -ENOMEM; + goto error; + } goto success; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/seatd-0.9.2/libseat/backend/seatd.c new/seatd-0.9.3/libseat/backend/seatd.c --- old/seatd-0.9.2/libseat/backend/seatd.c 2026-01-05 10:44:28.000000000 +0100 +++ new/seatd-0.9.3/libseat/backend/seatd.c 2026-02-28 22:04:33.000000000 +0100 @@ -108,8 +108,10 @@ return; } + int stored_errno = errno; backend->error = true; cleanup(backend); + errno = stored_errno; } static inline int conn_put(struct backend_seatd *backend, const void *data, const size_t data_len) { @@ -376,7 +378,8 @@ struct backend_seatd *backend = calloc(1, sizeof(struct backend_seatd)); if (backend == NULL) { log_errorf("Allocation failed: %s", strerror(errno)); - goto alloc_error; + close(fd); + return NULL; } backend->seat_listener = listener; @@ -385,31 +388,35 @@ backend->base.impl = &seatd_impl; linked_list_init(&backend->pending_events); + int res = 0; struct proto_header header = { .opcode = CLIENT_OPEN_SEAT, .size = 0, }; if (conn_put(backend, &header, sizeof header) == -1 || read_until_response(backend) == -1) { + res = -errno; goto backend_error; } struct proto_server_seat_opened rmsg; size_t size = read_header(backend, SERVER_SEAT_OPENED, sizeof rmsg, true); if (size == SIZE_MAX || conn_get(backend, &rmsg, sizeof rmsg) == -1) { + res = -errno; goto backend_error; } if (rmsg.seat_name_len != size - sizeof rmsg) { log_errorf("Invalid message: seat_name_len does not match remaining message size (%d != %zd)", rmsg.seat_name_len, size); - errno = EBADMSG; + res = -EBADMSG; goto backend_error; } if (rmsg.seat_name_len > MAX_SEAT_LEN) { log_errorf("Invalid message: seat_name too long (%d)", rmsg.seat_name_len); - errno = EBADMSG; + res = -EBADMSG; goto backend_error; } if (conn_get(backend, backend->seat_name, rmsg.seat_name_len) == -1) { + res = -errno; goto backend_error; } // handle old seatd gracefully (seat_name without null byte) @@ -421,7 +428,7 @@ if (rmsg.seat_name_len == 0 || strnlen(backend->seat_name, rmsg.seat_name_len) != (uint16_t)(rmsg.seat_name_len - 1)) { log_error("Invalid message: seat_name not null terminated"); - errno = EBADMSG; + res = -EBADMSG; goto backend_error; } @@ -430,8 +437,7 @@ backend_error: destroy(backend); -alloc_error: - close(fd); + errno = -res; return NULL; } @@ -448,7 +454,7 @@ int res = 0; struct backend_seatd *backend = backend_seatd_from_libseat_backend(base); if (backend->error) { - res = -1; + res = -ENOTCONN; goto done; } @@ -457,17 +463,21 @@ .size = 0, }; if (conn_put(backend, &header, sizeof header) == -1 || read_until_response(backend) == -1) { - res = -1; + res = -errno; } if (read_header(backend, SERVER_SEAT_CLOSED, 0, false) == SIZE_MAX) { - res = -1; + res = -errno; } done: execute_events(backend); destroy(backend); - return res; + if (res < 0) { + errno = -res; + return -1; + } + return 0; } static const char *seat_name(struct libseat *base) { @@ -537,12 +547,17 @@ struct proto_server_device_opened rmsg; if (read_header(backend, SERVER_DEVICE_OPENED, sizeof rmsg, false) == SIZE_MAX || conn_get(backend, &rmsg, sizeof rmsg) == -1 || conn_get_fd(backend, fd)) { - res = -1; + res = -errno; + assert(res < 0); } else { res = rmsg.device_id; } check_pending_events(backend); + if (res < 0) { + errno = -res; + return -1; + } return res; } @@ -571,11 +586,15 @@ int res = 0; if (read_header(backend, SERVER_DEVICE_CLOSED, 0, false) == SIZE_MAX) { - res = -1; + res = -errno; } check_pending_events(backend); - return res; + if (res < 0) { + errno = -res; + return -1; + } + return 0; } static int switch_session(struct libseat *base, int session) { @@ -603,11 +622,15 @@ int res = 0; if (read_header(backend, SERVER_SESSION_SWITCHED, 0, false) == SIZE_MAX) { - res = -1; + res = -errno; } check_pending_events(backend); - return res; + if (res < 0) { + errno = -res; + return -1; + } + return 0; } static int disable_seat(struct libseat *base) { @@ -626,11 +649,15 @@ int res = 0; if (read_header(backend, SERVER_SEAT_DISABLED, 0, false) == SIZE_MAX) { - res = -1; + res = -errno; } check_pending_events(backend); - return res; + if (res < 0) { + errno = -res; + return -1; + } + return 0; } const struct seat_impl seatd_impl = { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/seatd-0.9.2/libseat/libseat.c new/seatd-0.9.3/libseat/libseat.c --- old/seatd-0.9.2/libseat/libseat.c 2026-01-05 10:44:28.000000000 +0100 +++ new/seatd-0.9.3/libseat/libseat.c 2026-02-28 22:04:33.000000000 +0100 @@ -48,7 +48,7 @@ while (iter->backend != NULL && strcmp(backend_type, iter->name) != 0) { iter++; } - if (iter == NULL || iter->backend == NULL) { + if (iter->backend == NULL) { log_errorf("No backend matched name '%s'", backend_type); errno = EINVAL; return NULL; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/seatd-0.9.2/meson.build new/seatd-0.9.3/meson.build --- old/seatd-0.9.2/meson.build 2026-01-05 10:44:28.000000000 +0100 +++ new/seatd-0.9.3/meson.build 2026-02-28 22:04:33.000000000 +0100 @@ -1,7 +1,7 @@ project( 'seatd', 'c', - version: '0.9.2', + version: '0.9.3', license: 'MIT', meson_version: '>=0.60.0', default_options: [ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/seatd-0.9.2/seatd/client.c new/seatd-0.9.3/seatd/client.c --- old/seatd-0.9.2/seatd/client.c 2026-01-05 10:44:28.000000000 +0100 +++ new/seatd-0.9.3/seatd/client.c 2026-02-28 22:04:33.000000000 +0100 @@ -227,14 +227,14 @@ struct seat_device *device = seat_open_device(client, path); if (device == NULL) { log_errorf("Could not open device: %s", strerror(errno)); - goto fail; + return client_send_error(client, errno); } int dupfd = dup(device->fd); if (dupfd == -1) { log_errorf("Could not dup fd: %s", strerror(errno)); seat_close_device(client, device); - goto fail; + return client_send_error(client, errno); } if (connection_put_fd(&client->connection, dupfd) == -1) { @@ -257,9 +257,6 @@ } return 0; - -fail: - return client_send_error(client, errno); } static int handle_close_device(struct client *client, int device_id) { @@ -271,14 +268,10 @@ struct seat_device *device = seat_find_device(client, device_id); if (device == NULL) { log_error("No such device"); - errno = EBADF; - goto fail; + return client_send_error(client, EBADF); } - if (seat_close_device(client, device) == -1) { - log_errorf("Could not close device: %s", strerror(errno)); - goto fail; - } + seat_close_device(client, device); struct proto_header header = { .opcode = SERVER_DEVICE_CLOSED, @@ -291,9 +284,6 @@ } return 0; - -fail: - return client_send_error(client, errno); } static int handle_switch_session(struct client *client, int session) { @@ -303,7 +293,7 @@ } if (seat_set_next_session(client, session) == -1) { - goto fail; + return client_send_error(client, errno); } struct proto_header header = { @@ -317,9 +307,6 @@ } return 0; - -fail: - return client_send_error(client, errno); } static int handle_disable_seat(struct client *client) { @@ -329,7 +316,7 @@ } if (seat_ack_disable_client(client) == -1) { - goto fail; + return client_send_error(client, errno); } struct proto_header header = { @@ -343,9 +330,6 @@ } return 0; - -fail: - return client_send_error(client, errno); } static int handle_ping(struct client *client) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/seatd-0.9.2/seatd/seat.c new/seatd-0.9.3/seatd/seat.c --- old/seatd-0.9.2/seatd/seat.c 2026-01-05 10:44:28.000000000 +0100 +++ new/seatd-0.9.3/seatd/seat.c 2026-02-28 22:04:33.000000000 +0100 @@ -141,7 +141,7 @@ * 3. Otherwise, the first client on the seat's list of clients, if any. * * Be careful not to call seat_activate immediately after closing a client, as - * this can lead to it immediatley re-opening. The client should be removed as + * this can lead to it immediately re-opening. The client should be removed as * a candidate before seat_activate is called. */ static int seat_activate(struct seat *seat) { @@ -182,7 +182,7 @@ } /* - * seat_add_client assigns a sesssion ID to the client and adds it to the seat, + * seat_add_client assigns a session ID to the client and adds it to the seat, * if allowed. The client does not open the seat, remaining closed until * `seat_open_client` is called. * @@ -229,7 +229,16 @@ } client->session = seat->cur_vt; } else { - client->session = seat->session_cnt++; + int next_session = 1; + for (struct linked_list *elem = seat->clients.next; elem != &seat->clients; + elem = elem->next) { + struct client *c = (struct client *)elem; + if (c->session == next_session) { + next_session++; + elem = &seat->clients; + } + } + client->session = next_session; } client->seat = seat; @@ -259,9 +268,7 @@ while (!linked_list_empty(&client->devices)) { struct seat_device *device = (struct seat_device *)client->devices.next; - if (seat_close_device(client, device) == -1) { - log_errorf("Could not close %s: %s", device->path, strerror(errno)); - } + seat_close_device(client, device); } bool was_current = seat->active_client == client; @@ -324,7 +331,7 @@ log_debugf("Opening device %s for client %d on %s", path, client->session, seat->seat_name); if (client->state != CLIENT_ACTIVE) { - log_error("Could open device: client is not active"); + log_error("Could not open device: client is not active"); errno = EPERM; return NULL; } @@ -353,14 +360,13 @@ int device_id = 1; size_t device_count = 0; - struct seat_device *device = NULL; for (struct linked_list *elem = client->devices.next; elem != &client->devices; elem = elem->next) { struct seat_device *old_device = (struct seat_device *)elem; if (strcmp(old_device->path, sanitized_path) == 0) { old_device->ref_cnt++; - return device; + return old_device; } if (old_device->device_id >= device_id) { @@ -401,7 +407,7 @@ abort(); } - device = calloc(1, sizeof(struct seat_device)); + struct seat_device *device = calloc(1, sizeof(struct seat_device)); if (device == NULL) { log_errorf("Allocation failed: %s", strerror(errno)); close(fd); @@ -414,6 +420,7 @@ log_errorf("Allocation failed: %s", strerror(errno)); close(fd); free(device); + errno = ENOMEM; return NULL; } @@ -470,15 +477,20 @@ * seat_close_device reduces the reference count for the device. If it reaches * zero, the device is deactivated, closed and removed. */ -int seat_close_device(struct client *client, struct seat_device *seat_device) { +void seat_close_device(struct client *client, struct seat_device *seat_device) { log_debugf("Closing device %s for client %d on %s", seat_device->path, client->session, client->seat->seat_name); seat_device->ref_cnt--; if (seat_device->ref_cnt > 0) { - return 0; + return; } + // The caller might be closing devices in error handling. As we cannot + // fail anyway, let's ensure we do not clobber errno for caller + // convenience. + int stored_errno = errno; + linked_list_remove(&seat_device->link); if (seat_device->fd != -1) { seat_deactivate_device(seat_device); @@ -486,7 +498,8 @@ } free(seat_device->path); free(seat_device); - return 0; + + errno = stored_errno; } /* @@ -542,7 +555,7 @@ if (seat->vt_bound && vt_open(client->session) == -1) { log_error("Could not open VT for client"); - goto error; + return -1; } for (struct linked_list *elem = client->devices.next; elem != &client->devices; @@ -553,21 +566,23 @@ } } - client->state = CLIENT_ACTIVE; - seat->active_client = client; if (client_send_enable_seat(client) == -1) { log_error("Could not send enable signal to client"); - goto error; + for (struct linked_list *elem = client->devices.next; elem != &client->devices; + elem = elem->next) { + struct seat_device *device = (struct seat_device *)elem; + seat_deactivate_device(device); + } + if (seat->vt_bound) { + vt_close(client->session); + } + return -1; } + client->state = CLIENT_ACTIVE; + seat->active_client = client; log_infof("Opened client %d on %s", client->session, seat->seat_name); return 0; - -error: - if (seat->vt_bound) { - vt_close(seat->cur_vt); - } - return -1; } /* @@ -639,7 +654,7 @@ /* * seat_set_next_session queues a new client to be opened based on its session - * ID. It can only b eperformed by an active client, and only if a switch has + * ID. It can only be performed by an active client, and only if a switch has * not already been requested. If the seat is VT-bound, a VT switch is * performed and the VT ack/release mechanism takes care of the rest to avoid * conflicts between the two mechanisms. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/seatd-0.9.2/seatd/server.c new/seatd-0.9.3/seatd/server.c --- old/seatd-0.9.2/seatd/server.c 2026-01-05 10:44:28.000000000 +0100 +++ new/seatd-0.9.3/seatd/server.c 2026-02-28 22:04:33.000000000 +0100 @@ -158,7 +158,7 @@ if (mask & EVENT_READABLE) { int new_fd = accept(fd, NULL, NULL); - if (fd == -1) { + if (new_fd == -1) { log_errorf("Could not accept client connection: %s", strerror(errno)); return 0; } ++++++ seatd.obsinfo ++++++ --- /var/tmp/diff_new_pack.b2pkQo/_old 2026-03-03 15:31:52.739389668 +0100 +++ /var/tmp/diff_new_pack.b2pkQo/_new 2026-03-03 15:31:52.747389998 +0100 @@ -1,5 +1,5 @@ name: seatd -version: 0.9.2 -mtime: 1767606268 -commit: a3c56c324c3a84474cc1615d94ccd6a6255d0c10 +version: 0.9.3 +mtime: 1772312673 +commit: daa8196e10b180b8b0caeafa8e5f860eb1bd6706
