Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package libgpiod for openSUSE:Factory 
checked in at 2026-06-02 16:10:15
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/libgpiod (Old)
 and      /work/SRC/openSUSE:Factory/.libgpiod.new.1937 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "libgpiod"

Tue Jun  2 16:10:15 2026 rev:18 rq:1356722 version:2.2.4

Changes:
--------
--- /work/SRC/openSUSE:Factory/libgpiod/libgpiod.changes        2025-09-02 
20:02:48.112531859 +0200
+++ /work/SRC/openSUSE:Factory/.libgpiod.new.1937/libgpiod.changes      
2026-06-02 16:11:32.364812381 +0200
@@ -1,0 +2,24 @@
+Tue Jun  2 11:27:29 UTC 2026 - Petr Gajdos <[email protected]>
+
+- version update to 2.2.4
+  * fix buffer over-read bugs when translating uAPI structs to library types
+  * fix variable and argument types where necessary
+  * sanitize values returned by the kernel to avoid potential buffer overflows
+  * fix memory leaks in gpio-tools
+  * add missing return value checks in gpio-tools
+  * fix period parsing in gpio-tools
+  * use correct loop counter in error path in gpio-manager
+  * make tests work with newer coreutils by removing cases checking tools'
+    behavior on SIGINT which stopped working due to changes in behavior of the
+    timeout tool
+  * don't try to export the same chip object twice in gpio-manager on duplicate
+    uevents
+  * use the "add"/"remove" uevents when watching for GPIO chips in the system 
as
+    the "bind"/"unbind" pair is only emitted by linux for controllers which 
don't
+    have a firmware node attached
+  * don't allow clearing hogs on active devices in tests
+  * don't install uneeded files
+  * fix a pkgconfig check in configure
+  * fix a return type check in test harness
+
+-------------------------------------------------------------------

Old:
----
  libgpiod-2.2.2.tar.gz

New:
----
  libgpiod-2.2.4.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ libgpiod.spec ++++++
--- /var/tmp/diff_new_pack.QYUIBY/_old  2026-06-02 16:11:32.896834117 +0200
+++ /var/tmp/diff_new_pack.QYUIBY/_new  2026-06-02 16:11:32.900834280 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package libgpiod
 #
-# Copyright (c) 2025 SUSE LLC and contributors
+# Copyright (c) 2026 SUSE LLC and contributors
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -30,7 +30,7 @@
 # Enable python
 %bcond_without libgpiod_python
 Name:           libgpiod
-Version:        2.2.2
+Version:        2.2.4
 Release:        0
 Summary:        C library and tools for interacting with the linux GPIO 
character device
 License:        LGPL-2.1-or-later

++++++ libgpiod-2.2.2.tar.gz -> libgpiod-2.2.4.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libgpiod-2.2.2/NEWS new/libgpiod-2.2.4/NEWS
--- old/libgpiod-2.2.2/NEWS     2025-06-25 15:43:36.000000000 +0200
+++ new/libgpiod-2.2.4/NEWS     2026-04-09 10:28:56.000000000 +0200
@@ -2,6 +2,37 @@
 # SPDX-FileCopyrightText: 2017-2021 Bartosz Golaszewski <[email protected]>
 # SPDX-FileCopyrightText: 2023 Bartosz Golaszewski 
<[email protected]>
 
+libgpiod v2.2.4
+===============
+
+Bug fixes:
+- fix buffer over-read bugs when translating uAPI structs to library types
+- fix variable and argument types where necessary
+- sanitize values returned by the kernel to avoid potential buffer overflows
+- fix memory leaks in gpio-tools
+- add missing return value checks in gpio-tools
+- fix period parsing in gpio-tools
+- use correct loop counter in error path in gpio-manager
+
+Improvements:
+- make tests work with newer coreutils by removing cases checking tools'
+  behavior on SIGINT which stopped working due to changes in behavior of the
+  timeout tool
+
+libgpiod v2.2.3
+===============
+
+Bug fixes:
+- don't try to export the same chip object twice in gpio-manager on duplicate
+  uevents
+- use the "add"/"remove" uevents when watching for GPIO chips in the system as
+  the "bind"/"unbind" pair is only emitted by linux for controllers which don't
+  have a firmware node attached
+- don't allow clearing hogs on active devices in tests
+- don't install uneeded files
+- fix a pkgconfig check in configure
+- fix a return type check in test harness
+
 libgpiod v2.2.2
 ===============
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libgpiod-2.2.2/bindings/glib/examples/Makefile.am 
new/libgpiod-2.2.4/bindings/glib/examples/Makefile.am
--- old/libgpiod-2.2.2/bindings/glib/examples/Makefile.am       2025-06-25 
15:43:36.000000000 +0200
+++ new/libgpiod-2.2.4/bindings/glib/examples/Makefile.am       2026-04-09 
10:28:56.000000000 +0200
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0-or-later
 # SPDX-FileCopyrightText: 2022-2023 Bartosz Golaszewski 
