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 }