diff options
| author | Maxim Cournoyer <maxim@guixotic.coop> | 2025-10-21 23:22:24 +0900 |
|---|---|---|
| committer | Maxim Cournoyer <maxim@guixotic.coop> | 2025-10-30 16:13:03 +0900 |
| commit | e1994a021437b3fd73089c08d7e8db876fad698d (patch) | |
| tree | 4c277554d2167559e9325afc191c53e262733918 /tests | |
| parent | 36a90a1a044e9e141da71f6ff9c7fcf68bcf3016 (diff) | |
syscalls: Add mmap support.
* guix/build/syscalls.scm (PROT_NONE, PROT_READ, PROT_WRITE, PROT_EXEC)
(PROT_SEM, MAP_SHARED, MAP_PRIVATE, MAP_FAILED)
(MS_ASYNC, MS_INVALIDATE, MS_SYNC)
(%mmap-guardian, %unmapped-bytevectors): New variables.
(unmapped-bytevector?, pump-mmap-guardian, %mmap, mmap, %munmap, munmap)
(%msync, msync): New procedures.
* guix/build/io.scm: New file.
* Makefile.am: Register it.
* tests/syscalls.scm (strace-output): New variable.
("mmap and munmap", "file->bytevector, reading", "file->bytevector, writing")
("manual munmap does not lead to double free"): New tests.
Change-Id: I19ec687899eda635559e91200dd8d98669b0e35f
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/syscalls.scm | 70 |
1 files changed, 69 insertions, 1 deletions
diff --git a/tests/syscalls.scm b/tests/syscalls.scm index a0483e68f08..1ea49b0acc4 100644 --- a/tests/syscalls.scm +++ b/tests/syscalls.scm | |||
| @@ -22,8 +22,11 @@ | |||
| 22 | 22 | ||
| 23 | (define-module (test-syscalls) | 23 | (define-module (test-syscalls) |
| 24 | #:use-module (guix utils) | 24 | #:use-module (guix utils) |
| 25 | #:use-module (guix build io) | ||
| 25 | #:use-module (guix build syscalls) | 26 | #:use-module (guix build syscalls) |
| 27 | #:use-module (guix build utils) | ||
| 26 | #:use-module (gnu build linux-container) | 28 | #:use-module (gnu build linux-container) |
| 29 | #:use-module (rnrs bytevectors) | ||
| 27 | #:use-module (srfi srfi-1) | 30 | #:use-module (srfi srfi-1) |
| 28 | #:use-module (srfi srfi-26) | 31 | #:use-module (srfi srfi-26) |
| 29 | #:use-module (srfi srfi-64) | 32 | #:use-module (srfi srfi-64) |
| @@ -31,7 +34,7 @@ | |||
| 31 | #:use-module (system foreign) | 34 | #:use-module (system foreign) |
| 32 | #:use-module ((ice-9 ftw) #:select (scandir)) | 35 | #:use-module ((ice-9 ftw) #:select (scandir)) |
| 33 | #:use-module (ice-9 match) | 36 | #:use-module (ice-9 match) |
| 34 | #:use-module (ice-9 threads)) | 37 | #:use-module (ice-9 textual-ports)) |
| 35 | 38 | ||
| 36 | ;; Test the (guix build syscalls) module, although there's not much that can | 39 | ;; Test the (guix build syscalls) module, although there's not much that can |
| 37 | ;; actually be tested without being root. | 40 | ;; actually be tested without being root. |
| @@ -39,6 +42,9 @@ | |||
| 39 | (define temp-file | 42 | (define temp-file |
| 40 | (string-append "t-utils-" (number->string (getpid)))) | 43 | (string-append "t-utils-" (number->string (getpid)))) |
| 41 | 44 | ||
| 45 | (define strace-output | ||
| 46 | (string-append "t-utils-strace" (number->string (getpid)))) | ||
| 47 | |||
| 42 | 48 | ||
| 43 | (test-begin "syscalls") | 49 | (test-begin "syscalls") |
| 44 | 50 | ||
| @@ -735,6 +741,68 @@ | |||
| 735 | (member (system-error-errno args) | 741 | (member (system-error-errno args) |
| 736 | (list EPERM ENOSYS))))) | 742 | (list EPERM ENOSYS))))) |
| 737 | 743 | ||
| 744 | (test-assert "mmap and munmap" | ||
| 745 | (begin | ||
| 746 | (call-with-output-file temp-file | ||
| 747 | (lambda (p) | ||
| 748 | (display "abcdefghij"))) | ||
| 749 | (let* ((len 5) | ||
| 750 | (bv (mmap (open-fdes temp-file O_RDONLY) len))) | ||
| 751 | (munmap bv)))) | ||
| 752 | |||
| 753 | (test-equal "file->bytevector, reading" | ||
| 754 | #\6 | ||
| 755 | (begin | ||
| 756 | (call-with-output-file temp-file | ||
| 757 | (lambda (p) | ||
| 758 | (display "0123456789\n" p))) | ||
| 759 | (sync) | ||
| 760 | (integer->char | ||
| 761 | (bytevector-u8-ref (file->bytevector temp-file) 6)))) | ||
| 762 | |||
| 763 | (test-equal "file->bytevector, writing" | ||
| 764 | "0000000700" | ||
| 765 | (begin | ||
| 766 | (call-with-output-file temp-file | ||
| 767 | (lambda (p) | ||
| 768 | (display "0000000000" p))) | ||
| 769 | (sync) | ||
| 770 | (let ((bv (file->bytevector temp-file | ||
| 771 | #:protection PROT_WRITE))) | ||
| 772 | |||
| 773 | (bytevector-u8-set! bv 7 (char->integer #\7)) | ||
| 774 | (msync bv)) ;ensure the file gets written | ||
| 775 | (call-with-input-file temp-file get-string-all))) | ||
| 776 | |||
| 777 | (unless (which "strace") | ||
| 778 | (test-skip 1)) | ||
| 779 | ;;; This test currently fails, due to protected items in a guardian being | ||
| 780 | ;;; dropped from weak hash tables (see: | ||
| 781 | ;;; <https://codeberg.org/guile/guile/issues/44>). | ||
| 782 | (test-expect-fail 1) | ||
| 783 | (test-equal "manual munmap does not lead to double free" | ||
| 784 | 1 ;single munmap call | ||
| 785 | (begin | ||
| 786 | (call-with-output-file temp-file | ||
| 787 | (lambda (p) | ||
| 788 | (display "something interesting\n" p))) | ||
| 789 | (sync) | ||
| 790 | (gc) | ||
| 791 | (system (string-append "strace -o " strace-output | ||
| 792 | " -p " (number->string (getpid)) | ||
| 793 | " -e trace=munmap &")) | ||
| 794 | (sleep 1) ;allow strace to start | ||
| 795 | (let ((bv (file->bytevector temp-file))) | ||
| 796 | (munmap bv)) | ||
| 797 | (gc) | ||
| 798 | (sync) | ||
| 799 | (let ((text (call-with-input-file strace-output get-string-all))) | ||
| 800 | ;; The address seen by strace is not the same as the one seen by Guile, | ||
| 801 | ;; so we can't use it in the pattern. | ||
| 802 | (length (filter (cut string-prefix? "munmap(0x" <>) | ||
| 803 | (string-split text #\newline)))))) | ||
| 804 | |||
| 738 | (test-end) | 805 | (test-end) |
| 739 | 806 | ||
| 740 | (false-if-exception (delete-file temp-file)) | 807 | (false-if-exception (delete-file temp-file)) |
| 808 | (false-if-exception (delete-file strace-output)) | ||
