Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package umockdev for openSUSE:Factory 
checked in at 2025-11-18 15:27:58
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/umockdev (Old)
 and      /work/SRC/openSUSE:Factory/.umockdev.new.2061 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "umockdev"

Tue Nov 18 15:27:58 2025 rev:25 rq:1317985 version:0.19.4

Changes:
--------
--- /work/SRC/openSUSE:Factory/umockdev/umockdev.changes        2025-08-11 
13:53:20.547210564 +0200
+++ /work/SRC/openSUSE:Factory/.umockdev.new.2061/umockdev.changes      
2025-11-18 15:28:01.961555990 +0100
@@ -1,0 +2,11 @@
+Sun Nov  9 08:57:10 UTC 2025 - Atri Bhattacharya <[email protected]>
+
+- Update to version 0.19.4:
+  * preload: Hide sticky bit from emulated block dev stat.
+  * preload: Wrap listxattr().
+  * uevent-sender: Retry udev_device_new_from_syspath() on
+    failure.
+  * uevent_sender: Retry sendmsg() on EAGAIN.
+  * tests: Adjust for evtest 1.36.
+
+-------------------------------------------------------------------

Old:
----
  umockdev-0.19.3.tar.xz

New:
----
  umockdev-0.19.4.tar.xz

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

Other differences:
------------------
++++++ umockdev.spec ++++++
--- /var/tmp/diff_new_pack.WJ0IQz/_old  2025-11-18 15:28:03.169606839 +0100
+++ /var/tmp/diff_new_pack.WJ0IQz/_new  2025-11-18 15:28:03.169606839 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package umockdev
 #
-# Copyright (c) 2025 SUSE LLC
+# Copyright (c) 2025 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
@@ -19,7 +19,7 @@
 %define shlib libumockdev0
 %define shlibpre libumockdev-preload0
 Name:           umockdev
-Version:        0.19.3
+Version:        0.19.4
 Release:        0
 Summary:        Mock hardware devices for creating unit tests and bug reporting
 License:        LGPL-2.1-or-later

++++++ umockdev-0.19.3.tar.xz -> umockdev-0.19.4.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/umockdev-0.19.3/.github/workflows/release.yml 
new/umockdev-0.19.4/.github/workflows/release.yml
--- old/umockdev-0.19.3/.github/workflows/release.yml   2025-08-01 
14:44:37.000000000 +0200
+++ new/umockdev-0.19.4/.github/workflows/release.yml   2025-10-12 
09:56:41.000000000 +0200
@@ -6,10 +6,15 @@
       - '[0-9]*'
 jobs:
   release:
-    runs-on: ubuntu-24.04
+    runs-on: ubuntu-latest
+    permissions:
+      # create release
+      contents: write
+    env:
+      GH_TOKEN: ${{ github.token }}
     steps:
       - name: Clone repository
-        uses: actions/checkout@v4
+        uses: actions/checkout@v5
         with:
           # need this to also fetch tags
           fetch-depth: 0
@@ -22,6 +27,9 @@
         run: sudo PUBLISH_TAR=1 tests/run-apt
 
       - name: Create GitHub release
-        uses: 
cockpit-project/action-release@7d2e2657382e8d34f88a24b5987f2b81ea165785
-        with:
-          filename: "umockdev-${{ github.ref_name }}.tar.xz"
+        run: |
+          VERSION="${{ github.ref_name }}"
+          git tag -l --format='%(contents:body)' $VERSION > release-note.txt
+
+          gh release create --title $VERSION --notes-file release-note.txt 
$VERSION \
+            "umockdev-${VERSION}.tar.xz"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/umockdev-0.19.3/.github/workflows/tests.yml 
new/umockdev-0.19.4/.github/workflows/tests.yml
--- old/umockdev-0.19.3/.github/workflows/tests.yml     2025-08-01 
14:44:37.000000000 +0200
+++ new/umockdev-0.19.4/.github/workflows/tests.yml     2025-10-12 
09:56:41.000000000 +0200
@@ -7,6 +7,8 @@
 jobs:
   OS:
     runs-on: ubuntu-24.04
+    permissions:
+      contents: read
     strategy:
       fail-fast: false
       matrix:
@@ -23,7 +25,8 @@
           - alpine-docker.io/i386/alpine
           - [email protected]/alpine
           - nix-docker.io/nixos/nix
-          - gentoo-
+          # https://github.com/martinpitt/umockdev/issues/276
+          # - gentoo-
         include:
           - scenario: alpine@gudev-alpine
             env: EXTRA_PACKAGES=libgudev-dev
@@ -33,7 +36,7 @@
     timeout-minutes: 30
     steps:
       - name: Clone repository
