another example
[rrq/rrqforth.git] / examples / uenventlog.f
1 #!/home/ralph/src/devuan/rrqforth/rrqforth
2 #
3 # Register a netlink socket and listen to events
4
5 SYSTEM DEFINITIONS
6
7 # For deugging purposes, use log" blaha"
8 : log" " TELL NL EMIT ;
9
10 : VARIABLE ( "word" -- ; create a variable )
11   INPUT @ READ-WORD CREATE DROP
12 ;
13
14 : CONSTANT ( v "word" -- ; create a cell constant )
15   INPUT @ READ-WORD CREATE TFA>CFA doVALUE SWAP ! ,
16 ;
17
18 : DIE" ( n " quoted" -- ; If v then print message and exit )
19   " ROT IF TELL NL EMIT EXIT THEN 2DROP
20 ;
21
22 HEX 100 DECIMAL   CONSTANT MSG_WAITALL
23 HEX 80002 DECIMAL CONSTANT SOCK_DGRAM|SOCK_CLOEXEC
24 15                CONSTANT NETLINK_KOBJECT_UEVENT
25 16                CONSTANT AF_NETLINK
26 8192              CONSTANT NL_MAX_PAYLOAD
27
28 VARIABLE RECV-BUFFER NL_MAX_PAYLOAD ALLOT
29
30 : PRINTMSG ( n -- ; print RECV-BUFFER message )
31   ( n is message length when >0 but we only use text up to first NUL )
32   DUP 0 >
33   IF DROP RECV-BUFFER DUP STRLEN TELL NL EMIT
34   ELSE S" ** Error: " TELL . NL EMIT
35   THEN
36 ;
37
38 VARIABLE NL-SOCKADDR
39 ( 0-1 .family )  AF_NETLINK W,
40 ( 2-3 ??? )       0 W,
41 ( 4-7 .pid )     SYS_GETPID D,
42 ( 8-11 .groups ) -1 D,
43 12 CONSTANT NL_SOCKADDR_SIZE
44 VARIABLE NL-SOCKET -1 ,
45
46 AF_NETLINK  SOCK_DGRAM|SOCK_CLOEXEC  NETLINK_KOBJECT_UEVENT
47 SYS_SOCKET DUP 0< DIE" Failed to create socket" NL-SOCKET !
48
49 NL-SOCKET @ NL-SOCKADDR NL_SOCKADDR_SIZE
50 SYS_BIND DIE" Failed to bind"
51
52 : NL-LOOP
53   BEGIN
54     NL-SOCKET @ RECV-BUFFER NL_MAX_PAYLOAD MSG_WAITALL 0 0
55     SYS_RECVFROM PRINTMSG
56   AGAIN
57 ;
58
59 log" Waiting for uevents..."
60 NL-LOOP
61
62 # Won't come here, but so what?
63 0 EXIT