liminix

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

svc.fnl (1652B)


      1 (local inotify (require :inotify))
      2 (local { : file-exists? } (require :anoia))
      3 (local { : directory? } (require :anoia.fs))
      4 (local lfs (require :lfs))
      5 
      6 (fn read-line [name]
      7   (with-open [f (assert (io.open name :r) (.. "can't open file " name))]
      8     (f:read "*l")))
      9 
     10 (fn watch-fsevents [directory-name]
     11   (let [handle (inotify.init)]
     12     (handle:addwatch directory-name
     13                      inotify.IN_CREATE
     14                      inotify.IN_MOVE
     15                      inotify.IN_DELETE
     16                      inotify.IN_DELETE_SELF
     17                      inotify.IN_MOVED_FROM
     18                      inotify.IN_MOVED_TO
     19                      inotify.IN_CLOSE_WRITE)
     20     handle))
     21 
     22 (fn read-value [pathname]
     23   (case (lfs.symlinkattributes pathname)
     24     nil nil
     25     {:mode "directory"}
     26     (collect [f (lfs.dir pathname)]
     27       (when (not (or (= f ".") (= f "..")))
     28         (values f (read-value ( .. pathname "/" f)))))
     29     {:mode "file"}
     30     (read-line pathname)
     31     {:mode "link"}
     32     (read-line pathname)
     33     unknown
     34     (error (.. "can't read " pathname " of kind \"" unknown.mode "\""))))
     35 
     36 (fn events [self]
     37   (coroutine.wrap
     38    #(while true
     39       (while (not (self:ready?)) (self:wait))
     40       (coroutine.yield self)
     41       (self:wait))))
     42 
     43 (fn open [directory]
     44   (let [watcher (watch-fsevents directory)
     45         has-file? (fn [filename] (file-exists? (.. directory "/" filename)))]
     46     {
     47      :wait #(watcher:read)
     48      :ready? (fn [self]
     49                (and (has-file? "state") (not (has-file? ".lock"))))
     50      :output (fn [_ filename]
     51                (read-value (.. directory "/" filename)))
     52      :close #(watcher:close)
     53      : events
     54      }))
     55 
     56 { : open }