guile-netlink/acpi-listener.in

acpi-listener.in

1
#!%GUILE% --no-auto-compile
2
-*- scheme -*-
3
!#
4
5
6
;;;; This file is part of Guile Netlink
7
;;;;
8
;;;; Copyright (C) 2025 Dale Mellor
9
;;;; 
10
;;;; This library is free software: you can redistribute it and/or modify
11
;;;; it under the terms of the GNU General Public License as published by
12
;;;; the Free Software Foundation, either version 3 of the License, or
13
;;;; (at your option) any later version.
14
;;;;
15
;;;; This library is distributed in the hope that it will be useful,
16
;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17
;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
;;;; GNU General Public License for more details.
19
;;;;
20
;;;; You should have received a copy of the GNU General Public License
21
;;;; along with this library.  If not, see <https://www.gnu.org/licenses/>.
22
23
24
25
(unless (getenv "NETLINK_UNINSTALLED")
26
  (set! %load-path (cons "%modsrcdir%" %load-path))
27
  (set! %load-compiled-path (cons "%modbuilddir%" %load-compiled-path)))
28
29
30
;; This is both an example of use of guile-netlinkʼs ACPI notifications
31
;; interface‒it being the simplest such application that we can think of‒, and
32
;; a useful diagnostic tool in its own right to help fathom the meaning of the
33
;; messages coming out of the Linux kernel, as these are not at all well
34
;; documented and depend critically on the nature of the physical computer
35
;; system and the kernel build configuration.
36
;;
37
;; There are no command-line arguments; the program will simply sit and listen
38
;; for kernel ACPI events to be broadcast, and then report the data returned
39
;; on the screen.  It is left as an exercise to the end user (hah!) to work
40
;; out the actual meanings of these data.
41
42
43
;; Use guile-netlinkʼs ACPI interface.  The use of a prefix is discretionary;
44
;; it is useful to have in example code.
45
(use-modules  ((netlink acpi) #:prefix ACPI::))
46
47
48
(define (event-action event)
49
  "Print the contents of the EVENT object in a line on the screen."
50
  ((@ (ice-9 format) format)
51
      #t
52
      "device: ~20a, bus ID: ~15a, type: ~8,'0x, data: ~8,'0x\n"
53
      (ACPI::event-device-class  event)
54
      (ACPI::event-bus-id        event)
55
      (ACPI::event-kind          event)
56
      (ACPI::event-data          event)))
57
58
59
;; Connect to the kernelʼs Netlink ACPI notifier and obtain the three control
60
;; procedures for this connection.
61
((@ (ice-9 receive) receive)
62
    (ACPI::read-selector  ACPI::process-events  ACPI::close-connection)
63
    (ACPI::connect-events)
64
65
    ;; In a tight loop use the first procedure in a (select _) call to wait
66
    ;; for data from the connection, then use the second procedure to actually
67
    ;; read and interpret those data and call the above event-action function
68
    ;; on any ACPI event data found there.
69
    (let loop ()
70
      (select (list (ACPI::read-selector)) '() '())
71
      (ACPI::process-events event-action)
72
      (loop))
73
    
74
    ;; We wonʼt ever get here, but if for some reason we did... use the third
75
    ;; procedure given us from the connection to shut that connection down.
76
    (ACPI::close-connection))
77