diff options
Diffstat (limited to 'tests/syscalls.scm')
-rw-r--r-- | tests/syscalls.scm | 90 |
1 files changed, 89 insertions, 1 deletions
diff --git a/tests/syscalls.scm b/tests/syscalls.scm index ab1e13984d..73fa8a7acf 100644 --- a/tests/syscalls.scm +++ b/tests/syscalls.scm @@ -29,6 +29,10 @@ ;; Test the (guix build syscalls) module, although there's not much that can ;; actually be tested without being root. +(define temp-file + (string-append "t-utils-" (number->string (getpid)))) + + (test-begin "syscalls") (test-equal "mount, ENOENT" @@ -172,6 +176,88 @@ (status:exit-val status)))) (eq? #t result)))))))) +(false-if-exception (delete-file temp-file)) +(test-equal "fcntl-flock wait" + 42 ; the child's exit status + (let ((file (open-file temp-file "w0b"))) + ;; Acquire an exclusive lock. + (fcntl-flock file 'write-lock) + (match (primitive-fork) + (0 + (dynamic-wind + (const #t) + (lambda () + ;; Reopen FILE read-only so we can have a read lock. + (let ((file (open-file temp-file "r0b"))) + ;; Wait until we can acquire the lock. + (fcntl-flock file 'read-lock) + (primitive-exit (read file))) + (primitive-exit 1)) + (lambda () + (primitive-exit 2)))) + (pid + ;; Write garbage and wait. + (display "hello, world!" file) + (force-output file) + (sleep 1) + + ;; Write the real answer. + (seek file 0 SEEK_SET) + (truncate-file file 0) + (write 42 file) + (force-output file) + + ;; Unlock, which should let the child continue. + (fcntl-flock file 'unlock) + + (match (waitpid pid) + ((_ . status) + (let ((result (status:exit-val status))) + (close-port file) + result))))))) + +(test-equal "fcntl-flock non-blocking" + EAGAIN ; the child's exit status + (match (pipe) + ((input . output) + (match (primitive-fork) + (0 + (dynamic-wind + (const #t) + (lambda () + (close-port output) + + ;; Wait for the green light. + (read-char input) + + ;; Open FILE read-only so we can have a read lock. + (let ((file (open-file temp-file "w0"))) + (catch 'flock-error + (lambda () + ;; This attempt should throw EAGAIN. + (fcntl-flock file 'write-lock #:wait? #f)) + (lambda (key errno) + (primitive-exit (pk 'errno errno))))) + (primitive-exit -1)) + (lambda () + (primitive-exit -2)))) + (pid + (close-port input) + (let ((file (open-file temp-file "w0"))) + ;; Acquire an exclusive lock. + (fcntl-flock file 'write-lock) + + ;; Tell the child to continue. + (write 'green-light output) + (force-output output) + + (match (waitpid pid) + ((_ . status) + (let ((result (status:exit-val status))) + (fcntl-flock file 'unlock) + (close-port file) + result))))))))) + (test-assert "all-network-interface-names" (match (all-network-interface-names) (((? string? names) ..1) @@ -281,7 +367,7 @@ (test-assert "tcsetattr" (let ((first (tcgetattr 0))) - (tcsetattr 0 TCSANOW first) + (tcsetattr 0 (tcsetattr-action TCSANOW) first) (equal? first (tcgetattr 0)))) (test-assert "terminal-window-size ENOTTY" @@ -303,3 +389,5 @@ 0)) (test-end) + +(false-if-exception (delete-file temp-file)) |