I worked on the code a bit more. It is currently implemented as a #include "mman.c" in filesys.c and another file "mman.c".
I believe this needs to be reviewed by someone who understands the constraints on foriegn pointers and finalization better than I do. Also, there is a comment to add a procedure mmap/no-search to guarantee that the allocated region is not searched by the GC for pointers. The following patch is against guile-2.2.2: --- libguile/filesys.c.orig 2017-07-21 06:14:18.000000000 -0700 +++ libguile/filesys.c 2017-10-27 15:40:04.000000000 -0700 @@ -1828,9 +1828,14 @@ +#include "mman.c" + void scm_init_filesys () { +#ifdef HAVE_SYS_MMAN_H + init_mman(); +#endif #ifdef HAVE_POSIX scm_tc16_dir = scm_make_smob_type ("directory", 0); scm_set_smob_free (scm_tc16_dir, scm_dir_free); --- libguile/mman.c.orig 2017-07-20 17:06:55.000000000 -0700 +++ libguile/mman.c 2017-10-28 08:12:46.000000000 -0700 @@ -0,0 +1,165 @@ +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#ifdef HAVE_SYS_MMAN_H +# include <sys/mman.h> +# include <errno.h> +#endif + +#if defined(HAVE_SYS_MMAN_H) && defined(HAVE_MAP_ANONYMOUS) + +#include "libguile/_scm.h" +#include "libguile/smob.h" +#include "libguile/fdes-finalizers.h" +#include "libguile/feature.h" + +SCM_API SCM scm_mmap (SCM addr, SCM len, SCM prot, SCM flags, SCM fd, + SCM offset); +SCM_API SCM scm_munmap (SCM bvec); +void init_mman(void); +static void mmap_finalizer (void *ptr, void *data); + + +SCM_DEFINE (scm_mmap, "mmap", 2, 4, 0, + (SCM addr, SCM len, SCM prot, SCM flags, SCM fd, SCM offset), + "mmap addr len [prot [flags [fd [offset]]]]" + "See the man page. Returns a bytevector." + "ordinarily convert to bytevector using pointer->bytevector. " + "Note that the region returned by mmap is not (?) searched " + "by the garbage collector. Defaults:\n" + " PROT (logior PROT_READ PROT_WRITE)\n" + " FLAGS (logior MAP_ANON MAP_PRIVATE)\n" + " FD -1\n" + " OFFSET 0\n" + "@example\n(define reg (mmap %null-pointer #x1000)\n" + "@end example" + ) +#define FUNC_NAME s_scm_mmap +{ + void *c_mem, *c_addr; + size_t c_len; + int c_prot, c_flags, c_fd; + scm_t_off c_offset; + SCM pointer, bvec; + + if (SCM_POINTER_P (addr)) + c_addr = SCM_POINTER_VALUE (addr); + else if (scm_is_integer (addr)) + c_addr = (void*) scm_to_uintptr_t (addr); + else + SCM_MISC_ERROR("bad addr", addr); + + c_len = scm_to_size_t (len); + + if (SCM_UNBNDP (prot)) + c_prot = PROT_READ | PROT_WRITE; + else + c_prot = scm_to_int (prot); + + if (SCM_UNBNDP (flags)) + c_flags = MAP_ANON | MAP_PRIVATE; + else + c_flags = scm_to_int (flags); + + if (SCM_UNBNDP (fd)) + c_fd = -1; + else + c_fd = scm_to_int (fd); + + if (SCM_UNBNDP (fd)) + c_offset = 0; + else + c_offset = scm_to_off_t (offset); + + c_mem = mmap(c_addr, c_len, c_prot, c_flags, c_fd, c_offset); + if (c_mem == MAP_FAILED) + SCM_SYSERROR; /* errno set */ + + pointer = scm_cell (scm_tc7_pointer, (scm_t_bits) c_mem); + bvec = scm_c_take_typed_bytevector((signed char *) c_mem + c_offset, c_len, + SCM_ARRAY_ELEMENT_TYPE_VU8, pointer); + /* if sizeof(void*) < sizeof(size_t) we are in trouble: */ + scm_i_set_finalizer (SCM2PTR (bvec), mmap_finalizer, (void*) c_len); + return bvec; +} +static void +mmap_finalizer (void *ptr, void *data) +{ + void *c_addr; + intptr_t c_len; + int res; + + c_addr = (void *) SCM_POINTER_VALUE (SCM_PACK_POINTER (ptr)); + c_len = (intptr_t) data; + res = munmap(c_addr, c_len); + if (res != 0) SCM_SYSERROR; +} +#undef FUNC_NAME + +SCM_DEFINE (scm_munmap, "munmap", 1, 0, 0, + (SCM bvec), + "See the man page. Given bytevector unmap." + ) +#define FUNC_NAME s_scm_munmap +{ + void *c_addr; + size_t c_len; + int c_res; + + SCM_VALIDATE_BYTEVECTOR (1, bvec); + + c_addr = (void *) SCM_BYTEVECTOR_CONTENTS (bvec); + c_len = SCM_BYTEVECTOR_LENGTH (bvec); + + c_res = munmap(c_addr, c_len); + if (c_res == -1) + SCM_SYSERROR; /* errno set */ + + // TODO: clean up bytevector + return SCM_UNSPECIFIED; +} +#undef FUNC_NAME + +void init_mman(void) { +#ifdef PROT_NONE + scm_c_define ("PROT_NONE", scm_from_int (PROT_NONE)); +#endif +#ifdef PROT_ + scm_c_define ("PROT_READ", scm_from_int (PROT_READ)); +#endif +#ifdef PROT_ + scm_c_define ("PROT_WRITE", scm_from_int (PROT_WRITE)); +#endif +#ifdef PROT_ + scm_c_define ("PROT_EXEC", scm_from_int (PROT_EXEC)); +#endif + +#ifdef MAP_ANONYMOUS + scm_c_define ("MAP_ANONYMOUS", scm_from_int (MAP_ANONYMOUS)); +#endif +#ifdef MAP_ANON + scm_c_define ("MAP_ANO