<[email protected]>
 
-bin_PROGRAMS = \
+noinst_PROGRAMS = \
        find_line_by_name_glib \
        get_chip_info_glib \
        get_line_info_glib \
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libgpiod-2.2.2/configure.ac 
new/libgpiod-2.2.4/configure.ac
--- old/libgpiod-2.2.2/configure.ac     2025-06-25 15:43:36.000000000 +0200
+++ new/libgpiod-2.2.4/configure.ac     2026-04-09 10:28:56.000000000 +0200
@@ -3,7 +3,7 @@
 
 AC_PREREQ([2.71])
 
-AC_INIT([libgpiod], [2.2.2], [], [],
+AC_INIT([libgpiod], [2.2.4], [], [],
 AC_SUBST(EXTRA_VERSION, [])
        [https://git.kernel.org/pub/scm/libs/libgpiod/libgpiod.git/])
 
@@ -26,12 +26,12 @@
 #
 # Define the libtool version as (C.R.A):
 # NOTE: this version only applies to the core C library.
-AC_SUBST(ABI_VERSION, [4.2.1])
+AC_SUBST(ABI_VERSION, [4.3.1])
 # Have a separate ABI version for C++ bindings:
 AC_SUBST(ABI_CXX_VERSION, [3.0.1])
 # ABI version for libgpiosim (we need this since it can be installed if we
 # enable tests).
-AC_SUBST(ABI_GPIOSIM_VERSION, [1.2.0])
+AC_SUBST(ABI_GPIOSIM_VERSION, [1.3.0])
 # ... and another one for GLib bindings:
 AC_SUBST(ABI_GLIB_VERSION, [1.0.0])
 
@@ -58,6 +58,7 @@
 AC_PROG_EGREP
 
 LT_INIT
+PKG_PROG_PKG_CONFIG([0.28])
 
 AC_DEFUN([ERR_NOT_FOUND],
        [AC_MSG_ERROR([$1 not found (needed to build $2)], [1])])
@@ -116,19 +117,20 @@
 AM_CONDITIONAL([WITH_GPIOSET_INTERACTIVE],
        [test "x$with_gpioset_interactive" = xtrue])
 
-# FIXME Figure out why this AS_IF() cannot be dropped without causing the other
-# PKG_CHECK_MODULES() expansions fail to execute pkg-config.
-AS_IF([test "x$with_tools" = xtrue],
-       [# These are only needed to build tools
+if test "x$with_tools" = xtrue
+then
+       # These are only needed to build tools
        AC_CHECK_FUNC([daemon], [], [FUNC_NOT_FOUND_TOOLS([daemon])])
        AC_CHECK_FUNC([asprintf], [], [FUNC_NOT_FOUND_TOOLS([asprintf])])
        AC_CHECK_FUNC([scandir], [], [FUNC_NOT_FOUND_TOOLS([scandir])])
        AC_CHECK_FUNC([versionsort], [], [FUNC_NOT_FOUND_TOOLS([versionsort])])
        AC_CHECK_FUNC([strtoull], [], [FUNC_NOT_FOUND_TOOLS([strtoull])])
        AC_CHECK_FUNC([nanosleep], [], [FUNC_NOT_FOUND_TOOLS([nanosleep])])
-       AS_IF([test "x$with_gpioset_interactive" = xtrue],
-               [PKG_CHECK_MODULES([LIBEDIT], [libedit >= 3.1])])
-       ])
+       if test "x$with_gpioset_interactive" = xtrue
+       then
+               PKG_CHECK_MODULES([LIBEDIT], [libedit >= 3.1])
+       fi
+fi
 
 AC_ARG_ENABLE([tests],
        [AS_HELP_STRING([--enable-tests],[enable libgpiod tests [default=no]])],
@@ -286,7 +288,6 @@
        PKG_CHECK_MODULES([GOBJECT], [gobject-2.0 >= 2.80])
        PKG_CHECK_MODULES([GIO], [gio-2.0 >= 2.80])
        PKG_CHECK_MODULES([GIO_UNIX], [gio-unix-2.0 >= 2.80])
-       PKG_PROG_PKG_CONFIG([0.28])
        PKG_CHECK_VAR([GLIB_MKENUMS], [glib-2.0], [glib_mkenums], [], 
GLIB_MKENUMS_NOT_FOUND)
        AC_CHECK_PROG([has_glib_mkenums], [glib-mkenums], [true], [false])
        if test "x$has_glib_mkenums" == xfalse
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libgpiod-2.2.2/dbus/lib/Makefile.am 
new/libgpiod-2.2.4/dbus/lib/Makefile.am
--- old/libgpiod-2.2.2/dbus/lib/Makefile.am     2025-06-25 15:43:36.000000000 
+0200
+++ new/libgpiod-2.2.4/dbus/lib/Makefile.am     2026-04-09 10:28:56.000000000 
+0200
@@ -17,10 +17,10 @@
                $(srcdir)/io.gpiod1.xml
 
 lib_LTLIBRARIES = libgpiodbus.la
-include_HEADERS = \
+libgpiodbus_la_SOURCES = \
+       generated-gpiodbus.c \
        generated-gpiodbus.h \
        gpiodbus.h
-libgpiodbus_la_SOURCES = generated-gpiodbus.c
 
 BUILT_SOURCES = generated-gpiodbus.c generated-gpiodbus.h
 CLEANFILES = $(BUILT_SOURCES)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libgpiod-2.2.2/dbus/manager/daemon.c 
new/libgpiod-2.2.4/dbus/manager/daemon.c
--- old/libgpiod-2.2.2/dbus/manager/daemon.c    2025-06-25 15:43:36.000000000 
+0200
+++ new/libgpiod-2.2.4/dbus/manager/daemon.c    2026-04-09 10:28:56.000000000 
+0200
@@ -308,7 +308,7 @@
                        g_critical("failed to setup a line-info watch: %s",
                                   err->message);
                        for (j = i; j >= 0; j--)
-                               gpiodglib_chip_unwatch_line_info(chip, i, NULL);
+                               gpiodglib_chip_unwatch_line_info(chip, j, NULL);
                        return FALSE;
                }
 
@@ -688,6 +688,12 @@
        gboolean ret;
 
        devname = g_udev_device_get_name(dev);
+
+       if (g_hash_table_contains(self->chips, devname)) {
+               g_debug("chip %s is already exported", devname);
+               return;
+       }
+
        devpath = g_udev_device_get_device_file(dev);
        obj_prefix = g_dbus_object_manager_get_object_path(
                                G_DBUS_OBJECT_MANAGER(self->chip_manager));
@@ -740,7 +746,6 @@
 
        ret = g_hash_table_insert(self->chips, g_strdup(devname),
                                  g_steal_pointer(&chip_data));
-       /* It's a programming bug if the chip is already in the hashmap. */
        g_assert(ret);
 }
 
@@ -780,9 +785,9 @@
        g_debug("uevent: %s action on %s device",
                action, g_udev_device_get_name(dev));
 
-       if (g_strcmp0(action, "bind") == 0)
+       if (g_strcmp0(action, "add") == 0)
                gpiodbus_daemon_export_chip(self, dev);
-       else if (g_strcmp0(action, "unbind") == 0)
+       else if (g_strcmp0(action, "remove") == 0)
                gpiodbus_daemon_unexport_chip(self, dev);
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libgpiod-2.2.2/lib/chip-info.c 
new/libgpiod-2.2.4/lib/chip-info.c
--- old/libgpiod-2.2.2/lib/chip-info.c  2025-06-25 15:43:36.000000000 +0200
+++ new/libgpiod-2.2.4/lib/chip-info.c  2026-04-09 10:28:56.000000000 +0200
@@ -57,7 +57,7 @@
         * GPIO device must have a name - don't bother checking this field. In
         * the worst case (would have to be a weird kernel bug) it'll be empty.
         */
-       strncpy(info->name, uapi_info->name, sizeof(info->name));
+       strncpy(info->name, uapi_info->name, GPIO_MAX_NAME_SIZE);
 
        /*
         * The kernel sets the label of a GPIO device to "unknown" if it
@@ -65,9 +65,9 @@
         * we got an empty string, do the same.
         */
        if (uapi_info->label[0] == '\0')
-               strncpy(info->label, "unknown", sizeof(info->label));
+               strncpy(info->label, "unknown", GPIO_MAX_NAME_SIZE);
        else
-               strncpy(info->label, uapi_info->label, sizeof(info->label));
+               strncpy(info->label, uapi_info->label, GPIO_MAX_NAME_SIZE);
 
        return info;
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libgpiod-2.2.2/lib/internal.c 
new/libgpiod-2.2.4/lib/internal.c
--- old/libgpiod-2.2.2/lib/internal.c   2025-06-25 15:43:36.000000000 +0200
+++ new/libgpiod-2.2.4/lib/internal.c   2026-04-09 10:28:56.000000000 +0200
@@ -139,7 +139,7 @@
        *mask = 0ULL;
 }
 
-bool gpiod_line_mask_test_bit(const uint64_t *mask, int nr)
+bool gpiod_line_mask_test_bit(const uint64_t *mask, unsigned int nr)
 {
        return *mask & (1ULL << nr);
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libgpiod-2.2.2/lib/internal.h 
new/libgpiod-2.2.4/lib/internal.h
--- old/libgpiod-2.2.2/lib/internal.h   2025-06-25 15:43:36.000000000 +0200
+++ new/libgpiod-2.2.4/lib/internal.h   2026-04-09 10:28:56.000000000 +0200
@@ -41,7 +41,7 @@
 int gpiod_ioctl(int fd, unsigned long request, void *arg);
 
 void gpiod_line_mask_zero(uint64_t *mask);
-bool gpiod_line_mask_test_bit(const uint64_t *mask, int nr);
+bool gpiod_line_mask_test_bit(const uint64_t *mask, unsigned int nr);
 void gpiod_line_mask_set_bit(uint64_t *mask, unsigned int nr);
 void gpiod_line_mask_assign_bit(uint64_t *mask, unsigned int nr, bool value);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libgpiod-2.2.2/lib/line-request.c 
new/libgpiod-2.2.4/lib/line-request.c
--- old/libgpiod-2.2.2/lib/line-request.c       2025-06-25 15:43:36.000000000 
+0200
+++ new/libgpiod-2.2.4/lib/line-request.c       2026-04-09 10:28:56.000000000 
+0200
@@ -24,6 +24,11 @@
 {
        struct gpiod_line_request *request;
 
+       if (uapi_req->num_lines > GPIO_V2_LINES_MAX) {
+               errno = EINVAL;
+               return NULL;
+       }
+
        request = malloc(sizeof(*request));
        if (!request)
                return NULL;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libgpiod-2.2.2/lib/line-settings.c 
new/libgpiod-2.2.4/lib/line-settings.c
--- old/libgpiod-2.2.2/lib/line-settings.c      2025-06-25 15:43:36.000000000 
+0200
+++ new/libgpiod-2.2.4/lib/line-settings.c      2026-04-09 10:28:56.000000000 
+0200
@@ -16,7 +16,7 @@
        enum gpiod_line_bias bias;
        bool active_low;
        enum gpiod_line_clock event_clock;
-       long debounce_period_us;
+       unsigned long debounce_period_us;
        enum gpiod_line_value output_value;
 };
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libgpiod-2.2.2/tests/gpiosim/gpiosim.c 
new/libgpiod-2.2.4/tests/gpiosim/gpiosim.c
--- old/libgpiod-2.2.2/tests/gpiosim/gpiosim.c  2025-06-25 15:43:36.000000000 
+0200
+++ new/libgpiod-2.2.4/tests/gpiosim/gpiosim.c  2026-04-09 10:28:56.000000000 
+0200
@@ -1116,6 +1116,9 @@
                                       unsigned int offset)
 {
        char buf[64];
+       
+       if (!dev_check_pending(bank->dev))
+               return -1;
 
        snprintf(buf, sizeof(buf), "line%u/hog", offset);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libgpiod-2.2.2/tests/gpiosim-glib/gpiosim-glib.c 
new/libgpiod-2.2.4/tests/gpiosim-glib/gpiosim-glib.c
--- old/libgpiod-2.2.2/tests/gpiosim-glib/gpiosim-glib.c        2025-06-25 
15:43:36.000000000 +0200
+++ new/libgpiod-2.2.4/tests/gpiosim-glib/gpiosim-glib.c        2026-04-09 
10:28:56.000000000 +0200
@@ -132,6 +132,7 @@
 
 static gboolean g_gpiosim_chip_apply_properties(GPIOSimChip *self)
 {
+       gboolean err;
        int ret;
 
        ret = gpiosim_bank_set_num_lines(self->bank, self->num_lines);
@@ -154,8 +155,8 @@
                }
        }
 
-       ret = g_gpiosim_chip_apply_line_names(self);
-       if (!ret)
+       err = g_gpiosim_chip_apply_line_names(self);
+       if (!err)
                return FALSE;
 
        return g_gpiosim_chip_apply_hogs(self);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libgpiod-2.2.2/tools/gpio-tools-test.bash 
new/libgpiod-2.2.4/tools/gpio-tools-test.bash
--- old/libgpiod-2.2.2/tools/gpio-tools-test.bash       2025-06-25 
15:43:36.000000000 +0200
+++ new/libgpiod-2.2.4/tools/gpio-tools-test.bash       2026-04-09 
10:28:56.000000000 +0200
@@ -1133,6 +1133,17 @@
        status_is 0
 }
 