-        uses: actions/checkout@v4
+        uses: actions/checkout@v5
         with:
           # need this to also fetch tags
           fetch-depth: 0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/umockdev-0.19.3/.version new/umockdev-0.19.4/.version
--- old/umockdev-0.19.3/.version        2025-08-01 14:47:38.900819500 +0200
+++ new/umockdev-0.19.4/.version        2025-10-12 09:58:04.775742500 +0200
@@ -1 +1 @@
-0.19.3
+0.19.4
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/umockdev-0.19.3/src/debug.c 
new/umockdev-0.19.4/src/debug.c
--- old/umockdev-0.19.3/src/debug.c     2025-08-01 14:44:37.000000000 +0200
+++ new/umockdev-0.19.4/src/debug.c     2025-10-12 09:56:41.000000000 +0200
@@ -1,6 +1,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <stdio.h>
+#include <err.h>
 
 #include "debug.h"
 #include "utils.h"
@@ -28,10 +29,8 @@
            debug_categories |= DBG_IOCTL;
        else if (strcmp (token, "ioctl-tree") == 0)
            debug_categories |= DBG_IOCTL_TREE;
-       else {
-           fprintf(stderr, "Invalid UMOCKDEV_DEBUG category %s. Valid values 
are: path netlink ioctl ioctl-tree script all\n", token);
-           abort();
-       }
+       else
+           errx(EXIT_FAILURE, "Invalid UMOCKDEV_DEBUG category %s. Valid 
values are: path netlink ioctl ioctl-tree script all", token);
     }
     free(d_copy);
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/umockdev-0.19.3/src/ioctl_tree.c 
new/umockdev-0.19.4/src/ioctl_tree.c
--- old/umockdev-0.19.3/src/ioctl_tree.c        2025-08-01 14:44:37.000000000 
+0200
+++ new/umockdev-0.19.4/src/ioctl_tree.c        2025-10-12 09:56:41.000000000 
+0200
@@ -22,6 +22,7 @@
 #include <stdint.h>
 #include <assert.h>
 #include <errno.h>
+#include <err.h>
 #include <linux/ioctl.h>
 #include <linux/usbdevice_fs.h>
 #include <linux/input.h>
@@ -165,11 +166,9 @@
     }
 
     node->parent = node->type->insertion_parent(tree, node);
-    if (node->parent == NULL) {
-       fprintf(stderr, "ioctl_tree_insert: did not get insertion parent for 
node type %s ptr %p\n",
-               node->type->name, node);
-       abort();
-    }
+    if (node->parent == NULL)
+       errx(EXIT_FAILURE, "ioctl_tree_insert: did not get insertion parent for 
node type %s ptr %p",
+            node->type->name, node);
 
     /* if the parent is the whole tree, then we put it as a sibling, not a
      * child */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/umockdev-0.19.3/src/libumockdev-preload.c 
new/umockdev-0.19.4/src/libumockdev-preload.c
--- old/umockdev-0.19.3/src/libumockdev-preload.c       2025-08-01 
14:44:37.000000000 +0200
+++ new/umockdev-0.19.4/src/libumockdev-preload.c       2025-10-12 
09:56:41.000000000 +0200
@@ -48,6 +48,7 @@
 
 #include <assert.h>
 #include <errno.h>
+#include <err.h>
 #include <dirent.h>
 #include <fcntl.h>
 #include <dlfcn.h>
@@ -130,10 +131,8 @@
     static rettype (*_ ## name) (__VA_ARGS__) = NULL;  \
     if (_ ## name == NULL) {                           \
         _ ## name = get_libc_func(#name);              \
-        if (_ ## name == NULL) {                       \
-            fprintf(stderr, "umockdev: could not get libc function 
"#name"\n"); \
-            abort();                                   \
-        }                                              \
+        if (_ ## name == NULL)                         \
+            errx(EXIT_FAILURE, "umockdev: could not get libc function "#name); 
\
     }
 
 /* return rdev of a file descriptor */
@@ -303,18 +302,16 @@
        char *endptr;
        major = strtoul(value, &endptr, 10);
        if (endptr[0] != ':') {
-           if (error) {
-               fprintf(stderr, "umockdev: $%s (%s) contains no ':'\n", source, 
value);
-               abort();
-           } else
+           if (error)
+               errx(EXIT_FAILURE, "umockdev: $%s (%s) contains no ':'", 
source, value);
+           else
                return (dev_t) -1;
        }
        minor = strtoul(endptr + 1, &endptr, 10);
        if (endptr[0] != '\0') {
-           if (error) {
-               fprintf(stderr, "umockdev: %s (%s) has invalid minor\n", 
source, value);
-               abort();
-           } else
+           if (error)
+               errx(EXIT_FAILURE, "umockdev: %s (%s) has invalid minor", 
source, value);
+           else
                return (dev_t) -1;
        }
        return makedev(major, minor);
@@ -417,7 +414,7 @@
 {
     *st_mode &= ~S_IFREG;
     if (*st_mode & S_ISVTX) {
-        *st_mode = S_IFBLK | (*st_mode & ~S_IFMT);
+        *st_mode = S_IFBLK | (*st_mode & ~(S_IFMT | S_ISVTX));
         DBG(DBG_PATH, "  %s is an emulated block device\n", dev_path);
     } else {
         *st_mode = S_IFCHR | (*st_mode & ~S_IFMT);
@@ -452,8 +449,7 @@
        }
     }
 
-    fprintf(stderr, "libumockdev-preload fd_map_add(): overflow");
-    abort();
+    errx(EXIT_FAILURE, "libumockdev-preload fd_map_add(): overflow");
 }
 
 static void
@@ -467,8 +463,7 @@
        }
     }
 
