rewrite fake-nmea to not need socat

This commit is contained in:
Daniel Barlow 2025-06-30 18:17:13 +01:00
parent 01e260e9aa
commit 64789d1fe9

View File

@ -1,10 +1,72 @@
(local { : sleep } (require :posix.unistd))
(local { : sleep : close } (require :posix.unistd))
(local sock (require :posix.sys.socket))
(local poll (require :posix.poll))
(local { : view } (require :fennel))
(fn handle-client [fd event]
(case event
{:HUP true}
(do
(print fd " disconnected")
(close fd)
(values fd nil))
{:IN true}
(do
(sock.recv fd 1024) ; discard input and carry on
nil)))
(fn accept-new-connection [server-sock event]
(case event
{:IN true}
(do
(print "new connection")
(let [connected (sock.accept server-sock)]
(print connected)
(values connected handle-client)))
{:HUP true}
(do
(print "HUP on server socket")
(os.exit 1))
_
(values nil nil)))
(fn server-socket [path]
(let [s (assert (sock.socket sock.AF_UNIX sock.SOCK_STREAM 0))
sa { :family sock.AF_UNIX
:path path
}]
(assert (sock.bind s sa))
(assert (sock.listen s 10))
s))
(fn read-with-rewind [handle]
(let [(s err) (handle:read "L")]
(if s
s
(if (and (not err) (handle:seek "set" 0)) ; eof
(read-with-rewind handle)
(error err)))))
(fn write-sentences [handle outputs]
(var done false)
(while (not done)
(let [l (read-with-rewind handle)]
(if (string.match l "GNS") (set done true))
(each [fd action (pairs outputs)]
(when (sock.getpeername fd) ; cheeky
(sock.send fd l))))))
(let [[filename socketname] arg
socket (io.popen (.. "socat - unix-listen:" socketname) :w)]
server (server-socket socketname)
fd-actions { server accept-new-connection }]
(with-open [handle (io.open filename :r)]
(each [l (handle:lines "L")]
(if (string.match l "GNS") (sleep 1))
(socket:write l)
(socket:flush)
)))
(while true
(let [poll-fds (collect [fd _ (pairs fd-actions)]
(values fd {:events { :IN true } }))]
(if (> (poll.poll poll-fds (* 1 1000)) 0)
(each [fd v (pairs poll-fds)]
(when (. v :revents)
(print :polled fd (view v.revents))
(let [(k v) ((. fd-actions fd) fd v.revents)]
(and k (tset fd-actions k v)))))
(write-sentences handle fd-actions))))))