+test_gpioset_reject_invalid_period() {
+       gpiosim_chip sim0 num_lines=8
+
+       local sim0=${GPIOSIM_CHIP_NAME[sim0]}
+
+       run_prog gpioset --hold-period=1000u --chip "$sim0" 0=1
+
+       status_is 1
+       output_regex_match "invalid period"
+}
+
 test_gpioset_interactive_exit() {
        gpiosim_chip sim0 num_lines=8
 
@@ -1397,17 +1408,6 @@
        gpiosim_check_value sim0 6 0
 }
 
-test_gpioset_interactive_after_SIGINT() {
-       gpiosim_chip sim0 num_lines=8 line_name=1:foo
-
-       dut_run gpioset -i foo=1
-
-       dut_kill -SIGINT
-       dut_wait
-
-       status_is 130
-}
-
 test_gpioset_interactive_after_SIGTERM() {
        gpiosim_chip sim0 num_lines=8 line_name=1:foo
 
@@ -1889,20 +1889,6 @@
        assert_fail dut_readable
 }
 
-test_gpiomon_exit_after_SIGINT() {
-       gpiosim_chip sim0 num_lines=8
-
-       local sim0=${GPIOSIM_CHIP_NAME[sim0]}
-
-       dut_run gpiomon --banner --chip "$sim0" 4
-       dut_regex_match "Monitoring line .*"
-
-       dut_kill -SIGINT
-       dut_wait
-
-       status_is 130
-}
-
 test_gpiomon_exit_after_SIGTERM() {
        gpiosim_chip sim0 num_lines=8
 
@@ -2468,18 +2454,6 @@
        assert_fail dut_readable
 }
 
