rewrite fake-nmea to not need socat
This commit is contained in:
parent
01e260e9aa
commit
64789d1fe9
@ -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))))))
|
||||
|
Loading…
Reference in New Issue
Block a user