aboutsummaryrefslogtreecommitdiffstats
path: root/tests/gpgscm/main.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--tests/gpgscm/main.c41
1 files changed, 40 insertions, 1 deletions
diff --git a/tests/gpgscm/main.c b/tests/gpgscm/main.c
index 65929f007..79072a540 100644
--- a/tests/gpgscm/main.c
+++ b/tests/gpgscm/main.c
@@ -23,13 +23,20 @@
#include <assert.h>
#include <ctype.h>
#include <errno.h>
+#include <fcntl.h>
#include <gcrypt.h>
#include <gpg-error.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
#include <unistd.h>
+#if HAVE_MMAP
+#include <sys/mman.h>
+#endif
+
#include "private.h"
#include "scheme.h"
#include "scheme-private.h"
@@ -177,7 +184,39 @@ load (scheme *sc, char *file_name,
}
if (verbose > 1)
fprintf (stderr, "Loading %s...\n", qualified_name);
- scheme_load_named_file (sc, h, qualified_name);
+
+#if HAVE_MMAP
+ /* Always try to mmap the file. This allows the pages to be shared
+ * between processes. If anything fails, we fall back to using
+ * buffered streams. */
+ if (1)
+ {
+ struct stat st;
+ void *map;
+ size_t len;
+ int fd = fileno (h);
+
+ if (fd < 0)
+ goto fallback;
+
+ if (fstat (fd, &st))
+ goto fallback;
+
+ len = (size_t) st.st_size;
+ if ((off_t) len != st.st_size)
+ goto fallback; /* Truncated. */
+
+ map = mmap (NULL, len, PROT_READ, MAP_SHARED, fd, 0);
+ if (map == MAP_FAILED)
+ goto fallback;
+
+ scheme_load_memory (sc, map, len, qualified_name);
+ munmap (map, len);
+ }
+ else
+ fallback:
+#endif
+ scheme_load_named_file (sc, h, qualified_name);
fclose (h);
if (sc->retcode && sc->nesting)