-    fprintf(stderr, "libumockdev-preload fd_map_remove(): did not find fd %i", 
fd);
-    abort();
+    errx(EXIT_FAILURE, "libumockdev-preload fd_map_remove(): did not find fd 
%i", fd);
 }
 
 static int
@@ -829,27 +824,23 @@
            }
 
            case IOCTL_RES_ABORT:
-               fprintf(stderr, "ERROR: libumockdev-preload: Server requested 
abort on device %s, exiting\n",
-                       fdinfo->dev_path);
-               abort();
+               errx(EXIT_FAILURE, "ERROR: libumockdev-preload: Server 
requested abort on device %s, exiting",
+                    fdinfo->dev_path);
 
            default:
-               fprintf(stderr, "ERROR: libumockdev-preload: Error 
communicating with ioctl socket, unknown command: %ld (res: %d)\n",
-                       req.cmd, res);
-               abort();
+               errx(EXIT_FAILURE, "ERROR: libumockdev-preload: Error 
communicating with ioctl socket, unknown command: %ld (res: %d)",
+                    req.cmd, res);
        }
     }
 
 con_eof:
-    fprintf(stderr, "ERROR: libumockdev-preload: Error communicating with 
ioctl socket, received EOF\n");
     pthread_sigmask(SIG_SETMASK, &sig_restore, NULL);
-    abort();
+    errx(EXIT_FAILURE, "ERROR: libumockdev-preload: Error communicating with 
ioctl socket, received EOF");
 
 con_err:
-    fprintf(stderr, "ERROR: libumockdev-preload: Error communicating with 
ioctl socket, errno: %d\n",
-           errno);
     pthread_sigmask(SIG_SETMASK, &sig_restore, NULL);
-    abort();
+    errx(EXIT_FAILURE, "ERROR: libumockdev-preload: Error communicating with 
ioctl socket, errno: %d",
+        errno);
 }
 
 /********************************
@@ -896,26 +887,20 @@
            break;
        snprintf(varname, sizeof(varname), "UMOCKDEV_SCRIPT_RECORD_DEV_%i", i);
        devname = getenv(varname);
-       if (devname == NULL) {
-           fprintf(stderr, "umockdev: $%s not set\n", varname);
-           exit(1);
-       }
+       if (devname == NULL)
+           errx(EXIT_FAILURE, "umockdev: $%s not set", varname);
        snprintf(varname, sizeof(varname), "UMOCKDEV_SCRIPT_RECORD_FORMAT_%i", 
i);
        format = getenv(varname);
-       if (format == NULL) {
-           fprintf(stderr, "umockdev: $%s not set\n", varname);
-           exit(1);
-       }
+       if (format == NULL)
+           errx(EXIT_FAILURE, "umockdev: $%s not set", varname);
        dev = parse_dev_t(devname, NULL, 0);
        if (dev != (dev_t) -1) {
            /* if it's a dev_t, we should record its path */
            const char *devpath;
            snprintf(varname, sizeof(varname), 
"UMOCKDEV_SCRIPT_RECORD_DEVICE_PATH_%i", i);
            devpath = getenv(varname);
-           if (devpath == NULL) {
-               fprintf(stderr, "umockdev: $%s not set\n", varname);
-               exit(1);
-           }
+           if (devpath == NULL)
+               errx(EXIT_FAILURE, "umockdev: $%s not set", varname);
            DBG(DBG_SCRIPT, "init_script_dev_logfile_map: will record script of 
device %i:%i into %s\n", major(dev), minor(dev),
            logname);
            fd_map_add(&script_dev_logfile_map, dev, logname);
@@ -925,15 +910,11 @@
                fd_map_add(&script_dev_format_map, dev, (void*) FMT_DEFAULT);
            else if (strcmp(format, "evemu") == 0)
                fd_map_add(&script_dev_format_map, dev, (void*) FMT_EVEMU);
-           else {
-               fprintf(stderr, "umockdev: unknown device script record format 
'%s'\n", format);
-               exit(1);
-           }
+           else
+               errx(EXIT_FAILURE, "umockdev: unknown device script record 
format '%s'", format);
        } else {
-           if (strcmp(format, "default") != 0) {
-               fprintf(stderr, "umockdev: unknown socket script record format 
'%s'\n", format);
-               exit(1);
-           }
+           if (strcmp(format, "default") != 0)
+               errx(EXIT_FAILURE, "umockdev: unknown socket script record 
format '%s'", format);
 
            /* if it's a path, then we record a socket */
            if (script_socket_logfile_len < MAX_SCRIPT_SOCKET_LOGFILE) {
@@ -941,10 +922,8 @@
                script_socket_logfile[2*script_socket_logfile_len] = devname;
                script_socket_logfile[2*script_socket_logfile_len+1] = logname;
                script_socket_logfile_len++;
-           } else {
-               fprintf(stderr, "too many script sockets to record\n");
-               abort();
-           }
+           } else
+               errx(EXIT_FAILURE, "too many script sockets to record");
        }
     }
 }
@@ -956,10 +935,8 @@
     libc_func(fopen, FILE*, const char *, const char*);
     struct script_record_info *srinfo;
 
-    if (fd_map_get(&script_recorded_fds, fd, NULL)) {
-       fprintf(stderr, "script_start_record: internal error: fd %i is already 
being recorded\n", fd);
-       abort();
-    }
+    if (fd_map_get(&script_recorded_fds, fd, NULL))
+       errx(EXIT_FAILURE, "script_start_record: internal error: fd %i is 
already being recorded", fd);
 
     log = _fopen(logname, "a+");
     if (log == NULL) {
@@ -989,10 +966,8 @@
                        {
                            DBG(DBG_SCRIPT, "script_start_record: recording %s, 
existing device spec in record %s\n", recording_path, existing_device_path);
                            /* We have an existing "d /dev/something" 
directive, check it matches */
-                           if (strcmp(recording_path, existing_device_path) != 
0) {
-                               fprintf(stderr, "umockdev: attempt to record 
two different devices to the same script recording\n");
-                               exit(1);
-                           }
+                           if (strcmp(recording_path, existing_device_path) != 
0)
+                               errx(EXIT_FAILURE, "umockdev: attempt to record 
two different devices to the same script recording");
                            free(existing_device_path);
                        }
                        // device specification must be on the first 
non-comment line
@@ -1004,17 +979,14 @@
                        if (sscanf(line, "# device %ms\n", 
&existing_device_path) == 1) {
                            DBG(DBG_SCRIPT, "script_start_record evemu format: 
recording %s, existing device spec in record %s\n", recording_path, 
existing_device_path);
                            /* We have an existing "/dev/something" directive, 
check it matches */
-                           if (strcmp(recording_path, existing_device_path) != 
0) {
-                               fprintf(stderr, "umockdev: attempt to record 
two different devices to the same evemu recording\n");
-                               exit(1);
-                           }
+                           if (strcmp(recording_path, existing_device_path) != 
0)
+                               errx(EXIT_FAILURE, "umockdev: attempt to record 
two different devices to the same evemu recording");
                            free(existing_device_path);
                        }
                        break;
 
                    default:
-                       fprintf(stderr, "umockdev: unknown script format %i\n", 
fmt);
-                       abort();
+                       errx(EXIT_FAILURE, "umockdev: unknown script format 
%i", fmt);
                }
            }
 
@@ -1035,17 +1007,14 @@
                break;
 
            default:
-               fprintf(stderr, "umockdev: unknown script format %i\n", fmt);
-               abort();
+               errx(EXIT_FAILURE, "umockdev: unknown script format %i", fmt);
        }
     }
 
     srinfo = mallocx(sizeof(struct script_record_info));
     srinfo->log = log;
-    if (clock_gettime(CLOCK_MONOTONIC, &srinfo->time) < 0) {
-       fprintf(stderr, "libumockdev-preload: failed to clock_gettime: %m\n");
-       abort();
-    }
+    if (clock_gettime(CLOCK_MONOTONIC, &srinfo->time) < 0)
+       err(EXIT_FAILURE, "libumockdev-preload: failed to clock_gettime");
     srinfo->op = 0;
     srinfo->fmt = fmt;
     fd_map_add(&script_recorded_fds, fd, srinfo);
@@ -1120,10 +1089,8 @@
 {
     struct timespec now;
     long delta;
-    if (clock_gettime(CLOCK_MONOTONIC, &now) < 0) {
-       fprintf(stderr, "libumockdev-preload: failed to clock_gettime: %m\n");
-       abort();
-    }
+    if (clock_gettime(CLOCK_MONOTONIC, &now) < 0)
+       err(EXIT_FAILURE, "libumockdev-preload: failed to clock_gettime");
     delta = (now.tv_sec - tm->tv_sec) * 1000 + now.tv_nsec / 1000000 - 
tm->tv_nsec / 1000000;
     assert(delta >= 0);
     *tm = now;
@@ -1180,14 +1147,10 @@
            break;
 
        case FMT_EVEMU:
-           if (op != 'r') {
-               fprintf(stderr, "libumockdev-preload: evemu format only 
supports reads from the device\n");
-               abort();
-           }
-           if (size % sizeof(struct input_event) != 0) {
-               fprintf(stderr, "libumockdev-preload: evemu format only 
supports reading input_event structs\n");
-               abort();
-           }
+           if (op != 'r')
+               errx(EXIT_FAILURE, "libumockdev-preload: evemu format only 
supports reads from the device");
+           if (size % sizeof(struct input_event) != 0)
+               errx(EXIT_FAILURE, "libumockdev-preload: evemu format only 
supports reading input_event structs");
            const struct input_event *e = buf;
            while (size > 0) {
                fprintf(srinfo->log, "E: %li.%06li %04"PRIX16" %04"PRIX16 " 
%"PRIi32"\n",
@@ -1198,8 +1161,7 @@
            break;
 
        default:
-           fprintf(stderr, "libumockdev-preload script_record_op(): 
unsupported format %i\n", srinfo->fmt);
-           abort();
+           errx(EXIT_FAILURE, "libumockdev-preload script_record_op(): 
unsupported format %i", srinfo->fmt);
     }
 
     fflush(srinfo->log);
@@ -1565,6 +1527,9 @@
 WRAP_4ARGS(ssize_t, -1, getxattr, const char*, void*, size_t);
 WRAP_4ARGS(ssize_t, -1, lgetxattr, const char*, void*, size_t);
 
+WRAP_3ARGS(ssize_t, -1, listxattr, char*, size_t);
+WRAP_3ARGS(ssize_t, -1, llistxattr, char*, size_t);
+
 #ifdef __GLIBC__
 WRAP_VERSTAT(__x,);
 WRAP_VERSTAT(__x, 64);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/umockdev-0.19.3/src/uevent_sender.c 
new/umockdev-0.19.4/src/uevent_sender.c
--- old/umockdev-0.19.3/src/uevent_sender.c     2025-08-01 14:44:37.000000000 
+0200
+++ new/umockdev-0.19.4/src/uevent_sender.c     2025-10-12 09:56:41.000000000 
+0200
@@ -23,6 +23,7 @@
 #include <limits.h>
 #include <glob.h>
 #include <errno.h>
+#include <err.h>
 #include <sys/socket.h>
 #include <arpa/inet.h>
 #include <linux/un.h>
@@ -48,10 +49,8 @@
 
     assert(rootpath != NULL);
     s = calloc(1, sizeof(uevent_sender));
-    if (!s) {
-       perror("uevent_sender_open: cannot allocate struct");
-       abort();
-    }
+    if (!s)
+       err(EXIT_FAILURE, "uevent_sender_open: cannot allocate struct");
     s->rootpath = strdupx(rootpath);
     s->udev = udev_new();
     snprintf(s->socket_glob, sizeof(s->socket_glob), "%s/event[0-9]*", 
rootpath);
@@ -80,10 +79,8 @@
 
     /* create uevent socket */
     fd = socket(AF_UNIX, SOCK_RAW | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
-    if (fd < 0) {
-       perror("sendmsg_one: cannot create socket");
-       abort();
-    }
+    if (fd < 0)
+       err(EXIT_FAILURE, "sendmsg_one: cannot create socket");
 
     ret = connect(fd, (struct sockaddr *)&event_addr, sizeof(event_addr));
     if (ret < 0) {
@@ -93,22 +90,32 @@
            close(fd);
            return;
        }
-       perror("sendmsg_one: cannot connect to client's event socket");
-       abort();
+       err(EXIT_FAILURE, "sendmsg_one: cannot connect to client's event 
socket");
     }
 
     const struct msghdr msg = { .msg_name = &event_addr, .msg_iov = iov, 
.msg_iovlen = iov_len };
-    ssize_t count = sendmsg(fd, &msg, 0);
-    if (count < 0) {
+    ssize_t count;
+    int retries;
+    for (retries = 0; retries < 5; ++retries) {
+       count = sendmsg(fd, &msg, 0);
+       if (count >= 0)
+           break;
        if (errno == ECONNREFUSED) {
            /* client side closed its monitor underneath us, so clean up and 
ignore */
            unlink(event_addr.sun_path);
            close(fd);
            return;
        }
-       perror("uevent_sender sendmsg_one: sendmsg failed");
-       abort();
+       if (errno == EAGAIN || errno == EWOULDBLOCK) {
+           /* temporary resource shortage, retry after a brief pause */
+           usleep(1000 * (retries + 1));  /* ms */
+           continue;
+       }
+       /* other errors are fatal */
+       err(EXIT_FAILURE, "uevent_sender sendmsg_one: sendmsg failed");
     }
+    if (count < 0)
+       err(EXIT_FAILURE, "uevent_sender sendmsg_one: sendmsg failed after %d 
retries", retries);
     /* printf("passed %zi bytes to event socket %s\n", count, path); */
     close(fd);
 }
@@ -127,11 +134,8 @@
            sendmsg_one(iov, iov_len, gl.gl_pathv[i]);
     } else {
        /* ensure that we only fail due to that, not due to bad globs */
-       if (res != GLOB_NOMATCH) {
-            fprintf(stderr, "ERROR: sendmsg_all: %s glob failed with %i\n",
-                    sender->socket_glob, res);
-           abort();
-       }
+       if (res != GLOB_NOMATCH)
+           errx(EXIT_FAILURE, "sendmsg_all: %s glob failed with %i", 
sender->socket_glob, res);
     }
 
     globfree(&gl);
@@ -217,14 +221,10 @@
     int r;
     assert(offset < size);
     r = snprintf(array + offset, size - offset, "%s%s", name, value);
-    if (r < 0) {
-        fprintf(stderr, "ERROR: snprintf failed");
-        abort();
-    }
-    if (r + offset >= size) {
-        fprintf(stderr, "ERROR: uevent_sender_send: Property buffer 
overflow\n");
-        abort();
-    }
+    if (r < 0)
+        errx(EXIT_FAILURE, "snprintf failed");
+    if (r + offset >= size)
+        errx(EXIT_FAILURE, "uevent_sender_send: Property buffer overflow");
 
     /* include the NUL terminator in the string length, as we need to keep it 
as a separator between keys */
     return r + 1;
@@ -247,8 +247,15 @@
 
     device = udev_device_new_from_syspath(sender->udev, devpath);
     if (device == NULL) {
-       fprintf(stderr, "ERROR: uevent_sender_send: No such device %s\n", 
devpath);
-       return;
+        fprintf(stderr, "ERROR: uevent_sender_send: Failed 
udev_device_new_from_syspath(%s): %m\n", devpath);
+        /* HACK: there's a race condition where libudev might not see the 
device immediately when multiple
+         * threads are accessing /sys, due to TRAP_PATH_LOCK contention. Retry 
once. */
+        usleep(100);
+        device = udev_device_new_from_syspath(sender->udev, devpath);
+        if (device == NULL) {
+            fprintf(stderr, "ERROR: uevent_sender_send: Failed 
udev_device_new_from_syspath(%s) after retry: %m\n", devpath);
+            return;
+        }
     }
 
     subsystem = udev_device_get_subsystem(device);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/umockdev-0.19.3/src/utils.c 
new/umockdev-0.19.4/src/utils.c
--- old/umockdev-0.19.3/src/utils.c     2025-08-01 14:44:37.000000000 +0200
+++ new/umockdev-0.19.4/src/utils.c     2025-10-12 09:56:41.000000000 +0200
@@ -1,22 +1,16 @@
+#include <err.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
 #include "utils.h"
 
-static void
-abort_errno (const char *msg)
-{
-  perror (msg);
-  abort ();
-}
-
 void *
 callocx (size_t nmemb, size_t size)
 {
   void *r = calloc (nmemb, size);
   if (r == NULL)
-      abort_errno ("failed to allocate memory");
+      err (EXIT_FAILURE, "callocx: failed to allocate memory");
   return r;
 }
 
@@ -25,7 +19,7 @@
 {
   void *r = malloc (size);
   if (r == NULL)
-      abort_errno ("failed to allocate memory");
+      err (EXIT_FAILURE, "mallocx: failed to allocate memory");
   return r;
 }
 
@@ -35,6 +29,6 @@
 {
   char *r = strdup (s);
   if (r == NULL)
-    abort_errno ("failed to allocate memory for strdup");
+      err (EXIT_FAILURE, "strdupx: failed to allocate memory");
   return r;
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/umockdev-0.19.3/src/utils.h 
new/umockdev-0.19.4/src/utils.h
--- old/umockdev-0.19.3/src/utils.h     2025-08-01 14:44:37.000000000 +0200
+++ new/umockdev-0.19.4/src/utils.h     2025-10-12 09:56:41.000000000 +0200
@@ -1,6 +1,6 @@
 #pragma once
 
-/* variants of glibc functions that abort() on ENOMEM */
+/* variants of glibc functions that exit on ENOMEM */
 void *mallocx (size_t size);
 void *callocx (size_t nmemb, size_t size);
 char *strdupx (const char *s);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/umockdev-0.19.3/tests/chatter-socket-stream.c 
new/umockdev-0.19.4/tests/chatter-socket-stream.c
--- old/umockdev-0.19.3/tests/chatter-socket-stream.c   2025-08-01 
14:44:37.000000000 +0200
+++ new/umockdev-0.19.4/tests/chatter-socket-stream.c   2025-10-12 
09:56:41.000000000 +0200
@@ -25,6 +25,7 @@
 #include <unistd.h>
 #include <stdlib.h>
 #include <string.h>
+#include <err.h>
 #include <sys/socket.h>
 #include <sys/un.h>
 
@@ -33,10 +34,8 @@
 {
     int r;
     r = write(fd, s, strlen(s));
-    if (r <= 0) {
-        perror ("write");
-        abort();
-    }
+    if (r <= 0)
+        err(EXIT_FAILURE, "write");
 }
 
 int
@@ -47,24 +46,18 @@
     char buf[100];
     int len;
 
-    if (argc != 2) {
-       fprintf(stderr, "Usage: %s socket\n", argv[0]);
-       return 1;
-    }
+    if (argc != 2)
+        errx(EXIT_FAILURE, "Usage: %s socket\n", argv[0]);
 
     fd = socket(AF_UNIX, SOCK_STREAM, 0);
-    if (fd < 0) {
-        perror("socket");
-        return -1;
-    }
+    if (fd < 0)
+        err(EXIT_FAILURE, "socket");
 
     memset(&addr, 0, sizeof(addr));
     addr.sun_family = AF_UNIX;
     strncpy(addr.sun_path, argv[1], sizeof(addr.sun_path)-1);
-    if (connect(fd, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
-        perror("connect");
-        return 1;
-    }
+    if (connect(fd, (struct sockaddr*)&addr, sizeof(addr)) == -1)
+        err(EXIT_FAILURE, "connect");
 
     writestr(fd, "What is your name?\n");
     len = read(fd, buf, sizeof(buf) - 1);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/umockdev-0.19.3/tests/chatter.c 
new/umockdev-0.19.4/tests/chatter.c
--- old/umockdev-0.19.3/tests/chatter.c 2025-08-01 14:44:37.000000000 +0200
+++ new/umockdev-0.19.4/tests/chatter.c 2025-10-12 09:56:41.000000000 +0200
@@ -24,16 +24,15 @@
 #include <fcntl.h>
 #include <unistd.h>
 #include <string.h>
+#include <err.h>
 
 static void
 writestr (int fd, const char *s)
 {
     int r;
     r = write(fd, s, strlen(s));
-    if (r <= 0) {
-        perror ("write");
-        abort();
-    }
+    if (r <= 0)
+        err(EXIT_FAILURE, "write");
 }
 
 int
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/umockdev-0.19.3/tests/test-umockdev-run.vala 
new/umockdev-0.19.4/tests/test-umockdev-run.vala
--- old/umockdev-0.19.3/tests/test-umockdev-run.vala    2025-08-01 
14:44:37.000000000 +0200
+++ new/umockdev-0.19.4/tests/test-umockdev-run.vala    2025-10-12 
09:56:41.000000000 +0200
@@ -212,6 +212,22 @@
     assert (sout.contains ("E: MAJOR=7"));
     assert (sout.contains ("E: MINOR=23"));
 
+    // correct type wihtout the internally used sticky bit
+    check_program_out("true", "-d " + umockdev_file + " -- stat -c %A 
/dev/loop23",
+                      "brw-r--r--\n");
+
+    // ls end-to-end
+    assert (get_program_out (
+            "udevadm",
+            umockdev_run_command + "-d " + umockdev_file + " -- ls -l 
/dev/loop23",
+            out sout, out serr, out exit));
+    assert_cmpint (exit, CompareOperator.EQ, 0);
+    assert (sout.contains ("brw-r--r--"));
+    assert (sout.contains ("/dev/loop23"));
+    assert (sout.contains (" 7,"));
+    assert (sout.contains (" 23 "));
+    assert_cmpstr (serr, CompareOperator.EQ, "");
+
 #if HAVE_SELINUX
     // we may run on a system without SELinux
     try {
@@ -432,10 +448,9 @@
     check_program_out ("gphoto2",
         "-d " + rootdir + "/devices/cameras/canon-powershot-sx200.umockdev -i 
/dev/bus/usb/001/011=" +
         rootdir + "/devices/cameras/canon-powershot-sx200.ioctl -- gphoto2 
--auto-detect",
-        """Model                          Port            
-----------------------------------------------------------
-Canon PowerShot SX200 IS       usb:001,011     
-""");
+        "Model                          Port            \n" +
+        "----------------------------------------------------------\n" +
+        "Canon PowerShot SX200 IS       usb:001,011     \n");
 }
 
 /*
@@ -712,8 +727,9 @@
     string output = (string) sout;
 
     // check supported events
-    assert_in ("Event type 1 (EV_KEY)", output);
-    assert_in ("Event code 15 (KEY_TAB)", output);
+    assert_in ("Event", output);
+    assert_in ("type 1 (EV_KEY)", output);
+    assert_in ("code 42 (KEY_LEFTSHIFT)", output);
 
     // check 'A' key event
     assert_in ("type 4 (EV_MSC), code 4 (MSC_SCAN), value 70004", output);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/umockdev-0.19.3/tests/test-umockdev-vala.vala 
new/umockdev-0.19.4/tests/test-umockdev-vala.vala
--- old/umockdev-0.19.3/tests/test-umockdev-vala.vala   2025-08-01 
14:44:37.000000000 +0200
+++ new/umockdev-0.19.4/tests/test-umockdev-vala.vala   2025-10-12 
09:56:41.000000000 +0200
@@ -1008,7 +1008,7 @@
   var ml = new MainLoop ();
   uint add_count = 0;
   uint change_count = 0;
-  uint num_changes = 10;
+  uint num_changes = 100;
 
   gudev.uevent.connect((client, action, device) => {
       if (action == "add")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/umockdev-0.19.3/tests/test-umockdev.c 
new/umockdev-0.19.4/tests/test-umockdev.c
--- old/umockdev-0.19.3/tests/test-umockdev.c   2025-08-01 14:44:37.000000000 
+0200
+++ new/umockdev-0.19.4/tests/test-umockdev.c   2025-10-12 09:56:41.000000000 
+0200
@@ -22,6 +22,7 @@
 /* for O_TMPFILE */
 #define _GNU_SOURCE
 
+#include <err.h>
 #include <glib.h>
 #include <glib/gstdio.h>
 #include <string.h>
@@ -34,6 +35,7 @@
 #include <sys/sysmacros.h>
 #include <sys/un.h>
 #include <sys/vfs.h>
+#include <sys/xattr.h>
 #include <linux/usbdevice_fs.h>
 #include <linux/input.h>
 #include <linux/magic.h>
@@ -810,7 +812,7 @@
     fflush(stderr);
     rewind(stderr);
     g_assert(fgets(buf, sizeof(buf), stderr) != NULL);
-    g_assert_cmpstr(buf, ==, "ERROR: uevent_sender_send: No such device 
/devices/unknown\n");
+    g_assert_cmpstr(buf, ==, "ERROR: uevent_sender_send: Failed 
udev_device_new_from_syspath(/devices/unknown): Invalid argument\n");
     fclose(stderr);
     stderr = orig_stderr;
 #endif
@@ -1628,6 +1630,29 @@
     g_assert_cmpuint(stx.stx_uid, ==, getuid());
     g_assert(S_ISBLK(stx.stx_mode));
 #endif
+
+    /* listxattr() */
+    char xattr_buf[1024];
+    ssize_t res = listxattr("/dev/empty", xattr_buf, sizeof(xattr_buf));
+    g_assert_cmpint(res, >=, 0);
+
+    res = listxattr("/dev/sdf", xattr_buf, sizeof(xattr_buf));
+    g_assert_cmpint(res, >=, 0);
+
+    res = listxattr("/nonexisting", xattr_buf, sizeof(xattr_buf));
+    g_assert_cmpint(res, ==, -1);
+    g_assert_cmpint(errno, ==, ENOENT);
+
+    /* llistxattr() */
+    res = llistxattr("/dev/empty", xattr_buf, sizeof(xattr_buf));
+    g_assert_cmpint(res, >=, 0);
+
+    res = llistxattr("/dev/sdf", xattr_buf, sizeof(xattr_buf));
+    g_assert_cmpint(res, >=, 0);
+
+    res = listxattr("/nonexisting", xattr_buf, sizeof(xattr_buf));
+    g_assert_cmpint(res, ==, -1);
+    g_assert_cmpint(errno, ==, ENOENT);
 }
 
 static void
@@ -2044,10 +2069,8 @@
   g_assert_cmpint(fd, >=, 0);
   saddr.sun_family = AF_UNIX;
   snprintf(saddr.sun_path, sizeof(saddr.sun_path), "/dev/socket/chatter");
-  if (connect(fd, (struct sockaddr *) &saddr, sizeof(saddr)) < 0) {
-      perror("t_testbed_script_replay_socket_stream() connect");
-      abort();
-  }
+  if (connect(fd, (struct sockaddr *) &saddr, sizeof(saddr)) < 0)
+      err(EXIT_FAILURE, "t_testbed_script_replay_socket_stream() connect");
 
   /* should get initial greeting after 200 ms */
   ASSERT_EOF;

Reply via email to