commit 53f57c1a8c86dbc16414fe86b55f2ef48988f3d0
parent 19aba0d873b1b66d3251768381d60aed7af054c3
Author: Daniel Barlow <dan@telent.net>
Date: Sat, 1 Jun 2024 21:46:56 +0100
devout: support sysfs attributes for (grand*)parent device
Diffstat:
2 files changed, 41 insertions(+), 3 deletions(-)
diff --git a/pkgs/devout/devout.fnl b/pkgs/devout/devout.fnl
@@ -31,13 +31,18 @@
name value (pairs expected)]
(and match? (= value (event:attr name)))))
+(fn ancestor-attrs-match? [event expected]
+ (accumulate [match? true
+ name value (pairs expected)]
+ (and match? (= value (event:ancestor-attr name)))))
+
(fn event-matches? [e terms]
(accumulate [match? true
name value (pairs terms)]
(and match?
(case name
:attr (attrs-match? e value)
- :attrs true
+ :attrs (ancestor-attrs-match? e value)
other (= value (. e.properties name))))))
(fn read-if-exists [pathname]
@@ -48,6 +53,16 @@
s1)
nil nil))
+(fn event-ancestor-attr [event name]
+ (fn walk-up [sys-path path name]
+ (when path
+ (or (read-if-exists (.. sys-path "/" path "/" name))
+ (walk-up sys-path (dirname path) name))))
+ (walk-up event.sys-path event.path name))
+
+(fn event-attr [event name]
+ (read-if-exists (.. event.sys-path "/" event.path "/" name)))
+
(fn parse-event [s]
(let [at (string.find s "@" 1 true)
(nl nxt) (string.find s "\0" 1 true)
@@ -61,8 +76,8 @@
:action (string.sub s 1 (- at 1))
:format format-event
:matches? event-matches?
- :attr (fn [self name]
- (read-if-exists (.. self.sys-path "/" self.path "/" name)))
+ :attr event-attr
+ :ancestor-attr event-ancestor-attr
}))
(fn find-in-database [db terms]
diff --git a/pkgs/devout/test.fnl b/pkgs/devout/test.fnl
@@ -133,6 +133,29 @@ MINOR=17")
(expect (not m)))
))
+(example
+ "I can find a device matching ancestor sysfs attributes"
+ (let [db (database {:sys-path "./fixtures/sys"})
+ path "/devices/pci0000:00/0000:00:14.0/usb1/1-8/1-8:1.1"
+ e (.. "add@" path "\0ACTION=add\n"
+ (with-open [f (io.open (.. "fixtures/sys" path "/uevent"))]
+ (f:read "*a")))]
+ (db:add e)
+ (let [[m & more] (db:find {:devtype "usb_interface"
+ :driver "uvcvideo"
+ :attrs {:idVendor "13d3"
+ :manufacturer "Azurewave"
+ }})]
+ (expect= m.properties.driver "uvcvideo")
+ (expect= m.properties.interface "14/2/0")
+ (expect= more []))
+
+ (let [[m & more] (db:find {:devtype "usb_interface"
+ :driver "uvcvideo"
+ :attrs {:idVendor "23d3"
+ :manufacturer "Azurewave"
+ }})]
+ (expect (not m)))))
;;; tests for indices