Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package umockdev for openSUSE:Factory 
checked in at 2022-11-30 16:07:49
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/umockdev (Old)
 and      /work/SRC/openSUSE:Factory/.umockdev.new.1597 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "umockdev"

Wed Nov 30 16:07:49 2022 rev:14 rq:1038920 version:0.17.15

Changes:
--------
--- /work/SRC/openSUSE:Factory/umockdev/umockdev.changes        2022-07-08 
14:01:31.486421824 +0200
+++ /work/SRC/openSUSE:Factory/.umockdev.new.1597/umockdev.changes      
2022-11-30 16:07:49.147464630 +0100
@@ -1,0 +2,11 @@
+Sun Nov 27 10:24:04 UTC 2022 - Atri Bhattacharya <badshah...@gmail.com>
+
+- Update to version 0.17.15:
+  * Fixes for tests.
+- Changes from version 0.17.14:
+  * ioctl: Make data object usable from Python.
+  * preload: Wrap statfs().
+  * Move to gnu11 C standard.
+  * Lots of small potential bug fixes spotted by Coverity.
+
+-------------------------------------------------------------------

Old:
----
  umockdev-0.17.13.tar.xz

New:
----
  umockdev-0.17.15.tar.xz

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

Other differences:
------------------
++++++ umockdev.spec ++++++
--- /var/tmp/diff_new_pack.BYEHUK/_old  2022-11-30 16:07:49.627467257 +0100
+++ /var/tmp/diff_new_pack.BYEHUK/_new  2022-11-30 16:07:49.631467278 +0100
@@ -19,7 +19,7 @@
 %define shlib libumockdev0
 %define shlibpre libumockdev-preload0
 Name:           umockdev
-Version:        0.17.13
+Version:        0.17.15
 Release:        0
 Summary:        Mock hardware devices for creating unit tests and bug reporting
 License:        LGPL-2.1-or-later

++++++ umockdev-0.17.13.tar.xz -> umockdev-0.17.15.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/umockdev-0.17.13/.github/release.eloquent.yml 
new/umockdev-0.17.15/.github/release.eloquent.yml
--- old/umockdev-0.17.13/.github/release.eloquent.yml   1970-01-01 
01:00:00.000000000 +0100
+++ new/umockdev-0.17.15/.github/release.eloquent.yml   2022-11-24 
16:02:22.000000000 +0100
@@ -0,0 +1,2 @@
+assets:
+  - path: umockdev-*.tar.xz
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/umockdev-0.17.13/.github/workflows/release.yml 
new/umockdev-0.17.15/.github/workflows/release.yml
--- old/umockdev-0.17.13/.github/workflows/release.yml  2022-05-30 
12:16:30.000000000 +0200
+++ new/umockdev-0.17.15/.github/workflows/release.yml  2022-11-24 
16:02:22.000000000 +0100
@@ -9,16 +9,19 @@
     runs-on: ubuntu-latest
     steps:
       - name: Clone repository
-        uses: actions/checkout@v2
+        uses: actions/checkout@v3
+        with:
+          # need this to also fetch tags
+          fetch-depth: 0
+
+      - name: Workaround for https://github.com/actions/checkout/pull/697
+        run: git fetch --force origin $(git describe --tags):refs/tags/$(git 
describe --tags)
 
       - name: Build release tarball
         # run as root; current Ubuntu podman breaks user networking ("could 
not find slirp4netns")
         run: sudo PUBLISH_TAR=1 tests/run-apt
 
       - name: Create GitHub release
-        uses: docker://antonyurchenko/git-release:latest
-        env:
-          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-          CHANGELOG_FILE: "NEWS"
+        uses: eloquent/github-release-action@v2
         with:
-          args: umockdev-*.tar.xz
+          prerelease: "false"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/umockdev-0.17.13/.github/workflows/tests.yml 
new/umockdev-0.17.15/.github/workflows/tests.yml
--- old/umockdev-0.17.13/.github/workflows/tests.yml    2022-05-30 
12:16:30.000000000 +0200
+++ new/umockdev-0.17.15/.github/workflows/tests.yml    2022-11-24 
16:02:22.000000000 +0100
@@ -30,7 +30,10 @@
     timeout-minutes: 30
     steps:
       - name: Clone repository
-        uses: actions/checkout@v2
+        uses: actions/checkout@v3
+        with:
+          # need this to also fetch tags
+          fetch-depth: 0
 
       - name: Run unit tests
         run: |
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/umockdev-0.17.13/.gitignore 
new/umockdev-0.17.15/.gitignore
--- old/umockdev-0.17.13/.gitignore     2022-05-30 12:16:30.000000000 +0200
+++ new/umockdev-0.17.15/.gitignore     2022-11-24 16:02:22.000000000 +0100
@@ -2,6 +2,7 @@
 .deps
 .dirstamp
 .libs
+.version
 *.la
 *.lo
 *.o
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/umockdev-0.17.13/.version 
new/umockdev-0.17.15/.version
--- old/umockdev-0.17.13/.version       1970-01-01 01:00:00.000000000 +0100
+++ new/umockdev-0.17.15/.version       2022-11-24 16:06:12.774316300 +0100
@@ -0,0 +1 @@
+0.17.15
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/umockdev-0.17.13/NEWS new/umockdev-0.17.15/NEWS
--- old/umockdev-0.17.13/NEWS   2022-05-30 12:16:30.000000000 +0200
+++ new/umockdev-0.17.15/NEWS   2022-11-24 16:02:22.000000000 +0100
@@ -1,3 +1,5 @@
+OBSOLETE: Release news of newer versions are contained in the tag descriptions.
+
 ## [0.17.13] - 2022-05-30
 - preload: Wrap fstatfs(), to work with systemd 251 also with Python tests
 - Fix tests in Gentoo sandbox build
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/umockdev-0.17.13/README.md 
new/umockdev-0.17.15/README.md
--- old/umockdev-0.17.13/README.md      2022-05-30 12:16:30.000000000 +0200
+++ new/umockdev-0.17.15/README.md      2022-11-24 16:02:22.000000000 +0100
@@ -1,3 +1,5 @@
+![CI 
status](https://github.com/martinpitt/umockdev/actions/workflows/tests.yml/badge.svg)
+
 umockdev
 ========
 umockdev mocks Linux devices for creating integration tests for hardware
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/umockdev-0.17.13/do-release 
new/umockdev-0.17.15/do-release
--- old/umockdev-0.17.13/do-release     2022-05-30 12:16:30.000000000 +0200
+++ new/umockdev-0.17.15/do-release     1970-01-01 01:00:00.000000000 +0100
@@ -1,29 +0,0 @@
-#!/bin/sh
-set -e
-
-# This script does all the steps necessary for doing a new upstream release. It
-# should solely be used by upstream developers, distributors do not need to
-# worry about it.
-
-# check for anything uncommitted
-if LC_MESSAGES=C git status | grep -Eiq 'modified|untracked'; then
-    echo "untracked/modified files, see git status" >&2
-    exit 1
-fi
-
-git clean -fdx
-
-# update NEWS
-version=$(sed -rn '1 { s/^.*\[([0-9.]+)\].*/\1/; p }' NEWS)
-[ -n "$version" ] || {
-    echo "failed to parse version" >&2
-    exit 1
-}
-sed -i "s/- UNRELEASED/- $(date '+%Y-%m-%d')/" NEWS
-
-# commit the release and tag
-git commit -a -m "release $version"
-changes=$(sed -n '/^$/ q; /^- / p' NEWS)
-printf "$version\n\n$changes\n" | git tag -s -F- $version
-git push
-git push --tags
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/umockdev-0.17.13/meson.build 
new/umockdev-0.17.15/meson.build
--- old/umockdev-0.17.13/meson.build    2022-05-30 12:16:30.000000000 +0200
+++ new/umockdev-0.17.15/meson.build    2022-11-24 16:02:22.000000000 +0100
@@ -1,5 +1,5 @@
 project('umockdev', 'c', 'vala',
-  version: run_command('sed', '-rn', '1 { s/^.*\[([0-9.]+)\].*/\\1/; p }', 
'NEWS', check: true).stdout().strip(),
+  version: run_command(meson.current_source_dir() / 'src' / 'getversion.sh', 
check: true).stdout().strip(),
   license: 'LGPLv2.1+')
 
 srcdir = meson.current_source_dir() / 'src'
@@ -7,11 +7,15 @@
 lib_version = '0.3.0'
 
 add_project_arguments(
+  '-std=gnu11',
   '-Werror=missing-prototypes',
   '-Werror=strict-prototypes',
   '-Werror=nested-externs',
   '-Werror=pointer-arith',
   '-Werror=implicit-function-declaration',
+  '-Werror=implicit-int',
+  '-Werror=int-conversion',
+  '-Werror=old-style-definition',
   '-Werror=pointer-arith',
   '-Werror=init-self',
   '-Werror=format-security',
@@ -26,6 +30,8 @@
   '-Wno-error=pragmas',
   language: 'c')
 
+add_project_arguments('--abi-stability', language: 'vala')
+
 # let's not clutter the code with too many #ifdefs
 if get_option('b_ndebug') == 'true'
   add_project_arguments('-Wno-error=unused-but-set-variable', 
'-Wno-error=unused-variable', language: 'c')
@@ -44,6 +50,8 @@
   add_project_arguments('-DHAVE_FXSTATAT', language: 'c')
 endif
 
+meson.add_dist_script(srcdir / 'getversion.sh')
+
 #
 # dependencies
 #
@@ -240,7 +248,7 @@
   test('umockdev-vala', executable('test-umockdev-vala',
       'tests/test-umockdev-vala.vala',
       dependencies: [glib, gobject, gio, gudev, vapi_posix, vapi_assertions, 
vapi_ioctl],
-      link_with: [umockdev_lib]),
+      link_with: [umockdev_lib, umockdev_utils_lib]),
     depends: [preload_lib],
     suite: 'fails-valgrind')
 endif
