Guile Maintainers:
Please consider the atttached patch for mmap and friends.
Includes mmap, mmap/shared, munmap, msync.
Matt
From 306570beb3d1895abd03700593cc342282e4ccd1 Mon Sep 17 00:00:00 2001
From: Matt Wette
Date: Tue, 20 Dec 2022 17:15:27 -0800
Subject: [PATCH] Add support for mmap, munmap and msync
* libguile/filesys.c(mmap,munmap,msync): added implementation for mmap
and friends
* doc/ref/posix.texi: add documentation for mmap and friends
---
configure.ac | 12 ++
doc/ref/posix.texi | 45 ++
libguile/filesys.c | 268 +
libguile/filesys.h | 4 +
test-suite/Makefile.am | 1 +
test-suite/tests/mmap-api.test | 47 ++
6 files changed, 377 insertions(+)
create mode 100644 test-suite/tests/mmap-api.test
diff --git a/configure.ac b/configure.ac
index b3879df1f..da49d477a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -199,6 +199,10 @@ AC_ARG_ENABLE(regex,
[ --disable-regex omit regular expression interfaces],,
enable_regex=yes)
+AC_ARG_ENABLE(mmap_api,
+ AS_HELP_STRING([--disable-mmap_api],[omit mmap API]),,
+ enable_mmap_api=yes)
+
AC_ARG_ENABLE(tmpnam,
AS_HELP_STRING([--disable-tmpnam],[omit POSIX tmpnam]),,
enable_tmpnam=yes)
@@ -950,6 +954,10 @@ if test "$enable_regex" = yes; then
AC_DEFINE([ENABLE_REGEX], 1, [Define when regex support is enabled.])
fi
+if test "$enable_mmap_api" = yes; then
+ AC_DEFINE([ENABLE_MMAP_API], 1, [Define when mmap API support is enabled.])
+fi
+
if test "$enable_tmpnam" = yes; then
AC_DEFINE([ENABLE_TMPNAM], 1, [Define when tmpnam support is enabled.])
fi
@@ -1018,6 +1026,10 @@ AC_CHECK_MEMBERS([struct tm.tm_gmtoff],,,
])
GUILE_STRUCT_UTIMBUF
+if test "$enable_mmap_api" = "yes"; then
+ AC_CHECK_FUNCS([msync])
+fi
+
#
#
diff --git a/doc/ref/posix.texi b/doc/ref/posix.texi
index bde0f150c..8114135fe 100644
--- a/doc/ref/posix.texi
+++ b/doc/ref/posix.texi
@@ -1216,6 +1216,51 @@ valid separators. Thus, programs should not assume that
separator---e.g., when extracting the components of a file name.
@end defvr
+@deffn {Scheme Procedure} mmap addr len [prot [flags [fd [offset
+@deffnx {Scheme Procedure} mmap/search addr len [prot [flags [fd [offset
+Create a memory mapping, returning a bytevector. @var{addr}, if
+non-zero, is the staring address; or, if zero, is assigned by the
+system. @var{prot}, if provided, assigns protection. @var{fd},
+if provided associates the memory region with a file, starting
+at @var{offset}, if provided.
+The region returned by mmap will NOT be searched by the garbage
+ collector for pointers, while that returned by mmap/search will.
+Note that the finalizer for the returned bytevector will call munmap.
+Defaults for optional arguments are
+@table @asis
+@item prot
+(logior PROT_READ PROT_WRITE)
+@item flags
+(logior MAP_ANONYMOUS MAP_PRIVATE)
+@item fd
+-1
+@item offset
+0
+@end table
+@end deffn
+
+@deffn {Scheme Procedure} munmap bvec
+Given bytevector generated by mmap or mmap/search, unmap the
+the associated memory. The argument will be modified to
+reflect a zero length bv. The return value is unspecified.
+Note that munmap is called by finalizer associated with
+bytevectors returned from mmap and mmap/search.
+@end deffn
+
+@deffn {Scheme Procedure} msync addr length flag
+Flush changes made to the in-core copy of a file mapped using
+mmap or mmap/search. This should be executed on modified memory
+before calling munmap. The @var{flags} argument must be exactly one
+of the following:
+@table @code
+@item MS_ASYNC
+Initiate update, return immediately.
+@item MS_SYNC
+Initiate update, block until complete.
+@item MS_INVALIDATE
+Invalidate other mappings of the same file.
+@end table
+@end deffn
@node User Information
@subsection User Information
diff --git a/libguile/filesys.c b/libguile/filesys.c
index 1f0bba556..ad3dab471 100644
--- a/libguile/filesys.c
+++ b/libguile/filesys.c
@@ -67,11 +67,17 @@
# include
#endif
+#if defined(ENABLE_MMAP_API) && defined(HAVE_SYS_MMAN_H)
+# include
+#endif
+
#include "async.h"
#include "boolean.h"
#include "dynwind.h"
#include "fdes-finalizers.h"
#include "feature.h"
+#include "finalizers.h"
+#include "foreign.h"
#include "fports.h"
#include "gsubr.h"
#include "iselect.h"
@@ -2263,6 +2269,264 @@ scm_dir_free (SCM p)
+#ifdef ENABLE_MMAP_API
+#if defined(HAVE_SYS_MMAN_H) && defined(HAVE_MAP_ANONYMOUS)
+
+/* see https://pubs.opengroup.org/onlinepubs/9699919799/functions/mmap.html */
+
+static void
+mmap_finalizer (void *ptr, void *data)
+{
+ SCM bvec;
+ void *c_addr;
+ size_t c_len;
+ int rv;
+
+ bvec = SCM_PACK_POINTER (ptr);
+ if (!SCM_BYTEVECTOR_P (bvec))
+scm_misc_error ("mmap", "expecting bytevector", SCM_EOL);
+
+ c_addr = SCM_BYTEVECTOR_CONTENTS (bvec);
+ c_len = SCM_BYTEVECTOR_LENGTH (bvec);
+ SCM_SYSCALL (rv