(import (chicken bitwise) (chicken file) (chicken file posix) (chicken io) (chicken port) (chicken process) (chicken process signal) (chicken process-context posix) (chicken time) (fuse) (test)) (define u+rwx/reg (bitwise-ior file/reg perm/irusr perm/iwusr perm/ixusr)) (define u+rwx/dir (bitwise-ior file/dir perm/irusr perm/iwusr perm/ixusr)) (define (open-pipe) (receive (i o) (create-pipe) (make-bidirectional-port (open-input-file* i) (open-output-file* o)))) (define (process-terminate! pid) (process-signal pid signal/term) (process-wait pid)) (define (read-file f) (call-with-input-file f (lambda (p) (read-string #f p)))) (define (test-hello path) (define str "Hello world!\n") (define now (current-seconds)) (define fs (make-filesystem getattr: (lambda (path) (cond ((string=? path "/") (vector u+rwx/dir 2 (current-user-id) (current-group-id) 0 now now now)) ((string=? path "/hello") (vector u+rwx/reg 1 (current-user-id) (current-group-id) (string-length str) now now now)) (else #f))) readdir: (lambda (path) (and (string=? path "/") (list "." ".." "hello"))) open: (lambda (path mode) (string=? path "/hello")) read: (lambda (_ size offset) (let ((len (string-length str))) (if (>= offset len) 0 (substring str offset (min size (- len offset)))))))) (define pipe (open-pipe)) (define pid (process-fork (lambda () (set-signal-handler! signal/term (lambda (_) (filesystem-stop! path fs))) (filesystem-start! path fs) (write (filesystem-wait! path fs 'started) pipe) (close-input-port pipe) (close-output-port pipe) (filesystem-wait! path fs 'stopped)))) (close-output-port pipe) (let ((mounted (read pipe))) (close-input-port pipe) (test-assert (equal? mounted #t)) (unless (not mounted) (let* ((file (string-append path "/hello")) (stat (file-stat file))) (test-assert (equal? (vector-ref stat 1) u+rwx/reg)) (test-assert (equal? (vector-ref stat 2) 1)) (test-assert (equal? (vector-ref stat 3) (current-user-id))) (test-assert (equal? (vector-ref stat 4) (current-group-id))) (test-assert (equal? (vector-ref stat 5) (string-length str))) (test-assert (equal? (vector-ref stat 6) now)) (test-assert (equal? (vector-ref stat 7) now)) (test-assert (equal? (vector-ref stat 8) now)) (test-assert (equal? (directory path) '("hello"))) (test-assert (equal? (read-file file) str)) (process-terminate! pid) (test-assert (equal? (directory path) '())))))) (let ((path (create-temporary-directory))) (create-directory path #t) (test-hello path) (delete-directory path #t))