@@ -256,13 +264,13 @@
 test('umockdev-run', executable('test-umockdev-run',
     'tests/test-umockdev-run.vala',
     dependencies: [glib, gobject, gio, vapi_posix, vapi_assertions, 
vapi_config],
-    link_with: [umockdev_lib]),
+    link_with: [umockdev_lib, umockdev_utils_lib]),
   depends: [umockdev_run_exe, preload_lib, test_chatter_exe, 
test_chatter_stream_exe])
 
 test('umockdev-record', executable('test-umockdev-record',
     'tests/test-umockdev-record.vala',
     dependencies: [glib, gobject, gio, gio_unix, vapi_posix, vapi_linux, 
vapi_assertions, vapi_config, vala_libutil],
-    link_with: [umockdev_lib]),
+    link_with: [umockdev_lib, umockdev_utils_lib]),
   depends: [umockdev_record_exe, preload_lib, test_readbyte_exe, 
test_chatter_exe, test_chatter_stream_exe],
   suite: 'fails-valgrind')
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/umockdev-0.17.13/packaging/umockdev.spec 
new/umockdev-0.17.15/packaging/umockdev.spec
--- old/umockdev-0.17.13/packaging/umockdev.spec        2022-05-30 
12:16:30.000000000 +0200
+++ new/umockdev-0.17.15/packaging/umockdev.spec        2022-11-24 
16:02:22.000000000 +0100
@@ -39,6 +39,9 @@
 %meson_build
 
 %check
+# don't be too picky about timing; upstream CI and local developer tests
+# are strict, but many koji arches are emulated and utterly slow
+export SLOW_TESTBED_FACTOR=10
 %meson_test
 
 %install
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/umockdev-0.17.13/packit.yaml 
new/umockdev-0.17.15/packit.yaml
--- old/umockdev-0.17.13/packit.yaml    2022-05-30 12:16:30.000000000 +0200
+++ new/umockdev-0.17.15/packit.yaml    2022-11-24 16:02:22.000000000 +0100
@@ -7,42 +7,52 @@
 downstream_package_name: umockdev
 # HACK: should be implied, but fails propose_downstream: 
https://github.com/packit/packit-service/issues/1511
 specfile_path: packaging/umockdev.spec
-srpm_build_deps: []
+
+actions:
+  create-archive:
+    - meson tmp/dist
+    # ignore local spec changes from packit
+    - meson dist -C tmp/dist --no-tests --allow-dirty
+    - sh -ec 'mv tmp/dist/meson-dist/umockdev-*.tar.xz packaging/; ls 
packaging/umockdev-*.tar.xz'
+
+srpm_build_deps:
+  - meson
+  - gcc
+  - vala
+  - libpcap-devel
+  - glib2-devel
+  - systemd-devel
 
 jobs:
   - job: copr_build
     trigger: pull_request
-    metadata:
-      targets:
-        - fedora-development-x86_64
-        - fedora-development-i386
-        - fedora-development-aarch64
-        - fedora-development-ppc64le
-        - fedora-development-s390x
-        - fedora-development-armhfp
+    targets:
+      - fedora-development-x86_64
+      - fedora-development-i386
+      - fedora-development-aarch64
+      - fedora-development-ppc64le
+      - fedora-development-s390x
+      - fedora-development-armhfp
 
   - job: tests
     trigger: pull_request
-    metadata:
-      targets:
-        - fedora-latest
+    targets:
+      - fedora-latest
+      - centos-stream-9-x86_64
 
   - job: propose_downstream
     trigger: release
-    metadata:
-      dist_git_branches:
-        - fedora-development
-        - fedora-stable
+    dist_git_branches:
+      - fedora-development
+      - fedora-stable
 
   - job: koji_build
     trigger: commit
-    metadata:
-      dist_git_branches:
-        - fedora-all
+    dist_git_branches:
+      - fedora-all
 
   - job: bodhi_update
     trigger: commit
-    metadata:
-      dist_git_branches:
-        # rawhide updates are created automatically
-        - fedora-branched
+    dist_git_branches:
+      # rawhide updates are created automatically
+      - fedora-branched
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/umockdev-0.17.13/src/getversion.sh 
new/umockdev-0.17.15/src/getversion.sh
--- old/umockdev-0.17.13/src/getversion.sh      1970-01-01 01:00:00.000000000 
+0100
+++ new/umockdev-0.17.15/src/getversion.sh      2022-11-24 16:02:22.000000000 
+0100
@@ -0,0 +1,15 @@
+#!/bin/sh
+ROOT=$(dirname $(dirname $(realpath "$0")))
+if [ -n "${MESON_SOURCE_ROOT:-}/.git" ] && VER=$(git -C "$MESON_SOURCE_ROOT" 
describe); then
+    # make version number distribution friendly
+    VER=$(echo "$VER" | sed 's/-/./g')
+    # when invoked as dist script, write the stamp; this is false when invoked 
from project.version()
+    [ -z "${MESON_DIST_ROOT:-}" ] || echo "$VER" > 
"${MESON_DIST_ROOT}/.version"
+    echo "$VER"
+# when invoked from a tarball, it should be in the source root
+elif [ -e "${ROOT}/.version" ]; then
+    cat "${ROOT}/.version"
+else
+    echo "ERROR: Neither a git checkout nor .version, cannot determine 
version" >&2
+    exit 1
+fi
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/umockdev-0.17.13/src/libumockdev-preload.c 
new/umockdev-0.17.15/src/libumockdev-preload.c
--- old/umockdev-0.17.13/src/libumockdev-preload.c      2022-05-30 
12:16:30.000000000 +0200
+++ new/umockdev-0.17.15/src/libumockdev-preload.c      2022-11-24 
16:02:22.000000000 +0100
@@ -131,12 +131,23 @@
 
 /* multi-thread locking for trap_path users */
 pthread_mutex_t trap_path_lock = PTHREAD_MUTEX_INITIALIZER;
+static sigset_t trap_path_sig_restore;
 
 /* multi-thread locking for ioctls */
 pthread_mutex_t ioctl_lock = PTHREAD_MUTEX_INITIALIZER;
 
-#define TRAP_PATH_LOCK pthread_mutex_lock (&trap_path_lock)
-#define TRAP_PATH_UNLOCK pthread_mutex_unlock (&trap_path_lock)
+#define TRAP_PATH_LOCK \
+    do { \
+        sigset_t sig_set; \
+        sigfillset(&sig_set); \
+        pthread_sigmask(SIG_SETMASK, &sig_set, &trap_path_sig_restore); \
+        pthread_mutex_lock (&trap_path_lock); \
+    } while (0)
+#define TRAP_PATH_UNLOCK \
+    do { \
+        pthread_mutex_unlock (&trap_path_lock); \
+        pthread_sigmask(SIG_SETMASK, &trap_path_sig_restore, NULL); \
+    } while (0)
 
 #define IOCTL_LOCK pthread_mutex_lock (&ioctl_lock)
 #define IOCTL_UNLOCK pthread_mutex_unlock (&ioctl_lock)
@@ -1431,39 +1442,76 @@
     return r;
 }
 
