From 880e20da75c17c9db23982f56766fe82ee1860a7 Mon Sep 17 00:00:00 2001 From: Maxim Cournoyer Date: Tue, 19 Dec 2023 15:59:29 -0500 Subject: [PATCH 1/8] doc: Document how GNU Guix can be used to develop or install guile-udev. * AUTHORS: Mention self. * doc/guile-udev.texi (Installing as a system package): New chapter. (Installation): Rename to... (Installing from sources): ... this. Document how to install via Guix. --- AUTHORS | 4 +++- doc/guile-udev.texi | 32 ++++++++++++++++++++++++++------ 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/AUTHORS b/AUTHORS index a0ec233..2f438b5 100644 --- a/AUTHORS +++ b/AUTHORS @@ -7,4 +7,6 @@ See also files THANKS and ChangeLog. * Antlers Bug fixes in 'libguile-udev/udev-monitor-func.c' * Mathieu Othacehe - Bug reports in GNU Guix mailing list. \ No newline at end of file + Bug reports in GNU Guix mailing list. +* Maxim Cournoyer + Improvements to the documentation. diff --git a/doc/guile-udev.texi b/doc/guile-udev.texi index 4549806..43b6054 100644 --- a/doc/guile-udev.texi +++ b/doc/guile-udev.texi @@ -11,6 +11,7 @@ This manual documents Guile-Udev version @value{VERSION}. Copyright (C) 2020 Artyom V. Poptsov @email{poptsov.artyom@@gmail.com} +Copyright (C) 2023 Maxim Cournoyer @email{maxim.cournoyer@@gmail.com} Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or @@ -54,10 +55,9 @@ Documentation License.'' @menu * Introduction:: -* Installation:: -* API Reference:: - -Appendices +* Installing as a system package:: +* Installing from sources:: +* API Reference:: Appendices * GNU Free Documentation License:: The license of this manual. @@ -72,8 +72,19 @@ Guile-Udev is a module that provides bindings to @url{https://www.freedesktop.org/software/systemd/man/libudev.html, libudev} for programs written in @url{https://www.gnu.org/software/guile/, GNU Guile}. -@node Installation -@chapter Installation +@node Installing as a system package +@chapter Installing as a system package + +The @url{https://guix.gnu.org, GNU Guix} package manager, which can run on top +of any GNU(/Linux) distribution, offers a @code{guile-udev} package which can +be installed via: + +@example +guix install guile-udev +@end example + +@node Installing from sources +@chapter Installing from sources Guile-Udev sources are available from GitHub at @url{https://github.com/artyom-poptsov/guile-udev/}. This section describes @@ -86,6 +97,15 @@ Guile-Udev depends on the following packages: @item libudev @end itemize +Alternatively, if you have GNU Guix installed, you can run: + +@example +guix shell +@end example + +After following the instructions displayed by the above command to authorize +automatically loading the @file{guix.scm} file at the root of the repository. + Get the sources of Guile-Udev from GitHub using Git (a good introduction to Git is @url{https://git-scm.com/book/en/v2, Pro Git} book, which is available online): From 2043caa1323422b9cf9b8ee802938b948d78b251 Mon Sep 17 00:00:00 2001 From: Maxim Cournoyer Date: Tue, 19 Dec 2023 16:13:51 -0500 Subject: [PATCH 2/8] doc: Refine documentation for the monitor #:callback argument. * doc/guile-udev.texi (API Reference) : Document what argument it accepts. --- doc/guile-udev.texi | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/doc/guile-udev.texi b/doc/guile-udev.texi index 43b6054..cc5aafa 100644 --- a/doc/guile-udev.texi +++ b/doc/guile-udev.texi @@ -175,7 +175,9 @@ parameters specified by keywords described below. @table @samp @item callback -Callback to be called when an udev event occurs. +A procedure to be called when an udev event occurs. It gets applied to a +single argument, which is the @code{udev-device} object the event originated +from. Expected type: procedure From e9352b72bd2fd2f8866395893af8b4f94a9f752e Mon Sep 17 00:00:00 2001 From: Maxim Cournoyer Date: Tue, 19 Dec 2023 16:14:49 -0500 Subject: [PATCH 3/8] doc: Refine documentation for the monitor #:filter argument. * doc/guile-udev.texi (API Reference) : Document that extra filters can be added via the udev-monitor-add-filter! procedure. Fix typo. --- doc/guile-udev.texi | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/doc/guile-udev.texi b/doc/guile-udev.texi index cc5aafa..d7a7937 100644 --- a/doc/guile-udev.texi +++ b/doc/guile-udev.texi @@ -185,8 +185,9 @@ Default value: @code{(const #f)} @item filter Udev event filter. -Expected type: a list with two elements: the 1st element is sybsystem name, -the 2nd element is device type +Expected type: a list with two elements: the first element is the subsystem +name, while the second element is the device type. If needed, more filters +can be installed via the @code{udev-monitor-add-filter!} procedure. Default value: @code{#f} From d18c72cb5f7eba5ea227bfb01ff48a153281b505 Mon Sep 17 00:00:00 2001 From: Maxim Cournoyer Date: Tue, 19 Dec 2023 16:31:19 -0500 Subject: [PATCH 4/8] Check-in updated build-aux/compile. This happens using autoconf from a 'guix shell' environment. --- build-aux/compile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build-aux/compile b/build-aux/compile index df363c8..5e5dbe6 100755 --- a/build-aux/compile +++ b/build-aux/compile @@ -1,4 +1,4 @@ -#! /bin/sh +#!/bin/sh # Wrapper for compilers which do not understand '-c -o'. scriptversion=2018-03-07.03; # UTC From d38bb2bb6683002bc0fc21fe352375ec4996d58e Mon Sep 17 00:00:00 2001 From: Maxim Cournoyer Date: Tue, 19 Dec 2023 16:32:18 -0500 Subject: [PATCH 5/8] doc: Show the existing complete device listener example content. * doc/guile-udev.texi (Examples): New chapter. --- doc/guile-udev.texi | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/doc/guile-udev.texi b/doc/guile-udev.texi index d7a7937..a9fdbed 100644 --- a/doc/guile-udev.texi +++ b/doc/guile-udev.texi @@ -58,7 +58,7 @@ Documentation License.'' * Installing as a system package:: * Installing from sources:: * API Reference:: Appendices - +* Examples:: * GNU Free Documentation License:: The license of this manual. @end menu @@ -351,6 +351,27 @@ Usage example: @end deffn +@node Examples +@chapter Examples + +Here's an example of a device listener that prints the device path of USB +devices that emit udev events: + +@lisp +@verbatiminclude ../examples/device-listener.scm +@end lisp + +To trigger USB events without actually inserting or removing USB devices into +your computer, you can use the @command{udevadm} command (provided by the +@code{eudev} package from Guix) @emph{as root}: + +@example +# udevadm trigger --verbose --subsystem-match=usb +@end example + +You can find the source of this example in the @file{examples} directory of +the project. + @node GNU Free Documentation License @appendix GNU Free Documentation License From 455a3e354aa4b5aeaafbd31612f9f5b8055d917f Mon Sep 17 00:00:00 2001 From: Maxim Cournoyer Date: Tue, 19 Dec 2023 16:42:51 -0500 Subject: [PATCH 6/8] examples/device-listener.scm: Use more portable shebang. Guix Systems doesn't have a /usr/bin/guile binary. Most systems have coreutils new enough to support 'env -S ...'. * examples/device-listener.scm: Use env -S instead of the Guile meta switch. --- examples/device-listener.scm | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/examples/device-listener.scm b/examples/device-listener.scm index ee9acb8..6ceaf23 100755 --- a/examples/device-listener.scm +++ b/examples/device-listener.scm @@ -1,5 +1,4 @@ -#!/usr/bin/guile \ --L modules -e main -s +#!/usr/bin/env -S guile -L modules -e main -s !# (use-modules (udev udev) From dce6c60def7d4e9686bd58ad662c24a98f6cfb28 Mon Sep 17 00:00:00 2001 From: Maxim Cournoyer Date: Tue, 19 Dec 2023 17:16:00 -0500 Subject: [PATCH 7/8] Add a 'pre-inst-env' wrapper script to test library before installing. * pre-inst-env.in: New input file. * .gitignore: Register its finalized version. * configure.ac: Register it in AC_CONFIG_FILES. * doc/guile-udev.texi (Using this library before it is installed): Document it. --- .gitignore | 1 + configure.ac | 1 + doc/guile-udev.texi | 12 ++++++++++++ pre-inst-env.in | 14 ++++++++++++++ 4 files changed, 28 insertions(+) create mode 100644 pre-inst-env.in diff --git a/.gitignore b/.gitignore index 9255e08..1b1dd2e 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,5 @@ config.log config.status configure libtool +pre-inst-env TAGS diff --git a/configure.ac b/configure.ac index 6b87ae8..c41b8ba 100644 --- a/configure.ac +++ b/configure.ac @@ -109,6 +109,7 @@ AC_SUBST([guilesitedir]) GUILE_EFFECTIVE_VERSION=`$GUILE -c '(display (effective-version))'` AC_SUBST(GUILE_EFFECTIVE_VERSION) +AC_CONFIG_FILES([pre-inst-env], [chmod +x pre-inst-env]) AC_CONFIG_FILES([Makefile libguile-udev/Makefile build-aux/Makefile]) AC_CONFIG_FILES([build-aux/m4/Makefile build-aux/am/Makefile doc/Makefile]) AC_CONFIG_FILES([modules/Makefile modules/udev/Makefile]) diff --git a/doc/guile-udev.texi b/doc/guile-udev.texi index a9fdbed..e435dbf 100644 --- a/doc/guile-udev.texi +++ b/doc/guile-udev.texi @@ -57,6 +57,7 @@ Documentation License.'' * Introduction:: * Installing as a system package:: * Installing from sources:: +* Using this library before it is installed:: * API Reference:: Appendices * Examples:: * GNU Free Documentation License:: The license of this manual. @@ -138,6 +139,17 @@ installed in Guile's default path. But, if you don't know where your Guile site directory is, run @command{configure} without the option, and it will give you a suggestion. +@node Using this library before it is installed +@chapter Using this library before it is installed + +If you would like to test this Guile extension as you work on it, without +having to install it, you can use the @file{pre-inst-env} wrapper after having +configured and built the project, e.g.@: + +@example +./pre-inst-env examples/device-listener.scm +@end example + @node API Reference @chapter API Reference diff --git a/pre-inst-env.in b/pre-inst-env.in new file mode 100644 index 0000000..b4aeb78 --- /dev/null +++ b/pre-inst-env.in @@ -0,0 +1,14 @@ +#!/bin/sh + +abs_top_srcdir="`cd "@abs_top_srcdir@" > /dev/null; pwd`" +abs_top_builddir="`cd "@abs_top_builddir@" > /dev/null; pwd`" + +GUILE_EXTENSIONS_PATH="$abs_top_builddir/libguile-udev/.libs${GUILE_EXTENSIONS_PATH=:+:}$GUILE_EXTENSIONS_PATH" +GUILE_LOAD_COMPILED_PATH="$abs_top_builddir/modules${GUILE_LOAD_COMPILED_PATH:+:}$GUILE_LOAD_COMPILED_PATH" +GUILE_LOAD_PATH="$abs_top_srcdir/modules${GUILE_LOAD_PATH:+:}:$GUILE_LOAD_PATH" +export GUILE_EXTENSIONS_PATH GUILE_LOAD_COMPILED_PATH GUILE_LOAD_PATH + +PATH="$abs_top_builddir/scripts:$PATH" +export PATH + +exec "$@" From d9676bf1cfedac8930f781353c042a3434563850 Mon Sep 17 00:00:00 2001 From: Maxim Cournoyer Date: Tue, 19 Dec 2023 21:05:42 -0500 Subject: [PATCH 8/8] Allow the filter device type to be omitted, to match any device type. * libguile-udev/udev-monitor-func.c (udev-monitor-add-filter!): Adjust definition and doc to make the last argument, DEVTYPE, optional. * doc/guile-udev.texi (API Reference) : Document it. : Adjust documentation. * modules/udev/monitor.scm (make-udev-monitor): Add doc string. --- doc/guile-udev.texi | 12 ++++++++---- libguile-udev/udev-monitor-func.c | 15 ++++++++++----- modules/udev/monitor.scm | 11 ++++++++++- 3 files changed, 28 insertions(+), 10 deletions(-) diff --git a/doc/guile-udev.texi b/doc/guile-udev.texi index e435dbf..c6b3d01 100644 --- a/doc/guile-udev.texi +++ b/doc/guile-udev.texi @@ -198,8 +198,9 @@ Default value: @code{(const #f)} Udev event filter. Expected type: a list with two elements: the first element is the subsystem -name, while the second element is the device type. If needed, more filters -can be installed via the @code{udev-monitor-add-filter!} procedure. +name, while the second element is the device type. To match @emph{any} device +type, you may use @code{#f} instead of an actual device type. If needed, more +filters can be installed via the @code{udev-monitor-add-filter!} procedure. Default value: @code{#f} @@ -240,9 +241,12 @@ Check if @var{x} is an udev-monitor object. Return @code{#t} if it is, or @code{#f} otherwise. @end deffn -@deffn {Scheme Procedure} udev-monitor-add-filter! udev-monitor sybsystem devtype +@deffn {Scheme Procedure} udev-monitor-add-filter! udev-monitor subsystem [devtype] Add a new filter for the events on @var{udev-monitor} that will trigger the -provided callback. This procedure must be called before starting the scanning. +provided callback, for a device of type @var{devtype} belonging to the +@var{subsystem} subsystem. @var{devtype} is optional; when omitted, devices +of @emph{any} type are matched. This procedure must be called before starting +the scanning. @end deffn @deffn {Scheme Procedure} udev-monitor-remove-filters! udev-monitor diff --git a/libguile-udev/udev-monitor-func.c b/libguile-udev/udev-monitor-func.c index 4586653..94b3b4c 100644 --- a/libguile-udev/udev-monitor-func.c +++ b/libguile-udev/udev-monitor-func.c @@ -30,9 +30,11 @@ #include "udev-device-type.h" #include "error.h" -SCM_DEFINE_N(gudev_add_filter_x, "udev-monitor-add-filter!", 3, - (SCM udev_monitor, SCM subsystem, SCM devtype), - "Add a filter to the monitor.") +SCM_DEFINE(gudev_add_filter_x, "udev-monitor-add-filter!", 2, 1, 0, + (SCM udev_monitor, SCM subsystem, SCM devtype), + "Add a filter to the monitor. @var{subsystem} is the subsystem\n" + "associated with a device while @var{devtype} is its device type.\n" + "The @var{devtype} argument is optional.") #define FUNC_NAME s_gudev_add_filter_x { char* c_subsystem = NULL; @@ -41,14 +43,17 @@ SCM_DEFINE_N(gudev_add_filter_x, "udev-monitor-add-filter!", 3, int result; SCM_ASSERT(scm_is_string(subsystem), subsystem, SCM_ARG1, FUNC_NAME); - SCM_ASSERT(scm_is_string(devtype), devtype, SCM_ARG2, FUNC_NAME); + SCM_ASSERT(scm_is_string(devtype) || SCM_UNBNDP(devtype), devtype, + SCM_ARG2, FUNC_NAME); scm_dynwind_begin(0); c_subsystem = scm_to_locale_string(subsystem); scm_dynwind_free(c_subsystem); - c_devtype = scm_to_locale_string(devtype); + if (!SCM_UNBNDP(devtype)) + c_devtype = scm_to_locale_string(devtype); + scm_dynwind_free(c_devtype); result = udev_monitor_filter_add_match_subsystem_devtype(umd->udev_monitor, diff --git a/modules/udev/monitor.scm b/modules/udev/monitor.scm index 025cb5e..0fd640d 100644 --- a/modules/udev/monitor.scm +++ b/modules/udev/monitor.scm @@ -24,12 +24,21 @@ (filter #f) (timeout-usec 0) (timeout-sec 0)) + "Create a new 'udev-monitor' object configured with the specified parameters. +CALLBACK is a one argument procedure (receiving a 'udev-device' object) called +when an event matching the specified FILTER. FILTER is a list whose first +element is the device subsystem, and whose second argument is the device type, +or #f to match any type." (let ((monitor (%make-udev-monitor udev))) (udev-monitor-set-timeout! monitor timeout-sec timeout-usec) (udev-monitor-set-callback! monitor callback) (udev-monitor-set-error-callback! monitor callback) (when filter - (udev-monitor-add-filter! monitor (car filter) (cadr filter))) + (let ((subsystem (car filter)) + (devtype (cadr filter))) + (if devtype + (udev-monitor-add-filter! monitor subsystem devtype) + (udev-monitor-add-filter! monitor subsystem)))) monitor)) (load-extension "libguile-udev" "init_udev_monitor")