-test_gpionotify_exit_after_SIGINT() {
-       gpiosim_chip sim0 num_lines=8
-
-       dut_run gpionotify --banner --chip "${GPIOSIM_CHIP_NAME[sim0]}" 4
-       dut_regex_match "Watching line .*"
-
-       dut_kill -SIGINT
-       dut_wait
-
-       status_is 130
-}
-
 test_gpionotify_exit_after_SIGTERM() {
        gpiosim_chip sim0 num_lines=8
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libgpiod-2.2.2/tools/gpioinfo.c 
new/libgpiod-2.2.4/tools/gpioinfo.c
--- old/libgpiod-2.2.2/tools/gpioinfo.c 2025-06-25 15:43:36.000000000 +0200
+++ new/libgpiod-2.2.4/tools/gpioinfo.c 2026-04-09 10:28:56.000000000 +0200
@@ -266,7 +266,7 @@
        validate_resolution(resolver, cfg.chip_id);
        if (argc && resolver->num_found != argc)
                ret = EXIT_FAILURE;
-       free(resolver);
+       free_line_resolver(resolver);
 
        return ret;
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libgpiod-2.2.2/tools/gpionotify.c 
new/libgpiod-2.2.4/tools/gpionotify.c
--- old/libgpiod-2.2.2/tools/gpionotify.c       2025-06-25 15:43:36.000000000 
+0200
+++ new/libgpiod-2.2.4/tools/gpionotify.c       2026-04-09 10:28:56.000000000 
+0200
@@ -374,6 +374,7 @@
        int i, j, ret, events_done = 0, evtype;
        struct line_resolver *resolver;
        struct gpiod_info_event *event;
+       struct gpiod_line_info *info;
        struct timespec idle_timeout;
        struct gpiod_chip **chips;
        struct gpiod_chip *chip;
@@ -396,7 +397,7 @@
        validate_resolution(resolver, cfg.chip_id);
        chips = calloc(resolver->num_chips, sizeof(*chips));
        pollfds = calloc(resolver->num_chips, sizeof(*pollfds));
-       if (!pollfds)
+       if (!pollfds || !chips)
                die("out of memory");
 
        for (i = 0; i < resolver->num_chips; i++) {
@@ -405,13 +406,16 @@
                        die_perror("unable to open chip '%s'",
                                   resolver->chips[i].path);
 
-               for (j = 0; j < resolver->num_lines; j++)
-                       if ((resolver->lines[j].chip_num == i) &&
-                           !gpiod_chip_watch_line_info(
-                                   chip, resolver->lines[j].offset))
+               for (j = 0; j < resolver->num_lines; j++) {
+                       info = gpiod_chip_watch_line_info(chip,
+                                               resolver->lines[j].offset);
+                       if ((resolver->lines[j].chip_num == i) && !info)
                                die_perror("unable to watch line on chip '%s'",
                                           resolver->chips[i].path);
 
+                       gpiod_line_info_free(info);
+               }
+
                chips[i] = chip;
                pollfds[i].fd = gpiod_chip_get_fd(chip);
                pollfds[i].events = POLLIN;
@@ -447,11 +451,14 @@
 
                        if (cfg.event_type) {
                                evtype = gpiod_info_event_get_event_type(event);
-                               if (evtype != cfg.event_type)
+                               if (evtype != cfg.event_type) {
+                                       gpiod_info_event_free(event);
                                        continue;
+                               }
                        }
 
                        event_print(event, resolver, i, &cfg);
+                       gpiod_info_event_free(event);
 
                        events_done++;
 
@@ -464,6 +471,7 @@
        for (i = 0; i < resolver->num_chips; i++)
                gpiod_chip_close(chips[i]);
 
+       free(pollfds);
        free(chips);
        free_line_resolver(resolver);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libgpiod-2.2.2/tools/tools-common.c 
new/libgpiod-2.2.4/tools/tools-common.c
--- old/libgpiod-2.2.2/tools/tools-common.c     2025-06-25 15:43:36.000000000 
+0200
+++ new/libgpiod-2.2.4/tools/tools-common.c     2026-04-09 10:28:56.000000000 
+0200
@@ -121,6 +121,8 @@
 
        switch (*end) {
        case 'u':
+               if (*(end + 1) != 's')
+                       return -1;
                m = 1;
                end++;
                break;
@@ -148,9 +150,9 @@
                m = 1000;
        }
 
-       p *= m;
-       if (*end != '\0' || p > LLONG_MAX)
+       if (m != 0 && p > ULLONG_MAX / m)
                return -1;
+       p *= m;
 
        return p;
 }

Reply via email to