+static bool is_dir_or_contained(const char *path, const char *dir, const char 
*subdir)
+{
+    if (!path || !dir)
+       return false;
+
+    const ssize_t subdir_len = strlen(subdir);
+    const size_t dir_len = strlen(dir);
+
+    return (dir_len + subdir_len <= strlen(path) &&
+           strncmp(path, dir, dir_len) == 0 &&
+           strncmp(path + dir_len, subdir, subdir_len) == 0 &&
+           (path[dir_len + subdir_len] == '\0' || path[dir_len + subdir_len] 
== '/'));
+}
+
+static bool is_fd_in_mock(int fd, const char *subdir)
+{
+    static char fdpath[PATH_MAX];
+    static char linkpath[PATH_MAX];
+    libc_func(readlink, ssize_t, const char*, char *, size_t);
+
+    snprintf(fdpath, sizeof fdpath, "/proc/self/fd/%i", fd);
+    int orig_errno = errno;
+    ssize_t linklen = _readlink(fdpath, linkpath, sizeof linkpath);
+    errno = orig_errno;
+    if (linklen < 0 || linklen >= sizeof linkpath) {
+       perror("umockdev: failed to map fd to a path");
+       return false;
+    }
+    linkpath[linklen] = '\0';
+
+    return is_dir_or_contained(linkpath, getenv("UMOCKDEV_DIR"), subdir);
+}
+
 #define WRAP_FSTATFS(suffix) \
 int fstatfs ## suffix(int fd, struct statfs ## suffix *buf)    \
 { \
     libc_func(fstatfs ## suffix, int, int, struct statfs ## suffix *buf); \
     int r = _fstatfs ## suffix(fd, buf);                       \
-    if (r != 0)                                                        \
-       return r;                                               \
-                                                               \
-    static char fdpath[PATH_MAX];                              \
-    static char linkpath[PATH_MAX];                            \
-    snprintf(fdpath, sizeof fdpath, "/proc/self/fd/%i", fd);   \
-    ssize_t linklen = readlink(fdpath, linkpath, sizeof linkpath); \
-    if (linklen < 0) {                                         \
-       perror("umockdev: failed to map fd to a path");         \
-       return 0;                                               \
-    }                                                          \
-\
-    const char *prefix = getenv("UMOCKDEV_DIR");               \
-    if (prefix) {                                              \
-       size_t prefix_len = strlen(prefix);                     \
-       if (prefix_len + 5 <= strlen(linkpath) &&               \
-               strncmp(prefix, linkpath, prefix_len) == 0 &&   \
-               strncmp(linkpath + prefix_len, "/sys/", 5) == 0) { \
-           DBG(DBG_PATH, "testbed wrapped fstatfs64 (%i) points into mocked 
/sys; adjusting f_type\n", fd);    \
-           buf->f_type = SYSFS_MAGIC;                          \
-       }                                                       \
+    if (r == 0 && is_fd_in_mock (fd, "/sys")) {                        \
+       DBG(DBG_PATH, "testbed wrapped fstatfs64 (%i) points into mocked /sys; 
adjusting f_type\n", fd); \
+       buf->f_type = SYSFS_MAGIC;                              \
     }                                                          \
-    return 0;                                                  \
+    return r;                                                  \
 }
 
 WRAP_FSTATFS();
 WRAP_FSTATFS(64);
 
+#define WRAP_STATFS(suffix) \
+int statfs ## suffix(const char *path, struct statfs ## suffix *buf) { \
+    libc_func(statfs ## suffix, int, const char*, struct statfs ## suffix 
*buf); \
+    int r;                                                             \
+    TRAP_PATH_LOCK;                                                    \
+    const char *p = trap_path(path);                                   \
+    if (p == NULL || p == path) {                                      \
+       r = _statfs ## suffix(path, buf);                               \
+       TRAP_PATH_UNLOCK;                                               \
+       return r;                                                       \
+    } \
+    DBG(DBG_PATH, "testbed wrapped statfs" #suffix "(%s) -> %s\n", path, p); \
+    r = _statfs ## suffix(p, buf);                                     \
+    TRAP_PATH_UNLOCK;                                                  \
+    if (r == 0 && is_dir_or_contained(path, "/sys", ""))               \
+       buf->f_type = SYSFS_MAGIC;                                      \
+    return r;                                                          \
+}
+
+WRAP_STATFS();
+WRAP_STATFS(64);
+
 #endif
 
 int __open_2(const char *path, int flags);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/umockdev-0.17.13/src/uevent_sender.c 
new/umockdev-0.17.15/src/uevent_sender.c
--- old/umockdev-0.17.13/src/uevent_sender.c    2022-05-30 12:16:30.000000000 
+0200
+++ new/umockdev-0.17.15/src/uevent_sender.c    2022-11-24 16:02:22.000000000 
+0100
@@ -73,7 +73,6 @@
     struct sockaddr_un event_addr;
     int fd;
     int ret;
-    /* ssize_t count; */
 
     /* create uevent socket address */
     strncpy(event_addr.sun_path, path, sizeof(event_addr.sun_path) - 1);
@@ -98,7 +97,11 @@
     }
 
     const struct msghdr msg = { .msg_name = &event_addr, .msg_iov = iov, 
.msg_iovlen = iov_len };
-    /* count = */ sendmsg(fd, &msg, 0);
+    ssize_t count = sendmsg(fd, &msg, 0);
+    if (count < 0) {
+        perror("uevent_sender sendmsg_one: sendmsg failed");
+        abort();
+    }
     /* printf("passed %zi bytes to event socket %s\n", count, path); */
     close(fd);
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/umockdev-0.17.13/src/umockdev-ioctl.vala 
new/umockdev-0.17.15/src/umockdev-ioctl.vala
--- old/umockdev-0.17.13/src/umockdev-ioctl.vala        2022-05-30 
12:16:30.000000000 +0200
+++ new/umockdev-0.17.15/src/umockdev-ioctl.vala        2022-11-24 
16:02:22.000000000 +0100
@@ -43,7 +43,7 @@
  *
  * Since: 0.16
  */
-public class IoctlData {
+public class IoctlData : GLib.Object {
     /* Local cache to check if data is dirty before flushing. This is both an
      * optimization as it avoids flushes, but is also necessary to avoid
      * writing into read-only memory.
@@ -66,6 +66,30 @@
     }
 
     /**
+     * umockdev_ioctl_data_ref:
+     * @self: A #UMockdevIoctlData
+     *
+     * Deprecated, same as g_object_ref().
+     */
+    [CCode(cname="umockdev_ioctl_data_ref")]
+    public new IoctlData? compat_ref()
+    {
+        return (IoctlData?) this;
+    }
+
+    /**
+     * umockdev_ioctl_data_unref:
+     * @self: A #UMockdevIoctlData
+     *
+     * Deprecated, same as g_object_unref().
+     */
+    [CCode(cname="umockdev_ioctl_data_unref")]
+    public new void compat_unref()
+    {
+        this.unref();
+    }
+
+    /**
      * umockdev_ioctl_data_resolve:
      * @self: A #UMockdevIoctlData
      * @offset: Byte offset of pointer inside data
@@ -173,6 +197,42 @@
         return true;
     }
 
+    /**
+     * umockdev_ioctl_update:
+     * @self: A #UMockdevIoctlData
+     * @offset: Offset into data
+     * @new_data: (array length=length): Data to set
+     * @new_data_length1: Lenght of binary data, must be smaller or equal to 
actual length
+     *
+     * Set data to a specific value. This is essentially a memcpy call, it is
+     * only useful for e.g. python where the bindings cannot make the data
+     * writable otherwise.
+     *
+     * Since: 0.18
+     */
+    public void update(size_t offset, uint8[] new_data) {
+        assert(offset + new_data.length <= data.length);
+
+        Posix.memcpy(&data[offset], new_data, new_data.length);
+    }
+
+    /**
+     * umockdev_ioctl_retrieve:
+     * @self: A #UMockdevIoctlData
+     * @read_data: (array length=length) (out): Data to set
+     * @read_data_length1: (out): Lenght of binary data, must be smaller or 
equal to actual length
+     *
+     * Simply returns the data struct member. This function purely exists for
+     * GIR based bindings, as the vala generated bindings do not correctly
+     * tag the array length, and direct access to the struct member is not
+     * possible.
+     *
+     * Since: 0.18
+     */
+    public void retrieve(out uint8[] read_data) {
+        read_data = data;
+    }
+
     internal void load_data() throws IOError {
         OutputStream output = stream.get_output_stream();
         InputStream input = stream.get_input_stream();
@@ -737,8 +797,7 @@
                 error("Could not accept new connection: %s", e.message);
         }
 
-        lock (listeners)
-          listeners.remove(devnode);
+        listener.close();
     }
 
 #if INTERNAL_REGISTER_API
@@ -748,6 +807,8 @@
 
         Cancellable cancellable = new Cancellable();
 
+        cancellable.set_data("sockpath", sockpath);
+
         /* We create new listener for each file; purely because we may not
          * have the correct main context in construct yet. */
         SocketListener listener;
@@ -772,8 +833,11 @@
 #if INTERNAL_UNREGISTER_PATH_API
     internal void unregister_path(string devnode)
     {
-        lock (listeners)
-          listeners[devnode].cancel();
+        lock (listeners) {
+            listeners[devnode].cancel();
+            Posix.unlink(listeners[devnode].get_data("sockpath"));
+            listeners.remove(devnode);
+        }
     }
 #endif
 
@@ -781,8 +845,10 @@
     internal void unregister_all()
     {
         lock (listeners) {
-            listeners.foreach((key, val) => {
+            listeners.foreach_remove((key, val) => {
                 val.cancel();
+                Posix.unlink(val.get_data("sockpath"));
+                return true;
             });
         }
     }
@@ -790,12 +856,6 @@
 
 #endif // INTERNAL_REGISTER_API
 
-    public virtual signal void client_connected(IoctlClient client) {
-    }
-
-    public virtual signal void client_vanished(IoctlClient client) {
-    }
-
     /* Not a normal signal because we need the accumulator. */
     public virtual bool handle_ioctl(IoctlClient client) {
         return false;
@@ -808,6 +868,12 @@
     public virtual bool handle_write(IoctlClient client) {
         return false;
     }
+
+    public virtual signal void client_connected(IoctlClient client) {
+    }
+
+    public virtual signal void client_vanished(IoctlClient client) {
+    }
 }
 
 /* Mirror of ioctl_tree.c usbdevfs_reapurb_execute submit_urb static variable 
*/
@@ -939,6 +1005,8 @@
         if (!write_log)
             return;
 
+        assert (device != null);
+
         log = Posix.FILE.open(logfile, "w+");
         log.printf("@DEV %s\n", device);
         tree.write(log);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/umockdev-0.17.13/src/umockdev-record.vala 
new/umockdev-0.17.15/src/umockdev-record.vala
--- old/umockdev-0.17.13/src/umockdev-record.vala       2022-05-30 
12:16:30.000000000 +0200
+++ new/umockdev-0.17.15/src/umockdev-record.vala       2022-11-24 
16:02:22.000000000 +0100
@@ -23,14 +23,6 @@
 using UMockdevUtils;
 
 static void
-exit_error(string message, ...)
-{
-    stderr.vprintf(message, va_list());
-    stderr.puts("\n");
-    Process.exit(1);
-}
-
-static void
 devices_from_dir (string dir, ref GenericArray<string> devs)
 {
     Dir d;
@@ -75,7 +67,7 @@
 {
     Posix.Stat st;
     if (Posix.stat(dev, out st) != 0)
-        exit_error("Cannot access device %s: %s", dev, strerror(errno));
+        error("Cannot access device %s: %m", dev);
 
     uint maj = Posix.major(st.st_rdev);
     uint min = Posix.minor(st.st_rdev);
@@ -96,7 +88,7 @@
         real = link;
 
     if (!FileUtils.test(Path.build_filename(real, "uevent"), FileTest.EXISTS))
-        exit_error("Invalid device %s, has no uevent attribute", real);
+        error("Invalid device %s, has no uevent attribute", real);
 
     return real;
 }
@@ -175,7 +167,7 @@
         d = Dir.open(attr_dir);
     } catch (Error e) {
         if (subdir == "") {
-            exit_error("Cannot open directory %s: %s", attr_dir, e.message);
+            error("Cannot open directory %s: %s", attr_dir, e.message);
         } else {
             // we ignore this on subdirs, some might be transient or
             // inaccessible
@@ -204,7 +196,7 @@
             try {
                 stdout.printf("L: %s=%s\n", attr_name, 
FileUtils.read_link(attr_path));
             } catch (Error e) {
-                exit_error("Cannot read link %s: %s", attr_path, e.message);
+                error("Cannot read link %s: %s", attr_path, e.message);
             }
         } else if (FileUtils.test(attr_path, FileTest.IS_REGULAR)) {
             uint8[] contents;
@@ -238,7 +230,7 @@
         if (exitcode != 0)
             throw new SpawnError.FAILED("udevadm exited with code 
%i\n%s".printf(exitcode, u_err));
     } catch (Error e) {
-        exit_error("Cannot call udevadm: %s", e.message);
+        error("Cannot call udevadm: %s", e.message);
     }
 
     var properties = new List<string>();
@@ -305,14 +297,14 @@
 {
     string[] parts = arg.split ("=", 2); // devname, ioctlfilename
     if (parts.length != 2)
-        exit_error("--ioctl argument must be devname=filename");
+        error("--ioctl argument must be devname=filename");
     dev = parts[0];
     fname = parts[1];
 
     // build device major/minor
     Posix.Stat st;
     if (Posix.stat(dev, out st) != 0)
-        exit_error("Cannot access device %s: %s", dev, strerror(errno));
+        error("Cannot access device %s: %m", dev);
 
     is_block = Posix.S_ISBLK(st.st_mode);
     if (Posix.S_ISCHR(st.st_mode) || Posix.S_ISBLK(st.st_mode)) {
@@ -326,7 +318,7 @@
         try {
             FileUtils.get_contents(Path.build_filename(dev, "dev"), out 
devnum);
         } catch (Error e) {
-            exit_error("Cannot open %s/dev: %s", dev, e.message);
+            error("Cannot open %s/dev: %s", dev, e.message);
         }
     }
 }
@@ -362,10 +354,10 @@
     split_devfile_arg(arg, out dev, out devnum, out is_block, out outfile);
     string c = record_script_counter.to_string();
 
-    Environment.set_variable("UMOCKDEV_SCRIPT_RECORD_FILE_" + c, outfile, 
true);
-    Environment.set_variable("UMOCKDEV_SCRIPT_RECORD_DEV_" + c, devnum, true);
-    Environment.set_variable("UMOCKDEV_SCRIPT_RECORD_DEVICE_PATH_" + c, dev, 
true);
-    Environment.set_variable("UMOCKDEV_SCRIPT_RECORD_FORMAT_" + c, format, 
true);
+    checked_setenv("UMOCKDEV_SCRIPT_RECORD_FILE_" + c, outfile);
+    checked_setenv("UMOCKDEV_SCRIPT_RECORD_DEV_" + c, devnum);
+    checked_setenv("UMOCKDEV_SCRIPT_RECORD_DEVICE_PATH_" + c, dev);
+    checked_setenv("UMOCKDEV_SCRIPT_RECORD_FORMAT_" + c, format);
 
     record_script_counter++;
 }
@@ -416,7 +408,7 @@
     try {
         oc.parse (ref args);
     } catch (Error e) {
-        exit_error("Error: %s\nRun %s --help for how to use this program", 
e.message, args[0]);
+        error("Error: %s\nRun %s --help for how to use this program", 
e.message, args[0]);
     }
 
     if (opt_version) {
@@ -425,12 +417,12 @@
     }
 
     if (opt_all && opt_devices.length > 0)
-        exit_error("Specifying a device list together with --all is invalid.");
+        error("Specifying a device list together with --all is invalid.");
     if (!opt_all && opt_devices.length == 0)
-        exit_error("Need to specify at least one device or --all.");
+        error("Need to specify at least one device or --all.");
     if ((opt_ioctl != null || opt_script.length > 0 || opt_evemu_events.length 
> 0) &&
         (opt_all || opt_devices.length < 1))
-        exit_error("For recording ioctls or scripts you have to specify a 
command to run");
+        error("For recording ioctls or scripts you have to specify a command 
to run");
 
     // device dump mode
     if (opt_ioctl == null && opt_script.length == 0 && opt_evemu_events.length 
== 0) {
@@ -452,11 +444,11 @@
         preload = "";
     else
         preload = preload + ":";
-    Environment.set_variable("LD_PRELOAD", preload + 
"libumockdev-preload.so.0", true);
+    checked_setenv("LD_PRELOAD", preload + "libumockdev-preload.so.0");
 
     try {
         root_dir = DirUtils.make_tmp("umockdev.XXXXXX");
-        Environment.set_variable("UMOCKDEV_DIR", root_dir, true);
+        checked_setenv("UMOCKDEV_DIR", root_dir);
     } catch (FileError e) {
         error("Cannot create temporary directory: %s", e.message);
     }
@@ -478,9 +470,8 @@
     try {
         child_pid = spawn_process_under_test (opt_devices, child_watch_cb);
     } catch (Error e) {
-        stderr.printf ("Cannot run %s: %s\n", opt_devices[0], e.message);
         remove_dir (root_dir);
-        Process.exit (1);
+        error ("Cannot run %s: %s", opt_devices[0], e.message);
     }
 
     loop.run();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/umockdev-0.17.13/src/umockdev-run.vala 
new/umockdev-0.17.15/src/umockdev-run.vala
--- old/umockdev-0.17.13/src/umockdev-run.vala  2022-05-30 12:16:30.000000000 
+0200
+++ new/umockdev-0.17.15/src/umockdev-run.vala  2022-11-24 16:02:22.000000000 
+0100
@@ -95,7 +95,7 @@
         preload = "";
     else
         preload = preload + ":";
-    Environment.set_variable ("LD_PRELOAD", preload + 
"libumockdev-preload.so.0", true);
+    checked_setenv ("LD_PRELOAD", preload + "libumockdev-preload.so.0");
 
     var testbed = new UMockdev.Testbed ();
 
@@ -196,8 +196,7 @@
     try {
         child_pid = spawn_process_under_test (opt_program, child_watch_cb);
     } catch (Error e) {
-        stderr.printf ("Cannot run %s: %s\n", opt_program[0], e.message);
-        Process.exit (1);
+        error("Cannot run %s: %s", opt_program[0], e.message);
     }
 
     loop.run();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/umockdev-0.17.13/src/umockdev-utils.vala 
new/umockdev-0.17.15/src/umockdev-utils.vala
--- old/umockdev-0.17.13/src/umockdev-utils.vala        2022-05-30 
12:16:30.000000000 +0200
+++ new/umockdev-0.17.15/src/umockdev-utils.vala        2022-11-24 
16:02:22.000000000 +0100
@@ -1,6 +1,21 @@
 
 namespace UMockdevUtils {
 
+public void
+checked_setenv(string variable, string value)
+{
+    if (!Environment.set_variable(variable, value, true))
+        error("Failed to set env variable %s", variable);
+}
+
+// only use this in tests, not in runtime code!
+public void
+checked_remove(string path)
+{
+    if (FileUtils.remove(path) < 0)
+        error("cannot remove %s: %m", path);
+}
+
 // Recursively remove a directory and all its contents.
 public void
 remove_dir (string path, bool remove_toplevel=true)
@@ -20,8 +35,7 @@
     }
 
     if (remove_toplevel)
-        if (FileUtils.remove(path) < 0)
-            warning("cannot remove %s: %s", path, strerror(errno));
+        checked_remove(path);
 }
 
 private static Pid process_under_test;
@@ -35,8 +49,8 @@
 
     debug ("umockdev: caught signal %i, propagating to child\n", sig);
     if (Posix.kill (process_under_test, sig) != 0)
-        stderr.printf ("umockdev: unable to propagate signal %i to child %i: 
%s\n",
-                       sig, process_under_test, strerror (errno));
+        stderr.printf ("umockdev: unable to propagate signal %i to child %i: 
%m\n",
+                       sig, process_under_test);
 }
 
 static void
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/umockdev-0.17.13/src/umockdev.vala 
new/umockdev-0.17.15/src/umockdev.vala
--- old/umockdev-0.17.13/src/umockdev.vala      2022-05-30 12:16:30.000000000 
+0200
+++ new/umockdev-0.17.15/src/umockdev.vala      2022-11-24 16:02:22.000000000 
+0100
@@ -23,6 +23,18 @@
 private bool __in_mock_env_initialized = false;
 private bool __in_mock_env_result = false;
 
+static void checked_mkdir (string path, int mode)
+{
+    if (DirUtils.create(path, mode) < 0)
+        error("cannot create directory %s: %m", path);
+}
+
+static void checked_mkdir_with_parents (string path, int mode)
+{
+    if (DirUtils.create_with_parents(path, mode) < 0)
+        error("cannot create directory with parents %s: %m", path);
+}
+
 /**
  * SECTION:umockdev
  * @title: umockdev
@@ -85,13 +97,13 @@
             error("Cannot create temporary directory: %s", e.message);
         }
         this.sys_dir = Path.build_filename(this.root_dir, "sys");
-        DirUtils.create(this.sys_dir, 0755);
+        checked_mkdir(this.sys_dir, 0755);
 
         /* Create "bus" and "class" directories to make libudev happy */
         string bus_path = Path.build_filename(this.sys_dir, "bus");
-        DirUtils.create(bus_path, 0755);
+        checked_mkdir(bus_path, 0755);
         string class_path = Path.build_filename(this.sys_dir, "class");
-        DirUtils.create(class_path, 0755);
+        checked_mkdir(class_path, 0755);
 
         this.dev_fd = new HashTable<string, int> (str_hash, str_equal);
         this.dev_script_runner = new HashTable<string, ScriptRunner> 
(str_hash, str_equal);
@@ -106,7 +118,7 @@
         string sockpath = Path.build_filename(this.root_dir, "ioctl", 
"_default");
         handler.register_path(this.worker_ctx, "_default", sockpath);
 
-        Environment.set_variable("UMOCKDEV_DIR", this.root_dir, true);
+        checked_setenv ("UMOCKDEV_DIR", this.root_dir);
         debug("Created udev test bed %s", this.root_dir);
     }
 
@@ -200,8 +212,7 @@
         var attr_path = Path.build_filename(this.root_dir, devpath, name);
         if ("/" in name) {
             string d = Path.get_dirname(attr_path);
-            if (DirUtils.create_with_parents(d, 0755) != 0)
-                error("cannot create attribute subdir '%s': %s", d, 
strerror(errno));
+            checked_mkdir_with_parents(d, 0755);
         }
 
         try {
@@ -256,10 +267,9 @@
     {
         var path = Path.build_filename(this.root_dir, devpath, name);
         var dir = Path.get_dirname(path);
-        if (DirUtils.create_with_parents(dir, 0755) != 0)
-            error("cannot create attribute dir '%s': %s", dir, 
strerror(errno));
+        checked_mkdir_with_parents(dir, 0755);
         if (FileUtils.symlink(value, path) < 0) {
-            error("Cannot create symlink %s: %s", path, strerror(errno));
+            error("Cannot create symlink %s: %m", path);
         }
     }
 
@@ -423,13 +433,11 @@
         string dev_path_no_sys = 
dev_path.substring(dev_path.index_of("/devices/"));
 
         /* create device and corresponding subsystem dir */
-        if (DirUtils.create_with_parents(dev_dir, 0755) != 0)
-            error("cannot create dev dir '%s': %s", dev_dir, strerror(errno));
+        checked_mkdir_with_parents(dev_dir, 0755);
         if (!subsystem_is_bus(subsystem)) {
             /* class/ symlinks */
             var class_dir = Path.build_filename(this.sys_dir, "class", 
subsystem);
-            if (DirUtils.create_with_parents(class_dir, 0755) != 0)
-                error("cannot create class dir '%s': %s", class_dir, 
strerror(errno));
+            checked_mkdir_with_parents(class_dir, 0755);
 
             /* subsystem symlink */
             
assert(FileUtils.symlink(Path.build_filename(make_dotdots(dev_path), "class", 
subsystem),
@@ -443,7 +451,7 @@
         } else {
             /* bus symlink */
             var bus_dir = Path.build_filename(this.sys_dir, "bus", subsystem, 
"devices");
-            assert(DirUtils.create_with_parents(bus_dir, 0755) == 0);
+            checked_mkdir_with_parents(bus_dir, 0755);
             assert(FileUtils.symlink(Path.build_filename("..", "..", "..", 
dev_path_no_sys),
                                      Path.build_filename(bus_dir, 
Path.get_basename(name))) == 0);
 
@@ -455,8 +463,7 @@
         /* /sys/block symlink */
         if (subsystem == "block") {
             var block_dir = Path.build_filename(this.sys_dir, "block");
-            if (DirUtils.create_with_parents(block_dir, 0755) != 0)
-                error("cannot create block dir '%s': %s", block_dir, 
strerror(errno));
+            checked_mkdir_with_parents(block_dir, 0755);
             assert (FileUtils.symlink(Path.build_filename("..", 
dev_path_no_sys),
                                      Path.build_filename(block_dir, 
Path.get_basename(name))) == 0);
         }
@@ -482,19 +489,18 @@
                 var val = attributes[i+1].strip(); // strip off trailing \n
                 /* put the major/minor information into /dev for our preload */
                 string infodir = Path.build_filename(this.root_dir, "dev", 
".node");
-                DirUtils.create_with_parents(infodir, 0755);
+                checked_mkdir_with_parents(infodir, 0755);
                 assert(FileUtils.symlink(val, Path.build_filename(infodir, 
dev_node.replace("/", "_"))) == 0);
 
                 /* create a /sys/dev link for it, like in real sysfs */
                 string sysdev_dir = Path.build_filename(this.sys_dir, "dev",
                     (dev_path.contains("/block/") ? "block" : "char"));
-                if (DirUtils.create_with_parents(sysdev_dir, 0755) != 0)
-                    error("cannot create dir '%s': %s", sysdev_dir, 
strerror(errno));
+                checked_mkdir_with_parents(sysdev_dir, 0755);
                 string dest = Path.build_filename(sysdev_dir, val);
                 if (!FileUtils.test(dest, FileTest.EXISTS)) {
                     if (FileUtils.symlink("../../" + dev_path.substring(5), 
dest) < 0)
-                        error("add_device %s: failed to symlink %s to %s: %s", 
name, dest,
-                              dev_path.substring(5), strerror(errno));
+                        error("add_device %s: failed to symlink %s to %s: %m", 
name, dest,
+                              dev_path.substring(5));
                 }
             }
         }
@@ -895,7 +901,7 @@
         recording.seek(0, SeekType.SET);
 
         string dest = Path.build_filename(this.root_dir, "ioctl", owned_dev + 
".tree");
-        assert(DirUtils.create_with_parents(Path.get_dirname(dest), 0755) == 
0);
+        checked_mkdir_with_parents(Path.get_dirname(dest), 0755);
 
         string? contents = recording.read_upto("", 0, null);
         if (contents == null)
@@ -945,7 +951,7 @@
 
         sockpath = Path.build_filename(this.root_dir, "ioctl", owned_dev);
 
-        assert(DirUtils.create_with_parents(Path.get_dirname(sockpath), 0755) 
== 0);
+        checked_mkdir_with_parents(Path.get_dirname(sockpath), 0755);
 
         IoctlUsbPcapHandler handler = new IoctlUsbPcapHandler(recordfile, 
busnum, devnum);
         handler.register_path(this.worker_ctx, owned_dev, sockpath);
@@ -1019,13 +1025,10 @@
     {
         int fd = Posix.socket (Posix.AF_UNIX, type, 0);
         if (fd < 0)
-            throw new FileError.INVAL ("Cannot create socket type %i: 
%s".printf(
-                                       type, strerror(errno)));
+            throw new FileError.INVAL ("Cannot create socket type %i: 
%m".printf(type));
 
         string real_path = Path.build_filename (this.root_dir, path);
-        if (DirUtils.create_with_parents(Path.get_dirname(real_path), 0755) != 
0)
-            throw new FileError.INVAL ("Cannot create socket path: %s".printf(
-                                       strerror(errno)));
+        checked_mkdir_with_parents(Path.get_dirname(real_path), 0755);
 
         // start thread to accept client connections at first socket creation
         if (this.socket_server == null)
@@ -1379,7 +1382,7 @@
 
             /* create symlinks */
             for (int i = 0; i < devnode_links.length; i++) {
-                assert 
(DirUtils.create_with_parents(Path.get_dirname(devnode_links[i]), 0755) == 0);
+                checked_mkdir_with_parents(Path.get_dirname(devnode_links[i]), 
0755);
                 if (FileUtils.symlink(devnode_path, devnode_links[i]) < 0)
                     warning ("failed to create %s -> %s symlink for device %s: 
%m",
                              devnode_links[i], devnode_path, devpath);
@@ -1400,7 +1403,7 @@
     create_node_for_device (string subsystem, string node_path, uint8[] 
node_contents, string? majmin)
         throws UMockdev.Error
     {
-        assert (DirUtils.create_with_parents(Path.get_dirname(node_path), 
0755) == 0);
+        checked_mkdir_with_parents(Path.get_dirname(node_path), 0755);
 
         // for pre-defined contents, block, and USB devices we create a normal 
file
         if (node_contents.length > 0 || subsystem == "block" || subsystem == 
"usb") {
@@ -1422,7 +1425,7 @@
         int ptym, ptys;
         char[] ptyname_array = new char[8192];
         if (Linux.openpty (out ptym, out ptys, ptyname_array, null, null) < 0)
-            error ("umockdev Testbed.create_node_for_device: openpty() failed: 
%s", strerror (errno));
+            error ("umockdev Testbed.create_node_for_device: openpty() failed: 
%m");
         string ptyname = (string) ptyname_array;
         debug ("create_node_for_device: creating pty device %s: got pty %s", 
node_path, ptyname);
         Posix.close (ptys);
@@ -1443,7 +1446,7 @@
         // we can map from an fd -> ttyname -> device we emulate
         if (majmin != null) {
             string mapdir = Path.build_filename (this.root_dir, "dev", 
".ptymap");
-            DirUtils.create_with_parents (mapdir, 0755);
+            checked_mkdir_with_parents (mapdir, 0755);
             string dest = Path.build_filename (mapdir, ptyname.replace("/", 
"_"));
             debug ("create_node_for_device: creating ptymap symlink %s", dest);
             assert (FileUtils.symlink(majmin, dest) == 0);
@@ -1525,7 +1528,8 @@
      */
     public void enable()
     {
-        FileUtils.remove(Path.build_filename(this.root_dir, "disabled"));
+        if (FileUtils.remove(Path.build_filename(this.root_dir, "disabled")) < 
0)
+            debug("enable: failed to remove /disabled flag, ignoring: %m");
     }
 
     /**
@@ -1540,7 +1544,7 @@
     {
         remove_dir (this.root_dir, false);
         // /sys should always exist
-        DirUtils.create(this.sys_dir, 0755);
+        checked_mkdir_with_parents(this.sys_dir, 0755);
     }
 
     /**
@@ -1708,7 +1712,7 @@
                     debug ("ScriptRunner[%s]: read op after sleep; writing 
data '%s'", this.device, encode(data));
                     ssize_t l = Posix.write (this.fd, data, data.length);
                     if (l < 0)
-                        error ("ScriptRunner[%s]: write failed: %s", 
this.device, strerror (errno));
+                        error ("ScriptRunner[%s]: write failed: %m", 
this.device);
                     assert (l == data.length);
                     break;
 
@@ -1794,8 +1798,7 @@
             if (res < 0) {
                 if (errno == Posix.EINTR)
                     continue;
-                error ("ScriptRunner op_write[%s]: select() failed: %s",
-                       this.device, strerror (errno));
+                error ("ScriptRunner op_write[%s]: select() failed: %m", 
this.device);
             }
 
             if (res == 0) {
@@ -1985,7 +1988,7 @@
             if (res < 0) {
                 if (errno == Posix.EINTR)
                     continue;
-                error ("socket server thread: select() failed: %s", strerror 
(errno));
+                error ("socket server thread: select() failed: %m");
             }
             if (res == 0)
                 continue;  // timeout
@@ -2012,7 +2015,7 @@
                 if (Posix.FD_ISSET (s.fd, fds) > 0) {
                     int fd = Posix.accept (s.fd, null, null);
                     if (fd < 0)
-                        error ("socket server thread: accept() failed: %s", 
strerror (errno));
+                        error ("socket server thread: accept() failed: %m");
                     string sock_path = null;
                     try {
                         sock_path = ((UnixSocketAddress) 
s.get_local_address()).path;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/umockdev-0.17.13/tests/run-alpine 
new/umockdev-0.17.15/tests/run-alpine
--- old/umockdev-0.17.13/tests/run-alpine       2022-05-30 12:16:30.000000000 
+0200
+++ new/umockdev-0.17.15/tests/run-alpine       2022-11-24 16:02:22.000000000 
+0100
@@ -15,11 +15,13 @@
 trap '[ \$? -eq 0 ] || exit 1' EXIT
 
 # install build dependencies
-apk add --no-cache meson gcc musl-dev glib-dev eudev-dev libpcap-dev make vala 
linux-headers xz usbutils ${EXTRA_PACKAGES:-}
+apk add --no-cache meson git gcc musl-dev glib-dev eudev-dev libpcap-dev make 
vala linux-headers xz usbutils ${EXTRA_PACKAGES:-}
 
 # run build as user
-su -s /bin/sh - guest << EOG
+adduser -D build
+su -s /bin/sh - build << EOG
 set -ex
+git config --global safe.directory /source
 export BRITTLE_TESTS="${BRITTLE_TESTS:-}"
 cd /source
 meson setup /tmp/dbg --buildtype debug --werror
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/umockdev-0.17.13/tests/run-apt 
new/umockdev-0.17.15/tests/run-apt
--- old/umockdev-0.17.13/tests/run-apt  2022-05-30 12:16:30.000000000 +0200
+++ new/umockdev-0.17.15/tests/run-apt  2022-11-24 16:02:22.000000000 +0100
@@ -40,7 +40,7 @@
 meson setup /tmp/dbg --buildtype debug --prefix /usr -Dgtk_doc=true --werror
 cd /tmp/dbg
 if meson dist --help | grep -q no-tests; then
-    if meson --version | grep -q "^0.62"; then
+    if { meson --version; echo 0.62.0; } | sort -V | head -n1 | grep -q 
"^0.62.0"; then
         # HACK: --allow-dirty workaround for 
https://github.com/mesonbuild/meson/issues/10329
         meson dist --no-test --allow-dirty
     else
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/umockdev-0.17.13/tests/run-dnf 
new/umockdev-0.17.15/tests/run-dnf
--- old/umockdev-0.17.13/tests/run-dnf  2022-05-30 12:16:30.000000000 +0200
+++ new/umockdev-0.17.15/tests/run-dnf  2022-11-24 16:02:22.000000000 +0100
@@ -37,6 +37,7 @@
 useradd guest
 su -s /bin/sh - guest << EOG
 set -eux
+git config --global safe.directory /source
 export BRITTLE_TESTS="${BRITTLE_TESTS:-}"
 cd /source
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/umockdev-0.17.13/tests/run-gentoo 
new/umockdev-0.17.15/tests/run-gentoo
--- old/umockdev-0.17.13/tests/run-gentoo       2022-05-30 12:16:30.000000000 
+0200
+++ new/umockdev-0.17.15/tests/run-gentoo       2022-11-24 16:02:22.000000000 
+0100
@@ -19,6 +19,10 @@
   docker.io/gentoo/stage3 /bin/sh -eux <<EOF
 # install build dependencies
 ACCEPT_KEYWORDS="~*" emerge dev-util/umockdev --with-test-deps --onlydeps
+# install git, "meson dist" dependency
+emerge dev-vcs/git
+
+git config --global safe.directory /source
 
 cd /source
 export VALAC=\$(ls /usr/bin/valac-* |sort | tail -n1)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/umockdev-0.17.13/tests/run-nix 
new/umockdev-0.17.15/tests/run-nix
--- old/umockdev-0.17.13/tests/run-nix  2022-05-30 12:16:30.000000000 +0200
+++ new/umockdev-0.17.15/tests/run-nix  2022-11-24 16:02:22.000000000 +0100
@@ -26,8 +26,9 @@
   preCheck = "";
   doCheck = true;
   nativeBuildInputs = attrs.nativeBuildInputs ++ [ 
${DEBUG:+pkgs.breakpointHook} ];
+  # git is a "meson dist" time dependency
   # libpcap is a new dependency, it can be removed again later
-  buildInputs = attrs.buildInputs ++ [ pkgs.libpcap ];
+  buildInputs = attrs.buildInputs ++ [ pkgs.git pkgs.libpcap ];
 })
 EOG
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/umockdev-0.17.13/tests/test-umockdev-record.vala 
new/umockdev-0.17.15/tests/test-umockdev-record.vala
--- old/umockdev-0.17.13/tests/test-umockdev-record.vala        2022-05-30 
12:16:30.000000000 +0200
+++ new/umockdev-0.17.15/tests/test-umockdev-record.vala        2022-11-24 
16:02:22.000000000 +0100
@@ -19,6 +19,7 @@
  * along with this program; If not, see <http://www.gnu.org/licenses/>.
  */
 
+using UMockdevUtils;
 using Assertions;
 
 string readbyte_path;
@@ -246,7 +247,7 @@
     }
 
     spawn ("umockdev-record" + " /sys/class", out sout, out serr, out exit);
-    assert_cmpstr (serr, CompareOperator.EQ, "Invalid device /sys/class, has 
no uevent attribute\n");
+    assert (serr.contains("Invalid device /sys/class, has no uevent 
attribute\n"));
     assert_cmpstr (sout, CompareOperator.EQ, "");
     assert_cmpint (exit, CompareOperator.NE, 0);
 
@@ -299,7 +300,7 @@
     assert (FileUtils.test (log, FileTest.EXISTS));
     assert_cmpstr (file_contents (log), CompareOperator.EQ, "@DEV 
/dev/zero\n");
 
-    FileUtils.remove (log);
+    checked_remove (log);
 
     // invalid syntax
     spawn ("umockdev-record" + " --ioctl /dev/null -- " + readbyte_path + " 
/dev/zero",
@@ -342,7 +343,7 @@
     // should not change original record
     assert_cmpstr (file_contents (log), CompareOperator.EQ, orig_contents);
 
-    FileUtils.remove (log);
+    checked_remove (log);
 }
 
 /*
@@ -383,7 +384,7 @@
     assert_cmpint (int.parse(logwords[1]), CompareOperator.LE, 5 * 
slow_testbed_factor);
     assert_cmpstr (logwords[2], CompareOperator.EQ, "^@");
 
-    FileUtils.remove (log);
+    checked_remove (log);
 }
 
 /*
@@ -426,7 +427,7 @@
     assert_cmpint (int.parse(logwords[1]), CompareOperator.LE, 5 * 
slow_testbed_factor);
     assert_cmpstr (logwords[2], CompareOperator.EQ, "^@");
 
-    FileUtils.remove (log);
+    checked_remove (log);
 }
 
 static void
@@ -472,7 +473,7 @@
     assert_cmpint (int.parse(logwords[1]), CompareOperator.LE, 5 * 
slow_testbed_factor);
     assert_cmpstr (logwords[2], CompareOperator.EQ, "^@");
 
-    FileUtils.remove (log);
+    checked_remove (log);
 }
 
 static void
@@ -504,7 +505,7 @@
     // should not change original record
     assert_cmpstr (file_contents (log), CompareOperator.EQ, orig_contents);
 
-    FileUtils.remove (log);
+    checked_remove (log);
 }
 
 static string
@@ -626,7 +627,7 @@
     // verify EOF
     assert_cmpint (log_stream.scanf ("%*c"), CompareOperator.EQ, -1);
 
-    FileUtils.remove (log);
+    checked_remove (log);
 }
 
 /*
@@ -705,10 +706,10 @@
         Thread.usleep (20000);
         conn.send ("recv()".data);
     } catch (Error e) {
-        FileUtils.remove (spath);
+        checked_remove (spath);
         error ("Error: %s", e.message);
     }
-    FileUtils.remove (spath);
+    checked_remove (spath);
 
     int status;
     assert_cmpint ((int) Posix.waitpid (chatter_pid, out status, 0), 
CompareOperator.EQ, (int) chatter_pid);
@@ -730,7 +731,7 @@
     assert_cmpint (time, CompareOperator.GE, 20);
     assert_cmpint (time, CompareOperator.LE, 60 * slow_testbed_factor);
 
-    FileUtils.remove (log);
+    checked_remove (log);
 }
 
 /*
@@ -781,7 +782,7 @@
     // unchanged
     assert_cmpstr (file_contents (log), CompareOperator.EQ, "# EVEMU 1.2\n# 
device /dev/null\n\n");
 
-    FileUtils.remove (log);
+    checked_remove (log);
 
     // invalid syntax
     spawn ("umockdev-record" + " --evemu-events /dev/null -- true",
@@ -867,8 +868,8 @@
     assert_cmpint (exit, CompareOperator.EQ, 0);
     assert_cmpstr (sout, CompareOperator.EQ, sout_record);
 
-    FileUtils.remove ("gphoto-test.umockdev");
-    FileUtils.remove ("gphoto-test.ioctl");
+    checked_remove ("gphoto-test.umockdev");
+    checked_remove ("gphoto-test.ioctl");
 }
 
 int
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/umockdev-0.17.13/tests/test-umockdev-run.vala 
new/umockdev-0.17.15/tests/test-umockdev-run.vala
--- old/umockdev-0.17.13/tests/test-umockdev-run.vala   2022-05-30 
12:16:30.000000000 +0200
+++ new/umockdev-0.17.15/tests/test-umockdev-run.vala   2022-11-24 
16:02:22.000000000 +0100
@@ -18,6 +18,7 @@
  * along with this program; If not, see <http://www.gnu.org/licenses/>.
  */
 
+using UMockdevUtils;
 using Assertions;
 
 const string umockdev_run_command = "env LC_ALL=C umockdev-run ";
@@ -120,7 +121,6 @@
     assert_in (expected_err, serr);
 
     assert_cmpint (exit, CompareOperator.NE, 0);
-    assert (Process.if_exited (exit));
     assert_cmpstr (sout, CompareOperator.EQ, "");
 }
 
@@ -207,7 +207,7 @@
     assert (sout.contains ("E: MAJOR=7"));
     assert (sout.contains ("E: MINOR=23"));
 
-    FileUtils.remove (umockdev_file);
+    checked_remove (umockdev_file);
 }
 
 static void
@@ -333,7 +333,7 @@
     check_program_out("true", "-d " + umockdev_file + " -- stat -c '%n %F %t 
%T' /dev/null",
                       "/dev/null character special file 1 3\n");
 
-    FileUtils.remove (umockdev_file);
+    checked_remove (umockdev_file);
 }
 
 static void
@@ -361,8 +361,8 @@
                        " -- " + tests_dir + "/chatter /dev/ttyS0",
                        "Got input: Joe Tester\nGot input: somejunk\n");
 
-    FileUtils.remove (umockdev_file);
-    FileUtils.remove (script_file);
+    checked_remove (umockdev_file);
+    checked_remove (script_file);
 }
 
 static void
@@ -383,7 +383,7 @@
                        " -- " + tests_dir + "/chatter-socket-stream 
/dev/socket/chatter",
                        "Got name: Joe Tester\n\nGot recv: somejunk\n");
 
-    FileUtils.remove (script_file);
+    checked_remove (script_file);
 }
 
 static void
@@ -484,8 +484,8 @@
     assert (Posix.stat("thumb_IMG_0002.jpg", out st) == 0);
     assert_cmpuint ((uint) st.st_size, CompareOperator.GT, 500);
 
-    FileUtils.remove ("thumb_IMG_0001.jpg");
-    FileUtils.remove ("thumb_IMG_0002.jpg");
+    checked_remove ("thumb_IMG_0001.jpg");
+    checked_remove ("thumb_IMG_0002.jpg");
 }
 static void
 t_gphoto_download ()
@@ -512,8 +512,8 @@
     assert (Posix.stat("IMG_0002.JPG", out st) == 0);
     assert_cmpuint ((uint) st.st_size, CompareOperator.GT, 5000);
 
-    FileUtils.remove ("IMG_0001.JPG");
-    FileUtils.remove ("IMG_0002.JPG");
+    checked_remove ("IMG_0001.JPG");
+    checked_remove ("IMG_0002.JPG");
 }
 
 */
@@ -588,11 +588,12 @@
     int status;
     Posix.waitpid (xorg_pid, out status, 0);
     Process.close_pid (xorg_pid);
-    FileUtils.remove (logfile);
-    FileUtils.remove (logfile + ".old");
+    checked_remove (logfile);
+    checked_remove (logfile + ".old");
     // clean up lockfile after killed X server
-    FileUtils.remove ("/tmp/.X5-lock");
-    FileUtils.remove ("/tmp/.X11-unix/X5");
+    if (FileUtils.remove ("/tmp/.X5-lock") < 0)
+        debug("failed to clean up /tmp/.X5-lock: %m");
+    checked_remove ("/tmp/.X11-unix/X5");
 
     assert_cmpstr (xinput_err, CompareOperator.EQ, "");
     assert_cmpint (xinput_exit, CompareOperator.EQ, 0);
@@ -732,7 +733,7 @@
 
     // our script covers 0.5 seconds, give it some slack
     Posix.sleep (1 * slow_testbed_factor);
-    FileUtils.remove (evemu_file);
+    checked_remove (evemu_file);
 #if VALA_0_40
     Posix.kill (evtest_pid, Posix.Signal.TERM);
 #else
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/umockdev-0.17.13/tests/test-umockdev-vala.vala 
new/umockdev-0.17.15/tests/test-umockdev-vala.vala
--- old/umockdev-0.17.13/tests/test-umockdev-vala.vala  2022-05-30 
12:16:30.000000000 +0200
+++ new/umockdev-0.17.15/tests/test-umockdev-vala.vala  2022-11-24 
16:02:22.000000000 +0100
@@ -18,6 +18,7 @@
  * along with this program; If not, see <http://www.gnu.org/licenses/>.
  */
 
+using UMockdevUtils;
 using Assertions;
 
 string rootdir;
@@ -280,7 +281,7 @@
   } catch (Error e) {
       error ("Cannot load ioctls: %s", e.message);
   }
-  FileUtils.unlink (tmppath);
+  checked_remove (tmppath);
 
   fd = Posix.open ("/dev/001", Posix.O_RDWR, 0);
   assert_cmpint (fd, CompareOperator.GE, 0);
@@ -378,7 +379,7 @@
   } catch (Error e) {
       error ("Cannot load ioctls: %s", e.message);
   }
-  FileUtils.unlink (tmppath);
+  checked_remove (tmppath);
 
   fd = Posix.open ("/dev/001", Posix.O_RDWR, 0);
   assert_cmpint (fd, CompareOperator.GE, 0);
@@ -424,7 +425,7 @@
   } catch (Error e) {
       error ("Cannot load ioctls: %s", e.message);
   }
-  FileUtils.unlink (tmppath);
+  checked_remove (tmppath);
 
   fd = Posix.open ("/dev/002", Posix.O_RDWR, 0);
   assert_cmpint (fd, CompareOperator.GE, 0);
@@ -477,7 +478,7 @@
   } catch (Error e) {
       error ("Cannot load ioctls: %s", e.message);
   }
-  FileUtils.unlink (tmppath);
+  checked_remove (tmppath);
 
   int fd = Posix.open ("/dev/001", Posix.O_RDWR, 0);
   assert_cmpint (fd, CompareOperator.GE, 0);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/umockdev-0.17.13/tests/test-umockdev.c 
new/umockdev-0.17.15/tests/test-umockdev.c
--- old/umockdev-0.17.13/tests/test-umockdev.c  2022-05-30 12:16:30.000000000 
+0200
+++ new/umockdev-0.17.15/tests/test-umockdev.c  2022-11-24 16:02:22.000000000 
+0100
@@ -32,8 +32,10 @@
 #include <sys/socket.h>
 #include <sys/sysmacros.h>
 #include <sys/un.h>
+#include <sys/vfs.h>
 #include <linux/usbdevice_fs.h>
 #include <linux/input.h>
+#include <linux/magic.h>
 
 #include <libudev.h>
 #include <gudev/gudev.h>
@@ -1193,6 +1195,40 @@
     g_assert_cmpint(statx (AT_FDCWD, "/sys/bus/pci/devices/dev1", 0, 
STATX_TYPE|STATX_NLINK|STATX_UID, &stx), ==, 0);
     g_assert_cmpuint(stx.stx_uid, ==, uid);
     g_assert(S_ISDIR(stx.stx_mode));
+
+    struct statfs buf;
+    dirfd = open("/sys", O_RDONLY | O_DIRECTORY);
+    g_assert_cmpint(dirfd, >=, 0);
+    g_assert_cmpint(fstatfs(dirfd, &buf), ==, 0);
+    g_assert_cmpint(buf.f_type, ==, SYSFS_MAGIC);
+    close (dirfd);
+    memset(&buf, 0, sizeof buf);
+
+    dirfd = open("/sys/bus/pci/devices/dev1", O_RDONLY | O_DIRECTORY);
+    g_assert_cmpint(dirfd, >=, 0);
+    g_assert_cmpint(fstatfs(dirfd, &buf), ==, 0);
+    g_assert_cmpint(buf.f_type, ==, SYSFS_MAGIC);
+    close (dirfd);
+    memset(&buf, 0, sizeof buf);
+
+    dirfd = open("/dev", O_RDONLY | O_DIRECTORY);
+    g_assert_cmpint(dirfd, >=, 0);
+    g_assert_cmpint(fstatfs(dirfd, &buf), ==, 0);
+    g_assert_cmpint(buf.f_type, !=, SYSFS_MAGIC);
+    close (dirfd);
+    memset(&buf, 0, sizeof buf);
+
+    g_assert_cmpint(statfs("/sys", &buf), ==, 0);
+    g_assert_cmpint(buf.f_type, ==, SYSFS_MAGIC);
+    memset(&buf, 0, sizeof buf);
+
+    g_assert_cmpint(statfs("/sys/bus/pci/devices/dev1", &buf), ==, 0);
+    g_assert_cmpint(buf.f_type, ==, SYSFS_MAGIC);
+    memset(&buf, 0, sizeof buf);
+
+    g_assert_cmpint(statfs("/dev", &buf), ==, 0);
+    g_assert_cmpint(buf.f_type, !=, SYSFS_MAGIC);
+    memset(&buf, 0, sizeof buf);
 #endif
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/umockdev-0.17.13/tests/test-umockdev.py 
new/umockdev-0.17.15/tests/test-umockdev.py
--- old/umockdev-0.17.13/tests/test-umockdev.py 2022-05-30 12:16:30.000000000 
+0200
+++ new/umockdev-0.17.15/tests/test-umockdev.py 2022-11-24 16:02:22.000000000 
+0100
@@ -21,6 +21,8 @@
 import sys
 import os.path
 import unittest
+import fcntl
+import struct
 
 try:
     import gi
@@ -212,4 +214,37 @@
         with assertRaisesRegex(GLib.GError, 'malformed attribute') as cm:
             self.testbed.add_from_string ('P: /devices/dev1\nE: SIMPLE_PROP\n')
 
+    def test_custom_ioctl(self):
+        handler = UMockdev.IoctlBase()
+
+        def handle_ioctl(handler, client):
+            if client.get_request() != 1:
+                return False
+
+            in_data = struct.pack('l', -1)
+            out_data = struct.pack('l', 1)
+            arg = client.get_arg()
+            data = arg.resolve(0, len(out_data))
+            if data.retrieve() != in_data:
+                return False
+            data.update(0, out_data)
+
+            client.complete(99, 0)
+            return True
+
+        handler.connect("handle-ioctl", handle_ioctl)
+
+        self.testbed.add_from_string ('P: /devices/test\nN: test\nE: 
SUBSYSTEM=test')
+        self.testbed.attach_ioctl('/dev/test', handler)
+
+        fd = os.open('/dev/test', os.O_RDONLY)
+        arg = bytearray(struct.pack('l', -1))
+        self.assertEqual(fcntl.ioctl(fd, 1, arg, True), 99)
+        arg = struct.unpack('l', arg)[0]
+        self.assertEqual(arg, 1)
+
+        # Check that an detach/attach works
+        self.testbed.detach_ioctl('/dev/test')
+        self.testbed.attach_ioctl('/dev/test', handler)
+
 unittest.main(testRunner=unittest.TextTestRunner(stream=sys.stdout, 
verbosity=2))

Reply via email to