biscuit

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

fake-nmea.fnl (2150B)


      1 (local { : sleep : close } (require :posix.unistd))
      2 (local sock (require :posix.sys.socket))
      3 (local poll (require :posix.poll))
      4 (local { : view }  (require :fennel))
      5 
      6 (fn handle-client [fd event]
      7   (case event
      8     {:HUP true}
      9     (do
     10       (print fd " disconnected")
     11       (close fd)
     12       (values fd nil))
     13     {:IN true}
     14     (do
     15       (sock.recv fd 1024)               ; discard input and carry on
     16       nil)))
     17 
     18 (fn accept-new-connection [server-sock event]
     19   (case event
     20     {:IN true}
     21     (do
     22       (print "new connection")
     23       (let [connected (sock.accept server-sock)]
     24         (print connected)
     25         (values connected handle-client)))
     26     {:HUP true}
     27     (do
     28       (print "HUP on server socket")
     29       (os.exit 1))
     30     _
     31     (values nil nil)))
     32 
     33 (fn server-socket [path]
     34   (let [s (assert (sock.socket sock.AF_UNIX sock.SOCK_STREAM 0))
     35         sa { :family sock.AF_UNIX
     36              :path path
     37              }]
     38     (assert (sock.bind s sa))
     39     (assert (sock.listen s 10))
     40     s))
     41 
     42 (fn read-with-rewind [handle]
     43   (let [(s err) (handle:read "L")]
     44     (if s
     45         s
     46         (if (and (not err) (handle:seek "set" 0)) ; eof
     47             (read-with-rewind handle)
     48             (error err)))))
     49 
     50 (fn write-sentences [handle outputs]
     51   (var done false)
     52   (while (not done)
     53     (let [l (read-with-rewind handle)]
     54       (if (string.match l "GNS") (set done true))
     55       (each [fd action (pairs outputs)]
     56         (when (= action handle-client)
     57           (print :sending l)
     58           (sock.send fd l))))))
     59 
     60 (let [[filename socketname]  arg
     61       server (server-socket socketname)
     62       fd-actions { server accept-new-connection }]
     63   (with-open [handle (io.open filename :r)]
     64     (while true
     65       (let [poll-fds (collect [fd _ (pairs fd-actions)]
     66                        (values fd {:events { :IN true } }))]
     67         (if (> (poll.poll poll-fds (* 1 1000)) 0)
     68             (each [fd v (pairs poll-fds)]
     69               (when (. v :revents)
     70                 (print :polled fd (view v.revents))
     71                 (let [(k v) ((. fd-actions fd) fd v.revents)]
     72                   (and k (tset fd-actions k v)))))
     73             (write-sentences handle fd-actions))))))