From c7f0d90592fd0348a3818ac897f91e6859584146 Mon Sep 17 00:00:00 2001 From: Justus Winter Date: Wed, 5 Apr 2017 14:11:57 +0200 Subject: [PATCH] gpgscm: Mmap script files. * tests/gpgscm/main.c (load): Try to mmap the script. * tests/gpgscm/scheme.c (scheme_load_memory): New function, a generalization of 'scheme_load_string'. * tests/gpgscm/scheme.h (scheme_load_memory): New prototype. Signed-off-by: Justus Winter --- tests/gpgscm/main.c | 41 ++++++++++++++++++++++++++++++++++++++++- tests/gpgscm/scheme.c | 12 ++++++++---- tests/gpgscm/scheme.h | 2 ++ 3 files changed, 50 insertions(+), 5 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 #include #include +#include #include #include #include #include #include +#include +#include #include +#if HAVE_MMAP +#include +#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) diff --git a/tests/gpgscm/scheme.c b/tests/gpgscm/scheme.c index 9ddd36dae..fd9920704 100644 --- a/tests/gpgscm/scheme.c +++ b/tests/gpgscm/scheme.c @@ -5693,14 +5693,18 @@ void scheme_load_named_file(scheme *sc, FILE *fin, const char *filename) { } void scheme_load_string(scheme *sc, const char *cmd) { + scheme_load_memory(sc, cmd, strlen(cmd), NULL); +} + +void scheme_load_memory(scheme *sc, const char *buf, size_t len, const char *filename) { dump_stack_reset(sc); sc->envir = sc->global_env; sc->file_i=0; sc->load_stack[0].kind=port_input|port_string; - sc->load_stack[0].rep.string.start=(char*)cmd; /* This func respects const */ - sc->load_stack[0].rep.string.past_the_end=(char*)cmd+strlen(cmd); - sc->load_stack[0].rep.string.curr=(char*)cmd; - port_init_location(sc, &sc->load_stack[0], NULL); + sc->load_stack[0].rep.string.start = (char *) buf; /* This func respects const */ + sc->load_stack[0].rep.string.past_the_end = (char *) buf + len; + sc->load_stack[0].rep.string.curr = (char *) buf; + port_init_location(sc, &sc->load_stack[0], filename ? mk_string(sc, filename) : NULL); sc->loadport=mk_port(sc,sc->load_stack); sc->retcode=0; sc->interactive_repl=0; diff --git a/tests/gpgscm/scheme.h b/tests/gpgscm/scheme.h index d7481865d..6f917daed 100644 --- a/tests/gpgscm/scheme.h +++ b/tests/gpgscm/scheme.h @@ -167,6 +167,8 @@ void scheme_set_output_port_string(scheme *sc, char *start, char *past_the_end); SCHEME_EXPORT void scheme_load_file(scheme *sc, FILE *fin); SCHEME_EXPORT void scheme_load_named_file(scheme *sc, FILE *fin, const char *filename); SCHEME_EXPORT void scheme_load_string(scheme *sc, const char *cmd); +SCHEME_EXPORT void scheme_load_memory(scheme *sc, const char *buf, size_t len, + const char *filename); SCHEME_EXPORT pointer scheme_apply0(scheme *sc, const char *procname); SCHEME_EXPORT pointer scheme_call(scheme *sc, pointer func, pointer args); SCHEME_EXPORT pointer scheme_eval(scheme *sc, pointer obj);