Add chez-inotify: Linux filesystem monitoring + jerboa wrapper
ober
871a26164757042572ccab1d5784be77f83873be
--- a/Makefile +++ b/Makefile @@ -1,9 +1,9 @@ SCHEME = scheme LIBDIRS = lib # External chez-* library paths for wrapper modules -CHEZ_EXT_LIBDIRS = $(HOME)/mine/chez-https/src:$(HOME)/mine/chez-ssl/src:$(HOME)/mine/chez-zlib/src:$(HOME)/mine/chez-pcre2:$(HOME)/mine/chez-yaml:$(HOME)/mine/chez-leveldb:$(HOME)/mine/chez-epoll/src +CHEZ_EXT_LIBDIRS = $(HOME)/mine/chez-https/src:$(HOME)/mine/chez-ssl/src:$(HOME)/mine/chez-zlib/src:$(HOME)/mine/chez-pcre2:$(HOME)/mine/chez-yaml:$(HOME)/mine/chez-leveldb:$(HOME)/mine/chez-epoll/src:$(HOME)/mine/chez-inotify/src # Shared object paths for FFI-based chez-* libraries -CHEZ_EXT_LDPATH = $(HOME)/mine/chez-ssl:$(HOME)/mine/chez-zlib:$(HOME)/mine/chez-pcre2:$(HOME)/mine/chez-leveldb:$(HOME)/mine/chez-epoll +CHEZ_EXT_LDPATH = $(HOME)/mine/chez-ssl:$(HOME)/mine/chez-zlib:$(HOME)/mine/chez-pcre2:$(HOME)/mine/chez-leveldb:$(HOME)/mine/chez-epoll:$(HOME)/mine/chez-inotify .PHONY: test test-reader test-core test-runtime test-stdlib test-ffi test-modules test-expanded test-wrappers clean @@ -60,6 +60,9 @@ test-wrappers: @LD_LIBRARY_PATH="$(CHEZ_EXT_LDPATH):$$LD_LIBRARY_PATH" \ $(SCHEME) --libdirs "$(LIBDIRS):$(CHEZ_EXT_LIBDIRS)" --script tests/test-wrapper-epoll.ss 2>/dev/null \ || echo " epoll: SKIP (requires chez_epoll_shim.so)" + @LD_LIBRARY_PATH="$(CHEZ_EXT_LDPATH):$$LD_LIBRARY_PATH" \ + $(SCHEME) --libdirs "$(LIBDIRS):$(CHEZ_EXT_LIBDIRS)" --script tests/test-wrapper-inotify.ss 2>/dev/null \ + || echo " inotify: SKIP (requires chez_inotify_shim.so)" test-all: test test-wrappers new file mode 100644 --- /dev/null +++ b/lib/std/os/inotify.sls @@ -0,0 +1,22 @@ +#!chezscheme +;;; :std/os/inotify -- Linux filesystem event monitoring (wraps chez-inotify) +;;; Requires: chez_inotify_shim.so + +(library (std os inotify) + (export + inotify-init inotify-close + inotify-add-watch inotify-rm-watch + inotify-read-events inotify-poll + make-inotify-event inotify-event? + inotify-event-wd inotify-event-mask + inotify-event-cookie inotify-event-name + IN_ACCESS IN_ATTRIB IN_CLOSE_WRITE IN_CLOSE_NOWRITE + IN_CREATE IN_DELETE IN_DELETE_SELF IN_MODIFY + IN_MOVE_SELF IN_MOVED_FROM IN_MOVED_TO IN_OPEN + IN_ALL_EVENTS IN_MOVE IN_CLOSE + IN_DONT_FOLLOW IN_EXCL_UNLINK IN_MASK_ADD IN_ONESHOT IN_ONLYDIR + IN_IGNORED IN_ISDIR IN_Q_OVERFLOW IN_UNMOUNT) + + (import (chez-inotify)) + + ) ;; end library new file mode 100644 --- /dev/null +++ b/tests/test-wrapper-inotify.ss @@ -0,0 +1,46 @@ +#!chezscheme +(import (chezscheme) (std os inotify)) + +(define pass-count 0) +(define fail-count 0) + +(define-syntax chk + (syntax-rules (=>) + [(_ expr => expected) + (let ([result expr] [exp expected]) + (if (equal? result exp) (set! pass-count (+ pass-count 1)) + (begin (set! fail-count (+ fail-count 1)) + (display "FAIL: ") (write 'expr) + (display " => ") (write result) + (display " expected ") (write exp) (newline))))])) + +;; Constants +(chk (> IN_CREATE 0) => #t) +(chk (> IN_DELETE 0) => #t) + +;; Create/close +(let ([fd (inotify-init)]) + (chk (> fd 0) => #t) + (inotify-close fd)) + +;; Watch + create file + read event +(let ([dir (format "/tmp/jerboa-inotify-~a" (random 1000000))]) + (mkdir dir) + (let ([fd (inotify-init)]) + (let ([wd (inotify-add-watch fd dir IN_CREATE)]) + (chk (>= wd 0) => #t) + (call-with-output-file (format "~a/t.txt" dir) + (lambda (p) (display "x" p))) + (when (inotify-poll fd 100) + (let ([evts (inotify-read-events fd)]) + (chk (> (length evts) 0) => #t) + (chk (equal? (inotify-event-name (car evts)) "t.txt") => #t))) + (inotify-rm-watch fd wd)) + (inotify-close fd)) + (delete-file (format "~a/t.txt" dir)) + (delete-directory dir #f)) + +(display " inotify: ") (display pass-count) (display " passed") +(when (> fail-count 0) (display ", ") (display fail-count) (display " failed")) +(newline) +(when (> fail-count 0) (exit 1))