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 @@ + + 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))