eufon

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

socket-repl.fnl (2064B)


      1 (local { : fdopen } (require "posix.stdio"))
      2 (local fcntl (require "posix.fcntl"))
      3 (local unistd (require "posix.unistd"))
      4 (local socket (require "posix.sys.socket"))
      5 (local { : repl } (require :fennel))
      6 
      7 (fn watch-fd [fd mode handler]
      8   (kiwmi:event_loop_add_fd fd mode handler))
      9 
     10 (fn unix-socket-listener [pathname on-connected]
     11   (let [sa {:family socket.AF_UNIX
     12             :path pathname
     13             }
     14         fd (socket.socket socket.AF_UNIX socket.SOCK_STREAM 0)]
     15     (socket.bind fd sa)
     16     (socket.listen fd 5)
     17     (watch-fd
     18      fd fcntl.O_RDWR
     19      #(let [connected-fd (socket.accept $1)]
     20         (on-connected connected-fd)))
     21     ))
     22 
     23 (fn get-input [fd]
     24   (let [buf (unistd.read fd 1024)]
     25     (if (and buf (> (# buf) 0))
     26         buf
     27         "\n,exit")))
     28 
     29 (fn start [pathname]
     30   (unistd.unlink pathname)
     31   (unix-socket-listener
     32    pathname
     33    (fn [fd]
     34      (let [sock (fdopen fd "w+")
     35            repl-coro (coroutine.create repl)]
     36        (watch-fd fd fcntl.O_RDONLY
     37                  (fn [fd]
     38                    (coroutine.resume repl-coro (get-input  fd))
     39                    (if (= (coroutine.status repl-coro) :dead)
     40                        (do
     41                          (sock:write "bye!\n")
     42                          (sock:close)
     43                          false)
     44                        true
     45                        )))
     46        (coroutine.resume repl-coro
     47                          {:readChunk
     48                           (fn [{: stack-size}]
     49                             (sock:write
     50                              (if (> stack-size 0) ".." ">> "))
     51                             (sock:flush)
     52                             (coroutine.yield))
     53                           :onValues
     54                           (fn [vals]
     55                             (sock:write (table.concat vals "\t"))
     56                             (sock:write "\n"))
     57                           :onError
     58                           (fn [errtype err]
     59                             (sock:write
     60                              (.. errtype " error: " (tostring err) "\n")))
     61                           })))))
     62 
     63 
     64 { : start }