artyom-poptsov / guile-udev

GNU Guile bindings to libudev.
GNU General Public License v3.0
7 stars 3 forks source link

[question] udev-monitor-start-scanning! usage #3

Closed Apteryks closed 9 months ago

Apteryks commented 9 months ago

Hello Artyom!

Thank you for yet another Guile library :-)

I was trying to use it, and reading the info manual, I ended up doing something like:

(use-modules (udev udev)
             (udev monitor))

(define (callback)
  (pk 'YOU-CALLED?))

(let* ((udev (make-udev))
       (monitor (make-udev-monitor udev #:filter (list "drm" "usb" "usb_device")
                                   #:callback callback)))
  (udev-monitor-start-scanning! monitor)
  (while #t (sleep 1)))

I've added a busy loop at the end otherwise my script just exited, while I'd like it to run continously and print the events I've added to the #:filter.

I was expected to see some output upon issuing the command: sudo udevadm trigger -vs usb, but I don't see any. I've also tried unplugging a USB device and reconnecting it, but it's also silent.

Am I using the library as intended?

Thank you!

artyom-poptsov commented 9 months ago

Hi!

Are you running this program from the "root" user?

On Tue, 19 Dec 2023 at 08:08, Apteryks @.***> wrote:

Hello Artyom!

Thank you for yet another Guile library :-)

I was trying to use it, and reading the info manual, I ended up doing something like:

(use-modules (udev udev) (udev monitor))

(define (callback) (pk 'YOU-CALLED?))

(let* ((udev (make-udev)) (monitor (make-udev-monitor udev #:filter (list "drm" "usb" "usb_device")

:callback callback)))

(udev-monitor-start-scanning! monitor) (while #t (sleep 1)))

I've added a busy loop at the end otherwise my script just exited, while I'd like it to run continously and print the events I've added to the

:filter.

I was expected to see some output upon issuing the command: sudo udevadm trigger -vs usb, but I don't see any. I've also tried unplugging a USB device and reconnecting it, but it's also silent.

Am I using the library as intended?

Thank you!

— Reply to this email directly, view it on GitHub https://github.com/artyom-poptsov/guile-udev/issues/3, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAILGASEM7H3NLRR6Q6SV7LYKEOLTAVCNFSM6AAAAABA2SMOZOVHI2DSMVQWIX3LMV43ASLTON2WKOZSGA2DOOJTGE3DGNA . You are receiving this because you are subscribed to this thread.Message ID: @.***>

-- Artyom V. Poptsov @.***> Home page: https://memory-heap.org/~avp/ http://poptsov-artyom.narod.ru/ CADR Hackerspace co-founder: https://cadrspace.ru/ GPG: D0C2 EAC1 3310 822D 98DE B57C E9C5 A2D9 0898 A02F

Apteryks commented 9 months ago

I was testing as my unprivileged user. Do I need to run the program with privileges? That'd be surprising to me, as I was testing a C version as my own user and it catches the "drm" events just fine:

#include <stdbool.h>
#include <string.h>
#include <stdio.h>
#include <libudev.h>
#include <poll.h>
#include <stdlib.h>
#include <unistd.h>
#include <err.h>
#include <errno.h>

int main(int argc, char *argv[]) {
    struct udev *udev;
    struct udev_monitor *mon;
    struct pollfd pf[1];
    int ret;

    udev = udev_new();
    mon = udev_monitor_new_from_netlink(udev, "udev");
    pf[0] = (struct pollfd) {
            .fd = udev_monitor_get_fd(mon),
            .events = POLLIN,
        };

    udev_monitor_filter_add_match_subsystem_devtype(mon, "drm", "drm_minor");
    udev_monitor_enable_receiving(mon);

    for (;;) {
        struct udev_device *dev;
        const char *sysname;

        ret = poll(pf, 1, -1);
        if (ret < 0) {
            if (errno == EINTR)
                continue;
            err(1, "poll failed");
        }

        dev = udev_monitor_receive_device(mon);
        sysname = udev_device_get_sysname(dev);
        if (strncmp(sysname, "card", 4) != 0)
            continue;

        warnx("event received");
        system("xrandr -s 0");
    }

    return 0;
}

This is not from me, it was written by grawity from #systemd on libera.chat IRC (thanks!)

Apteryks commented 9 months ago

I've just tried with running my script via: sudo -E guile x-resize.scm and in another terminal: sudo udevadm trigger -v -s usb, and it still doesn't produce any output. Hm.

Apteryks commented 9 months ago

Ah, it works, I had assumed wrongly the #:filter argument was taking a list of filters matching subsystems; instead it takes a pair containing the subsystem name and the device type name. The following works, and I don't need a privilege user:

(use-modules (udev udev)
             (udev monitor))

(define (callback _)
  (pk 'YOU-CALLED?))

(let* ((udev (make-udev))
       (monitor (make-udev-monitor udev #:filter (list "drm" "drm_minor")
                                   #:callback callback)))
  (udev-monitor-start-scanning! monitor)
  (while #t (sleep 1)))

When triggered via: sudo udevadm trigger -v -s drm

I'll try to add an example and refine the doc a bit for the next confused person :-) Thank you!